summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
authorLogan Dethrow <log@lindenlab.com>2011-09-07 16:40:40 -0400
committerLogan Dethrow <log@lindenlab.com>2011-09-07 16:40:40 -0400
commitb8fddce34d1737acf32d83dac423dbb7a948cc4a (patch)
treeadf4c05ab3a42b2d3fed8fbda23c2de97840bab7 /indra/llmessage
parentf73b795bb709b3060e06b4238ae4dac702f21301 (diff)
parent82b1b1bc6ee91e1778a16634fb9e2988da23fd71 (diff)
Merge. Fixed issue with LLProxy code related to changes to the LLSocket interface.
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/llares.cpp17
-rw-r--r--indra/llmessage/llcurl.cpp6
-rw-r--r--indra/llmessage/lliohttpserver.cpp10
-rw-r--r--indra/llmessage/lliohttpserver.h2
-rw-r--r--indra/llmessage/lliosocket.cpp100
-rw-r--r--indra/llmessage/lliosocket.h37
-rw-r--r--indra/llmessage/llmail.cpp17
-rw-r--r--indra/llmessage/llmail.h4
-rw-r--r--indra/llmessage/llproxy.cpp11
-rw-r--r--indra/llmessage/llpumpio.cpp74
-rw-r--r--indra/llmessage/llpumpio.h31
-rw-r--r--indra/llmessage/llurlrequest.cpp24
-rw-r--r--indra/llmessage/message.cpp17
-rw-r--r--indra/llmessage/tests/networkio.h9
14 files changed, 134 insertions, 225 deletions
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
index 5a67035ed1..fab9858b69 100644
--- a/indra/llmessage/llares.cpp
+++ b/indra/llmessage/llares.cpp
@@ -28,6 +28,7 @@
#include "linden_common.h"
#include "llares.h"
+#include "llscopedvolatileaprpool.h"
#include <ares_dns.h>
#include <ares_version.h>
@@ -464,11 +465,6 @@ void LLAres::search(const std::string &query, LLResType type,
bool LLAres::process(U64 timeout)
{
- if (!gAPRPoolp)
- {
- ll_init_apr();
- }
-
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
apr_int32_t nsds = 0;
@@ -482,10 +478,7 @@ bool LLAres::process(U64 timeout)
return nsds > 0;
}
- apr_status_t status;
- LLAPRPool pool;
- status = pool.getStatus() ;
- ll_apr_assert_status(status);
+ LLScopedVolatileAPRPool scoped_pool;
for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
{
@@ -502,7 +495,7 @@ bool LLAres::process(U64 timeout)
apr_socket_t *aprSock = NULL;
- status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());
+ apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool);
if (status != APR_SUCCESS)
{
ll_apr_warn_status(status);
@@ -511,7 +504,7 @@ bool LLAres::process(U64 timeout)
aprFds[nactive].desc.s = aprSock;
aprFds[nactive].desc_type = APR_POLL_SOCKET;
- aprFds[nactive].p = pool.getAPRPool();
+ aprFds[nactive].p = scoped_pool;
aprFds[nactive].rtnevents = 0;
aprFds[nactive].client_data = &socks[i];
@@ -520,7 +513,7 @@ bool LLAres::process(U64 timeout)
if (nactive > 0)
{
- status = apr_poll(aprFds, nactive, &nsds, timeout);
+ apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout);
if (status != APR_SUCCESS && status != APR_TIMEUP)
{
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 785d07acb8..14e169c6b1 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -531,7 +531,7 @@ LLCurl::Multi::Multi()
mThreaded = LLCurl::sMultiThreaded && LLThread::currentID() == sMainThreadID;
if (mThreaded)
{
- mSignal = new LLCondition(NULL);
+ mSignal = new LLCondition();
}
else
{
@@ -1178,13 +1178,13 @@ void LLCurl::initClass(bool multi_threaded)
check_curl_code(code);
- Easy::sHandleMutex = new LLMutex(NULL);
+ Easy::sHandleMutex = new LLMutex();
#if SAFE_SSL
S32 mutex_count = CRYPTO_num_locks();
for (S32 i=0; i<mutex_count; i++)
{
- sSSLMutex.push_back(new LLMutex(NULL));
+ sSSLMutex.push_back(new LLMutex);
}
CRYPTO_set_id_callback(&LLCurl::ssl_thread_id);
CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback);
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 73e8a69085..920a57ab55 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -963,13 +963,9 @@ private:
// static
-LLHTTPNode& LLIOHTTPServer::create(
- apr_pool_t* pool, LLPumpIO& pump, U16 port)
+LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)
{
- LLSocket::ptr_t socket = LLSocket::create(
- pool,
- LLSocket::STREAM_TCP,
- port);
+ LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port);
if(!socket)
{
llerrs << "Unable to initialize socket" << llendl;
@@ -978,7 +974,7 @@ LLHTTPNode& LLIOHTTPServer::create(
LLHTTPResponseFactory* factory = new LLHTTPResponseFactory;
boost::shared_ptr<LLChainIOFactory> factory_ptr(factory);
- LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr);
+ LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr);
LLPumpIO::chain_t chain;
chain.push_back(LLIOPipe::ptr_t(server));
diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h
index 5c1b0531ff..2294e4b8ae 100644
--- a/indra/llmessage/lliohttpserver.h
+++ b/indra/llmessage/lliohttpserver.h
@@ -50,7 +50,7 @@ class LLIOHTTPServer
public:
typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data);
- static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port);
+ static LLHTTPNode& create(LLPumpIO& pump, U16 port);
/**< Creates an HTTP wire server on the pump for the given TCP port.
*
* Returns the root node of the new server. Add LLHTTPNode instances
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index ee9379f205..a885ba8ee1 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -35,6 +35,7 @@
#include "llhost.h"
#include "llmemtype.h"
#include "llpumpio.h"
+#include "llthread.h"
//
// constants
@@ -98,51 +99,31 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock)
///
// static
-LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
+LLSocket::ptr_t LLSocket::create(EType type, U16 port)
{
LLMemType m1(LLMemType::MTYPE_IO_TCP);
- LLSocket::ptr_t rv;
- apr_socket_t* socket = NULL;
- apr_pool_t* new_pool = NULL;
apr_status_t status = APR_EGENERAL;
-
- // create a pool for the socket
- status = apr_pool_create(&new_pool, pool);
- if(ll_apr_warn_status(status))
- {
- if(new_pool) apr_pool_destroy(new_pool);
- return rv;
- }
+ LLSocket::ptr_t rv(new LLSocket);
if(STREAM_TCP == type)
{
- status = apr_socket_create(
- &socket,
- APR_INET,
- SOCK_STREAM,
- APR_PROTO_TCP,
- new_pool);
+ status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool());
}
else if(DATAGRAM_UDP == type)
{
- status = apr_socket_create(
- &socket,
- APR_INET,
- SOCK_DGRAM,
- APR_PROTO_UDP,
- new_pool);
+ status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool());
}
else
{
- if(new_pool) apr_pool_destroy(new_pool);
+ rv.reset();
return rv;
}
if(ll_apr_warn_status(status))
{
- if(new_pool) apr_pool_destroy(new_pool);
+ rv->mSocket = NULL;
+ rv.reset();
return rv;
}
- rv = ptr_t(new LLSocket(socket, new_pool));
if(port > 0)
{
apr_sockaddr_t* sa = NULL;
@@ -152,7 +133,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
APR_UNSPEC,
port,
0,
- new_pool);
+ rv->mPool());
if(ll_apr_warn_status(status))
{
rv.reset();
@@ -160,8 +141,8 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
}
// This allows us to reuse the address on quick down/up. This
// is unlikely to create problems.
- ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1));
- status = apr_socket_bind(socket, sa);
+ ll_apr_warn_status(apr_socket_opt_set(rv->mSocket, APR_SO_REUSEADDR, 1));
+ status = apr_socket_bind(rv->mSocket, sa);
if(ll_apr_warn_status(status))
{
rv.reset();
@@ -175,7 +156,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
// to keep a queue of incoming connections for ACCEPT.
lldebugs << "Setting listen state for socket." << llendl;
status = apr_socket_listen(
- socket,
+ rv->mSocket,
LL_DEFAULT_LISTEN_BACKLOG);
if(ll_apr_warn_status(status))
{
@@ -196,21 +177,28 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
}
// static
-LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool)
+LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket)
{
LLMemType m1(LLMemType::MTYPE_IO_TCP);
- LLSocket::ptr_t rv;
- if(!socket)
+ if (!listen_socket->getSocket())
+ {
+ status = APR_ENOSOCKET;
+ return LLSocket::ptr_t();
+ }
+ LLSocket::ptr_t rv(new LLSocket);
+ lldebugs << "accepting socket" << llendl;
+ status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool());
+ if (status != APR_SUCCESS)
{
+ rv->mSocket = NULL;
+ rv.reset();
return rv;
}
- rv = ptr_t(new LLSocket(socket, pool));
rv->mPort = PORT_EPHEMERAL;
rv->setNonBlocking();
return rv;
}
-
bool LLSocket::blockingConnect(const LLHost& host)
{
if(!mSocket) return false;
@@ -223,7 +211,7 @@ bool LLSocket::blockingConnect(const LLHost& host)
APR_UNSPEC,
host.getPort(),
0,
- mPool)))
+ mPool())))
{
return false;
}
@@ -234,13 +222,11 @@ bool LLSocket::blockingConnect(const LLHost& host)
return true;
}
-LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) :
- mSocket(socket),
- mPool(pool),
+LLSocket::LLSocket() :
+ mSocket(NULL),
+ mPool(LLThread::tldata().mRootPool),
mPort(PORT_INVALID)
{
- ll_debug_socket("Constructing wholely formed socket", mSocket);
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
}
LLSocket::~LLSocket()
@@ -253,11 +239,6 @@ LLSocket::~LLSocket()
apr_socket_close(mSocket);
mSocket = NULL;
}
- if(mPool)
- {
- apr_pool_destroy(mPool);
- mPool = NULL;
- }
}
// See http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-13.html#ss13.4
@@ -539,10 +520,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
///
LLIOServerSocket::LLIOServerSocket(
- apr_pool_t* pool,
LLIOServerSocket::socket_t listener,
factory_t factory) :
- mPool(pool),
mListenSocket(listener),
mReactor(factory),
mInitialized(false),
@@ -604,21 +583,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
lldebugs << "accepting socket" << llendl;
PUMP_DEBUG;
- apr_pool_t* new_pool = NULL;
- apr_status_t status = apr_pool_create(&new_pool, mPool);
- apr_socket_t* socket = NULL;
- status = apr_socket_accept(
- &socket,
- mListenSocket->getSocket(),
- new_pool);
- LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool));
+ apr_status_t status;
+ LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket));
//EStatus rv = STATUS_ERROR;
- if(llsocket)
+ if(llsocket && status == APR_SUCCESS)
{
PUMP_DEBUG;
apr_sockaddr_t* remote_addr;
- apr_socket_addr_get(&remote_addr, APR_REMOTE, socket);
+ apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket());
char* remote_host_string;
apr_sockaddr_ip_get(&remote_host_string, remote_addr);
@@ -633,7 +606,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
{
chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));
pump->addChain(chain, mResponseTimeout);
- status = STATUS_OK;
}
else
{
@@ -642,7 +614,8 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
}
else
{
- llwarns << "Unable to create linden socket." << llendl;
+ char buf[256];
+ llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl;
}
PUMP_DEBUG;
@@ -655,11 +628,10 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
#if 0
LLIODataSocket::LLIODataSocket(
U16 suggested_port,
- U16 start_discovery_port,
- apr_pool_t* pool) :
+ U16 start_discovery_port) :
mSocket(NULL)
{
- if(!pool || (PORT_INVALID == suggested_port)) return;
+ if(PORT_INVALID == suggested_port) return;
if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return;
apr_sockaddr_t* sa = NULL;
if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return;
diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h
index be0f7dfcc6..f0a6f25657 100644
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
@@ -38,7 +38,6 @@
*/
#include "lliopipe.h"
-#include "apr_pools.h"
#include "apr_network_io.h"
#include "llchainio.h"
@@ -88,34 +87,22 @@ public:
* socket. If you intend the socket to be known to external
* clients without prior port notification, do not use
* PORT_EPHEMERAL.
- * @param pool The apr pool to use. A child pool will be created
- * and associated with the socket.
* @param type The type of socket to create
* @param port The port for the socket
* @return A valid socket shared pointer if the call worked.
*/
static ptr_t create(
- apr_pool_t* pool,
EType type,
U16 port = PORT_EPHEMERAL);
/**
- * @brief Create a LLSocket when you already have an apr socket.
+ * @brief Create a LLSocket by accepting a connection from a listen socket.
*
- * This method assumes an ephemeral port. This is typically used
- * by calls which spawn a socket such as a call to
- * <code>accept()</code> as in the server socket. This call should
- * not fail if you have a valid apr socket.
- * Because of the nature of how accept() works, you are expected
- * to create a new pool for the socket, use that pool for the
- * accept, and pass it in here where it will be bound with the
- * socket and destroyed at the same time.
- * @param socket The apr socket to use
- * @param pool The pool used to create the socket. *NOTE: The pool
- * passed in will be DESTROYED.
+ * @param status Output. Status of the accept if a valid listen socket was passed.
+ * @param listen_socket The listen socket to use.
* @return A valid socket shared pointer if the call worked.
*/
- static ptr_t create(apr_socket_t* socket, apr_pool_t* pool);
+ static ptr_t create(apr_status_t& status, ptr_t& listen_socket);
/**
* @brief Perform a blocking connect to a host. Do not use in production.
@@ -146,6 +133,12 @@ public:
apr_socket_t* getSocket() const { return mSocket; }
/**
+ * @brief Protected constructor since should only make sockets
+ * with one of the two <code>create()</code> calls.
+ */
+ LLSocket(void);
+
+ /**
* @brief Set default socket options, with SO_NONBLOCK = 0 and a timeout in us.
* @param timeout Number of microseconds to wait on this socket. Any
* negative number means block-forever. TIMEOUT OF 0 IS NON-PORTABLE.
@@ -174,8 +167,8 @@ protected:
// The apr socket.
apr_socket_t* mSocket;
- // our memory pool
- apr_pool_t* mPool;
+ // Our memory pool.
+ LLAPRPool mPool;
// The port if we know it.
U16 mPort;
@@ -300,7 +293,7 @@ class LLIOServerSocket : public LLIOPipe
public:
typedef LLSocket::ptr_t socket_t;
typedef boost::shared_ptr<LLChainIOFactory> factory_t;
- LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor);
+ LLIOServerSocket(socket_t listener, factory_t reactor);
virtual ~LLIOServerSocket();
/**
@@ -332,7 +325,6 @@ protected:
//@}
protected:
- apr_pool_t* mPool;
socket_t mListenSocket;
factory_t mReactor;
bool mInitialized;
@@ -366,8 +358,7 @@ public:
*/
LLIODataSocket(
U16 suggested_port,
- U16 start_discovery_port,
- apr_pool_t* pool);
+ U16 start_discovery_port);
virtual ~LLIODataSocket();
protected:
diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp
index 08b31e9c7a..8a898ab1b0 100644
--- a/indra/llmessage/llmail.cpp
+++ b/indra/llmessage/llmail.cpp
@@ -50,6 +50,7 @@
#include "llstring.h"
#include "lluuid.h"
#include "net.h"
+#include "llaprpool.h"
//
// constants
@@ -57,7 +58,7 @@
const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
static bool gMailEnabled = true;
-static apr_pool_t* gMailPool;
+static LLAPRPool gMailPool;
static apr_sockaddr_t* gSockAddr;
static apr_socket_t* gMailSocket;
@@ -82,7 +83,7 @@ bool connect_smtp()
gSockAddr->sa.sin.sin_family,
SOCK_STREAM,
APR_PROTO_TCP,
- gMailPool);
+ gMailPool());
if(ll_apr_warn_status(status)) return false;
status = apr_socket_connect(gMailSocket, gSockAddr);
if(ll_apr_warn_status(status))
@@ -139,19 +140,19 @@ BOOL LLMail::send(
}
// static
-void LLMail::init(const std::string& hostname, apr_pool_t* pool)
+void LLMail::init(const std::string& hostname)
{
gMailSocket = NULL;
- if(hostname.empty() || !pool)
+ if (hostname.empty())
{
- gMailPool = NULL;
gSockAddr = NULL;
+ gMailPool.destroy();
}
else
{
- gMailPool = pool;
+ gMailPool.create();
- // collect all the information into a socaddr sturcture. the
+ // Collect all the information into a sockaddr structure. the
// documentation is a bit unclear, but I either have to
// specify APR_UNSPEC or not specify any flags. I am not sure
// which option is better.
@@ -161,7 +162,7 @@ void LLMail::init(const std::string& hostname, apr_pool_t* pool)
APR_UNSPEC,
25,
APR_IPV4_ADDR_OK,
- gMailPool);
+ gMailPool());
ll_apr_warn_status(status);
}
}
diff --git a/indra/llmessage/llmail.h b/indra/llmessage/llmail.h
index 3791714363..0a5c532088 100644
--- a/indra/llmessage/llmail.h
+++ b/indra/llmessage/llmail.h
@@ -27,15 +27,13 @@
#ifndef LL_LLMAIL_H
#define LL_LLMAIL_H
-typedef struct apr_pool_t apr_pool_t;
-
#include "llsd.h"
class LLMail
{
public:
// if hostname is NULL, then the host is resolved as 'mail'
- static void init(const std::string& hostname, apr_pool_t* pool);
+ static void init(const std::string& hostname);
// Allow all email transmission to be disabled/enabled.
static void enable(bool mail_enabled);
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index b26ac42899..3ffe6d2d3b 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -44,12 +44,12 @@ bool LLProxy::sUDPProxyEnabled = false;
// Some helpful TCP static functions.
static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
-static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host); // Open a TCP channel to a given host
+static LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a given host
static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel
LLProxy::LLProxy():
mHTTPProxyEnabled(false),
- mProxyMutex(0),
+ mProxyMutex(),
mUDPProxy(),
mTCPProxy(),
mHTTPProxy(),
@@ -210,7 +210,7 @@ S32 LLProxy::startSOCKSProxy(LLHost host)
// Close any running SOCKS connection.
stopSOCKSProxy();
- mProxyControlChannel = tcp_open_channel(gAPRPoolp, mTCPProxy);
+ mProxyControlChannel = tcp_open_channel(mTCPProxy);
if (!mProxyControlChannel)
{
return SOCKS_HOST_CONNECT_FAILED;
@@ -515,13 +515,12 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
*
* Checks for a successful connection, and makes sure the connection is closed if it fails.
*
- * @param pool APR pool to pass into the LLSocket.
* @param host The host to open the connection to.
* @return The created socket. Will evaluate as NULL if the connection is unsuccessful.
*/
-static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host)
+static LLSocket::ptr_t tcp_open_channel(LLHost host)
{
- LLSocket::ptr_t socket = LLSocket::create(pool, LLSocket::STREAM_TCP);
+ LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP);
bool connected = socket->blockingConnect(host);
if (!connected)
{
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index a8d2a0a224..89cfd66e1b 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -37,6 +37,7 @@
#include "llmemtype.h"
#include "llstl.h"
#include "llstat.h"
+#include "llthread.h"
// These should not be enabled in production, but they can be
// intensely useful during development for finding certain kinds of
@@ -162,14 +163,12 @@ struct ll_delete_apr_pollset_fd_client_data
/**
* LLPumpIO
*/
-LLPumpIO::LLPumpIO(apr_pool_t* pool) :
+LLPumpIO::LLPumpIO(void) :
mState(LLPumpIO::NORMAL),
mRebuildPollset(false),
mPollset(NULL),
mPollsetClientID(0),
mNextLock(0),
- mPool(NULL),
- mCurrentPool(NULL),
mCurrentPoolReallocCount(0),
mChainsMutex(NULL),
mCallbackMutex(NULL),
@@ -178,21 +177,24 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) :
mCurrentChain = mRunningChains.end();
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- initialize(pool);
+ initialize();
}
LLPumpIO::~LLPumpIO()
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- cleanup();
-}
-
-bool LLPumpIO::prime(apr_pool_t* pool)
-{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- cleanup();
- initialize(pool);
- return ((pool == NULL) ? false : true);
+#if LL_THREADS_APR
+ if (mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
+ if (mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
+#endif
+ mChainsMutex = NULL;
+ mCallbackMutex = NULL;
+ if(mPollset)
+ {
+// lldebugs << "cleaning up pollset" << llendl;
+ apr_pollset_destroy(mPollset);
+ mPollset = NULL;
+ }
}
bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
@@ -352,8 +354,7 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll)
{
// each fd needs a pool to work with, so if one was
// not specified, use this pool.
- // *FIX: Should it always be this pool?
- value.second.p = mPool;
+ value.second.p = (*mCurrentChain).mDescriptorsPool->operator()();
}
value.second.client_data = new S32(++mPollsetClientID);
(*mCurrentChain).mDescriptors.push_back(value);
@@ -825,39 +826,15 @@ void LLPumpIO::control(LLPumpIO::EControl op)
}
}
-void LLPumpIO::initialize(apr_pool_t* pool)
+void LLPumpIO::initialize(void)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- if(!pool) return;
+ mPool.create();
#if LL_THREADS_APR
// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
- apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
- apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
-#endif
- mPool = pool;
-}
-
-void LLPumpIO::cleanup()
-{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
-#if LL_THREADS_APR
- if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
- if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
+ apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
+ apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
#endif
- mChainsMutex = NULL;
- mCallbackMutex = NULL;
- if(mPollset)
- {
-// lldebugs << "cleaning up pollset" << llendl;
- apr_pollset_destroy(mPollset);
- mPollset = NULL;
- }
- if(mCurrentPool)
- {
- apr_pool_destroy(mCurrentPool);
- mCurrentPool = NULL;
- }
- mPool = NULL;
}
void LLPumpIO::rebuildPollset()
@@ -885,21 +862,19 @@ void LLPumpIO::rebuildPollset()
if(mCurrentPool
&& (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT)))
{
- apr_pool_destroy(mCurrentPool);
- mCurrentPool = NULL;
+ mCurrentPool.destroy();
mCurrentPoolReallocCount = 0;
}
if(!mCurrentPool)
{
- apr_status_t status = apr_pool_create(&mCurrentPool, mPool);
- (void)ll_apr_warn_status(status);
+ mCurrentPool.create(mPool);
}
// add all of the file descriptors
run_it = mRunningChains.begin();
LLChainInfo::conditionals_t::iterator fd_it;
LLChainInfo::conditionals_t::iterator fd_end;
- apr_pollset_create(&mPollset, size, mCurrentPool, 0);
+ apr_pollset_create(&mPollset, size, mCurrentPool(), 0);
for(; run_it != run_end; ++run_it)
{
fd_it = (*run_it).mDescriptors.begin();
@@ -1157,7 +1132,8 @@ bool LLPumpIO::handleChainError(
LLPumpIO::LLChainInfo::LLChainInfo() :
mInit(false),
mLock(0),
- mEOS(false)
+ mEOS(false),
+ mDescriptorsPool(new LLAPRPool(LLThread::tldata().mRootPool))
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index 9303c9d7fc..75c35ae7ab 100644
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
@@ -30,11 +30,12 @@
#define LL_LLPUMPIO_H
#include <set>
+#include <boost/shared_ptr.hpp>
#if LL_LINUX // needed for PATH_MAX in APR.
#include <sys/param.h>
#endif
-#include "apr_pools.h"
+#include "llaprpool.h"
#include "llbuffer.h"
#include "llframetimer.h"
#include "lliopipe.h"
@@ -58,9 +59,8 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS;
* <code>pump()</code> on a thread used for IO and call
* <code>respond()</code> on a thread that is expected to do higher
* level processing. You can call almost any other method from any
- * thread - see notes for each method for details. In order for the
- * threading abstraction to work, you need to call <code>prime()</code>
- * with a valid apr pool.
+ * thread - see notes for each method for details.
+ *
* A pump instance manages much of the state for the pipe, including
* the list of pipes in the chain, the channel for each element in the
* chain, the buffer, and if any pipe has marked the stream or process
@@ -79,7 +79,7 @@ public:
/**
* @brief Constructor.
*/
- LLPumpIO(apr_pool_t* pool);
+ LLPumpIO(void);
/**
* @brief Destructor.
@@ -87,17 +87,6 @@ public:
~LLPumpIO();
/**
- * @brief Prepare this pump for usage.
- *
- * If you fail to call this method prior to use, the pump will
- * try to work, but will not come with any thread locking
- * mechanisms.
- * @param pool The apr pool to use.
- * @return Returns true if the pump is primed.
- */
- bool prime(apr_pool_t* pool);
-
- /**
* @brief Typedef for having a chain of pipes.
*/
typedef std::vector<LLIOPipe::ptr_t> chain_t;
@@ -368,6 +357,7 @@ protected:
typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t;
typedef std::vector<pipe_conditional_t> conditionals_t;
conditionals_t mDescriptors;
+ boost::shared_ptr<LLAPRPool> mDescriptorsPool;
};
// All the running chains & info
@@ -386,9 +376,9 @@ protected:
callbacks_t mPendingCallbacks;
callbacks_t mCallbacks;
- // memory allocator for pollsets & mutexes.
- apr_pool_t* mPool;
- apr_pool_t* mCurrentPool;
+ // Memory pool for pollsets & mutexes.
+ LLAPRPool mPool;
+ LLAPRPool mCurrentPool;
S32 mCurrentPoolReallocCount;
#if LL_THREADS_APR
@@ -400,8 +390,7 @@ protected:
#endif
protected:
- void initialize(apr_pool_t* pool);
- void cleanup();
+ void initialize();
/**
* @brief Given the internal state of the chains, rebuild the pollset
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index d5400e4169..91a5a8ce2c 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -41,6 +41,7 @@
#include "llstring.h"
#include "apr_env.h"
#include "llapr.h"
+#include "llscopedvolatileaprpool.h"
static const U32 HTTP_STATUS_PIPE_ERROR = 499;
/**
@@ -211,26 +212,31 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback)
// is called with use_proxy = FALSE
void LLURLRequest::useProxy(bool use_proxy)
{
- static char *env_proxy;
+ static std::string env_proxy;
- if (use_proxy && (env_proxy == NULL))
+ if (use_proxy && env_proxy.empty())
{
- apr_status_t status;
- LLAPRPool pool;
- status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool());
+ char* env_proxy_str;
+ LLScopedVolatileAPRPool scoped_pool;
+ apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool);
if (status != APR_SUCCESS)
{
- status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool());
+ status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool);
}
if (status != APR_SUCCESS)
{
- use_proxy = FALSE;
+ use_proxy = false;
}
+ else
+ {
+ // env_proxy_str is stored in the scoped_pool, so we have to make a copy.
+ env_proxy = env_proxy_str;
+ }
}
- LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << LL_ENDL;
+ LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (!env_proxy.empty() ? env_proxy : "(null)") << LL_ENDL;
- if (env_proxy && use_proxy)
+ if (use_proxy && !env_proxy.empty())
{
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
}
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index d0b0e178b8..7d21e35f96 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -97,8 +97,10 @@ std::string get_shared_secret();
class LLMessagePollInfo
{
public:
+ LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { }
apr_socket_t *mAPRSocketp;
apr_pollfd_t mPollFD;
+ LLAPRPool mPool;
};
namespace
@@ -287,20 +289,13 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,
}
// LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl;
- //
- // Create the data structure that we can poll on
- //
- if (!gAPRPoolp)
- {
- LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl;
- ll_init_apr();
- }
+ mPollInfop = new LLMessagePollInfo;
+
apr_socket_t *aprSocketp = NULL;
- apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp);
+ apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool());
- mPollInfop = new LLMessagePollInfo;
mPollInfop->mAPRSocketp = aprSocketp;
- mPollInfop->mPollFD.p = gAPRPoolp;
+ mPollInfop->mPollFD.p = mPollInfop->mPool();
mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET;
mPollInfop->mPollFD.reqevents = APR_POLLIN;
mPollInfop->mPollFD.rtnevents = 0;
diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h
index 2aff90ca1e..23e1c791f4 100644
--- a/indra/llmessage/tests/networkio.h
+++ b/indra/llmessage/tests/networkio.h
@@ -30,7 +30,6 @@
#define LL_NETWORKIO_H
#include "llmemory.h" // LLSingleton
-#include "llapr.h"
#include "llares.h"
#include "llpumpio.h"
#include "llhttpclient.h"
@@ -48,14 +47,8 @@ public:
mServicePump(NULL),
mDone(false)
{
- ll_init_apr();
- if (! gAPRPoolp)
- {
- throw std::runtime_error("Can't initialize APR");
- }
-
// Create IO Pump to use for HTTP Requests.
- mServicePump = new LLPumpIO(gAPRPoolp);
+ mServicePump = new LLPumpIO;
LLHTTPClient::setPump(*mServicePump);
if (ll_init_ares() == NULL || !gAres->isInitialized())
{