diff options
| author | Dave Parks <davep@lindenlab.com> | 2011-10-14 11:58:35 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2011-10-14 11:58:35 -0500 | 
| commit | c0ca8e5e2e4d3f591db3175f09c0b64b6b2e10c5 (patch) | |
| tree | 28ea7a212319b0bd452c68e54f374904bfe6ed8a /indra/llmessage | |
| parent | fc2929bf4f6366c3a3386e4b79b0fda7bd0466ba (diff) | |
| parent | 4331c112aba074562e9a8826fe6d271a94f790f0 (diff) | |
Merge backout of b782a75c99e6
Diffstat (limited to 'indra/llmessage')
| -rw-r--r-- | indra/llmessage/llares.cpp | 17 | ||||
| -rw-r--r-- | indra/llmessage/llcurl.cpp | 2 | ||||
| -rw-r--r-- | indra/llmessage/lliohttpserver.cpp | 10 | ||||
| -rw-r--r-- | indra/llmessage/lliohttpserver.h | 2 | ||||
| -rw-r--r-- | indra/llmessage/lliosocket.cpp | 99 | ||||
| -rw-r--r-- | indra/llmessage/lliosocket.h | 33 | ||||
| -rw-r--r-- | indra/llmessage/llmail.cpp | 17 | ||||
| -rw-r--r-- | indra/llmessage/llmail.h | 4 | ||||
| -rw-r--r-- | indra/llmessage/llpumpio.cpp | 74 | ||||
| -rw-r--r-- | indra/llmessage/llpumpio.h | 31 | ||||
| -rw-r--r-- | indra/llmessage/llurlrequest.cpp | 25 | ||||
| -rw-r--r-- | indra/llmessage/message.cpp | 17 | ||||
| -rw-r--r-- | indra/llmessage/tests/networkio.h | 9 | 
13 files changed, 218 insertions, 122 deletions
| diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp index fab9858b69..5a67035ed1 100644 --- a/indra/llmessage/llares.cpp +++ b/indra/llmessage/llares.cpp @@ -28,7 +28,6 @@  #include "linden_common.h"  #include "llares.h" -#include "llscopedvolatileaprpool.h"  #include <ares_dns.h>  #include <ares_version.h> @@ -465,6 +464,11 @@ 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;	 @@ -478,7 +482,10 @@ bool LLAres::process(U64 timeout)  		return nsds > 0;  	} -	LLScopedVolatileAPRPool scoped_pool; +	apr_status_t status; +	LLAPRPool pool; +	status = pool.getStatus() ; +	ll_apr_assert_status(status);  	for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)  	{ @@ -495,7 +502,7 @@ bool LLAres::process(U64 timeout)  		apr_socket_t *aprSock = NULL; -		apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool); +		status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());  		if (status != APR_SUCCESS)  		{  			ll_apr_warn_status(status); @@ -504,7 +511,7 @@ bool LLAres::process(U64 timeout)  		aprFds[nactive].desc.s = aprSock;  		aprFds[nactive].desc_type = APR_POLL_SOCKET; -		aprFds[nactive].p = scoped_pool; +		aprFds[nactive].p = pool.getAPRPool();  		aprFds[nactive].rtnevents = 0;  		aprFds[nactive].client_data = &socks[i]; @@ -513,7 +520,7 @@ bool LLAres::process(U64 timeout)  	if (nactive > 0)  	{ -		apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout); +		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 6d9213f51b..6e063818e2 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -1196,7 +1196,7 @@ void LLCurl::initClass(bool multi_threaded)  	S32 mutex_count = CRYPTO_num_locks();  	for (S32 i=0; i<mutex_count; i++)  	{ -		sSSLMutex.push_back(new LLMutex); +		sSSLMutex.push_back(new LLMutex(NULL));  	}  	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 920a57ab55..73e8a69085 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -963,9 +963,13 @@ private:  // static -LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port) +LLHTTPNode& LLIOHTTPServer::create( +	apr_pool_t* pool, LLPumpIO& pump, U16 port)  { -	LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port); +	LLSocket::ptr_t socket = LLSocket::create( +        pool, +        LLSocket::STREAM_TCP, +        port);      if(!socket)      {          llerrs << "Unable to initialize socket" << llendl; @@ -974,7 +978,7 @@ LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)      LLHTTPResponseFactory* factory = new LLHTTPResponseFactory;  	boost::shared_ptr<LLChainIOFactory> factory_ptr(factory); -    LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr); +    LLIOServerSocket* server = new LLIOServerSocket(pool, 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 2294e4b8ae..5c1b0531ff 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(LLPumpIO& pump, U16 port); +	static LLHTTPNode& create(apr_pool_t* pool, 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 a885ba8ee1..54ceab3422 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -35,7 +35,6 @@  #include "llhost.h"  #include "llmemtype.h"  #include "llpumpio.h" -#include "llthread.h"  //  // constants @@ -99,31 +98,51 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock)  ///  // static -LLSocket::ptr_t LLSocket::create(EType type, U16 port) +LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, 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; -	LLSocket::ptr_t rv(new LLSocket); + +	// 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; +	}  	if(STREAM_TCP == type)  	{ -		status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool()); +		status = apr_socket_create( +			&socket, +			APR_INET, +			SOCK_STREAM, +			APR_PROTO_TCP, +			new_pool);  	}  	else if(DATAGRAM_UDP == type)  	{ -		status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool()); +		status = apr_socket_create( +			&socket, +			APR_INET, +			SOCK_DGRAM, +			APR_PROTO_UDP, +			new_pool);  	}  	else  	{ -		rv.reset(); +		if(new_pool) apr_pool_destroy(new_pool);  		return rv;  	}  	if(ll_apr_warn_status(status))  	{ -		rv->mSocket = NULL; -		rv.reset(); +		if(new_pool) apr_pool_destroy(new_pool);  		return rv;  	} +	rv = ptr_t(new LLSocket(socket, new_pool));  	if(port > 0)  	{  		apr_sockaddr_t* sa = NULL; @@ -133,7 +152,7 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)  			APR_UNSPEC,  			port,  			0, -			rv->mPool()); +			new_pool);  		if(ll_apr_warn_status(status))  		{  			rv.reset(); @@ -141,8 +160,8 @@ LLSocket::ptr_t LLSocket::create(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(rv->mSocket, APR_SO_REUSEADDR, 1)); -		status = apr_socket_bind(rv->mSocket, sa); +		ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); +		status = apr_socket_bind(socket, sa);  		if(ll_apr_warn_status(status))  		{  			rv.reset(); @@ -156,7 +175,7 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)  			// to keep a queue of incoming connections for ACCEPT.  			lldebugs << "Setting listen state for socket." << llendl;  			status = apr_socket_listen( -				rv->mSocket, +				socket,  				LL_DEFAULT_LISTEN_BACKLOG);  			if(ll_apr_warn_status(status))  			{ @@ -177,28 +196,21 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)  }  // static -LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket) +LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool)  {  	LLMemType m1(LLMemType::MTYPE_IO_TCP); -	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) +	LLSocket::ptr_t rv; +	if(!socket)  	{ -		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; @@ -211,7 +223,7 @@ bool LLSocket::blockingConnect(const LLHost& host)  		APR_UNSPEC,  		host.getPort(),  		0, -		mPool()))) +		mPool)))  	{  		return false;  	} @@ -222,11 +234,13 @@ bool LLSocket::blockingConnect(const LLHost& host)  	return true;  } -LLSocket::LLSocket() : -	mSocket(NULL), -	mPool(LLThread::tldata().mRootPool), +LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) : +	mSocket(socket), +	mPool(pool),  	mPort(PORT_INVALID)  { +	ll_debug_socket("Constructing wholely formed socket", mSocket); +	LLMemType m1(LLMemType::MTYPE_IO_TCP);  }  LLSocket::~LLSocket() @@ -239,6 +253,10 @@ LLSocket::~LLSocket()  		apr_socket_close(mSocket);  		mSocket = NULL;  	} +	if(mPool) +	{ +		apr_pool_destroy(mPool); +	}  }  // See http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-13.html#ss13.4 @@ -520,8 +538,10 @@ 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), @@ -583,15 +603,21 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(  	lldebugs << "accepting socket" << llendl;  	PUMP_DEBUG; -	apr_status_t status; -	LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket)); +	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));  	//EStatus rv = STATUS_ERROR; -	if(llsocket && status == APR_SUCCESS) +	if(llsocket)  	{  		PUMP_DEBUG;  		apr_sockaddr_t* remote_addr; -		apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket()); +		apr_socket_addr_get(&remote_addr, APR_REMOTE, socket);  		char* remote_host_string;  		apr_sockaddr_ip_get(&remote_host_string, remote_addr); @@ -606,6 +632,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(  		{  			chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));  			pump->addChain(chain, mResponseTimeout); +			status = STATUS_OK;  		}  		else  		{ @@ -614,8 +641,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(  	}  	else  	{ -		char buf[256]; -		llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl; +		llwarns << "Unable to create linden socket." << llendl;  	}  	PUMP_DEBUG; @@ -628,10 +654,11 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(  #if 0  LLIODataSocket::LLIODataSocket(  	U16 suggested_port, -	U16 start_discovery_port) : +	U16 start_discovery_port, +	apr_pool_t* pool) :   	mSocket(NULL)  { -	if(PORT_INVALID == suggested_port) return; +	if(!pool || (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 f0a6f25657..d8ee4e9f98 100644 --- a/indra/llmessage/lliosocket.h +++ b/indra/llmessage/lliosocket.h @@ -38,6 +38,7 @@   */  #include "lliopipe.h" +#include "apr_pools.h"  #include "apr_network_io.h"  #include "llchainio.h" @@ -87,22 +88,34 @@ 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 by accepting a connection from a listen socket. +	 * @brief Create a LLSocket when you already have an apr socket.  	 * -	 * @param status Output. Status of the accept if a valid listen socket was passed. -	 * @param listen_socket The listen socket to use. +	 * 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.  	 * @return A valid socket shared pointer if the call worked.  	 */ -	static ptr_t create(apr_status_t& status, ptr_t& listen_socket); +	static ptr_t create(apr_socket_t* socket, apr_pool_t* pool);  	/**   	 * @brief Perform a blocking connect to a host. Do not use in production. @@ -136,7 +149,7 @@ public:  	 * @brief Protected constructor since should only make sockets  	 * with one of the two <code>create()</code> calls.  	 */ -	LLSocket(void); +	LLSocket(apr_socket_t* socket, apr_pool_t* pool);  	/**   	 * @brief Set default socket options, with SO_NONBLOCK = 0 and a timeout in us. @@ -167,8 +180,8 @@ protected:  	// The apr socket.  	apr_socket_t* mSocket; -	// Our memory pool. -	LLAPRPool mPool; +	// our memory pool +	apr_pool_t* mPool;  	// The port if we know it.  	U16 mPort; @@ -293,7 +306,7 @@ class LLIOServerSocket : public LLIOPipe  public:  	typedef LLSocket::ptr_t socket_t;  	typedef boost::shared_ptr<LLChainIOFactory> factory_t; -	LLIOServerSocket(socket_t listener, factory_t reactor); +	LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor);  	virtual ~LLIOServerSocket();  	/**  @@ -325,6 +338,7 @@ protected:  	//@}  protected: +	apr_pool_t* mPool;  	socket_t mListenSocket;  	factory_t mReactor;  	bool mInitialized; @@ -358,7 +372,8 @@ public:  	 */  	LLIODataSocket(  		U16 suggested_port, -		U16 start_discovery_port); +		U16 start_discovery_port, +		apr_pool_t* pool);  	virtual ~LLIODataSocket();  protected: diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp index 8a898ab1b0..08b31e9c7a 100644 --- a/indra/llmessage/llmail.cpp +++ b/indra/llmessage/llmail.cpp @@ -50,7 +50,6 @@  #include "llstring.h"  #include "lluuid.h"  #include "net.h" -#include "llaprpool.h"  //  // constants @@ -58,7 +57,7 @@  const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;  static bool gMailEnabled = true; -static LLAPRPool gMailPool; +static apr_pool_t* gMailPool;  static apr_sockaddr_t* gSockAddr;  static apr_socket_t* gMailSocket; @@ -83,7 +82,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)) @@ -140,19 +139,19 @@ BOOL LLMail::send(  }  // static -void LLMail::init(const std::string& hostname) +void LLMail::init(const std::string& hostname, apr_pool_t* pool)  {  	gMailSocket = NULL; -	if (hostname.empty()) +	if(hostname.empty() || !pool)  	{ +		gMailPool = NULL;  		gSockAddr = NULL; -		gMailPool.destroy();  	}  	else  	{ -		gMailPool.create(); +		gMailPool = pool; -		// Collect all the information into a sockaddr structure. the +		// collect all the information into a socaddr sturcture. 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. @@ -162,7 +161,7 @@ void LLMail::init(const std::string& hostname)  			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 0a5c532088..3791714363 100644 --- a/indra/llmessage/llmail.h +++ b/indra/llmessage/llmail.h @@ -27,13 +27,15 @@  #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); +	static void init(const std::string& hostname, apr_pool_t* pool);  	// Allow all email transmission to be disabled/enabled.  	static void enable(bool mail_enabled); diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 89cfd66e1b..a8d2a0a224 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -37,7 +37,6 @@  #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 @@ -163,12 +162,14 @@ struct ll_delete_apr_pollset_fd_client_data  /**   * LLPumpIO   */ -LLPumpIO::LLPumpIO(void) : +LLPumpIO::LLPumpIO(apr_pool_t* pool) :  	mState(LLPumpIO::NORMAL),  	mRebuildPollset(false),  	mPollset(NULL),  	mPollsetClientID(0),  	mNextLock(0), +	mPool(NULL), +	mCurrentPool(NULL),  	mCurrentPoolReallocCount(0),  	mChainsMutex(NULL),  	mCallbackMutex(NULL), @@ -177,24 +178,21 @@ LLPumpIO::LLPumpIO(void) :  	mCurrentChain = mRunningChains.end();  	LLMemType m1(LLMemType::MTYPE_IO_PUMP); -	initialize(); +	initialize(pool);  }  LLPumpIO::~LLPumpIO()  {  	LLMemType m1(LLMemType::MTYPE_IO_PUMP); -#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; -	} +	cleanup(); +} + +bool LLPumpIO::prime(apr_pool_t* pool) +{ +	LLMemType m1(LLMemType::MTYPE_IO_PUMP); +	cleanup(); +	initialize(pool); +	return ((pool == NULL) ? false : true);  }  bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) @@ -354,7 +352,8 @@ 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. -		value.second.p = (*mCurrentChain).mDescriptorsPool->operator()(); +		// *FIX: Should it always be this pool? +		value.second.p = mPool;  	}  	value.second.client_data = new S32(++mPollsetClientID);  	(*mCurrentChain).mDescriptors.push_back(value); @@ -826,15 +825,39 @@ void LLPumpIO::control(LLPumpIO::EControl op)  	}  } -void LLPumpIO::initialize(void) +void LLPumpIO::initialize(apr_pool_t* pool)  {  	LLMemType m1(LLMemType::MTYPE_IO_PUMP); -	mPool.create(); +	if(!pool) return;  #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, mPool()); -	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool()); +	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);  #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() @@ -862,19 +885,21 @@ void LLPumpIO::rebuildPollset()  		if(mCurrentPool  		   && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT)))  		{ -			mCurrentPool.destroy(); +			apr_pool_destroy(mCurrentPool); +			mCurrentPool = NULL;  			mCurrentPoolReallocCount = 0;  		}  		if(!mCurrentPool)  		{ -			mCurrentPool.create(mPool); +			apr_status_t status = apr_pool_create(&mCurrentPool, mPool); +			(void)ll_apr_warn_status(status);  		}  		// 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(); @@ -1132,8 +1157,7 @@ bool LLPumpIO::handleChainError(  LLPumpIO::LLChainInfo::LLChainInfo() :  	mInit(false),  	mLock(0), -	mEOS(false), -	mDescriptorsPool(new LLAPRPool(LLThread::tldata().mRootPool)) +	mEOS(false)  {  	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 75c35ae7ab..9303c9d7fc 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -30,12 +30,11 @@  #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 "llaprpool.h" +#include "apr_pools.h"  #include "llbuffer.h"  #include "llframetimer.h"  #include "lliopipe.h" @@ -59,8 +58,9 @@ 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. - * + * 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.   * 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(void); +	LLPumpIO(apr_pool_t* pool);  	/**  	 * @brief Destructor. @@ -87,6 +87,17 @@ 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; @@ -357,7 +368,6 @@ 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 @@ -376,9 +386,9 @@ protected:  	callbacks_t mPendingCallbacks;  	callbacks_t mCallbacks; -	// Memory pool for pollsets & mutexes. -	LLAPRPool mPool; -	LLAPRPool mCurrentPool; +	// memory allocator for pollsets & mutexes. +	apr_pool_t* mPool; +	apr_pool_t* mCurrentPool;  	S32 mCurrentPoolReallocCount;  #if LL_THREADS_APR @@ -390,7 +400,8 @@ protected:  #endif  protected: -	void initialize(); +	void initialize(apr_pool_t* pool); +	void cleanup();  	/**   	 * @brief Given the internal state of the chains, rebuild the pollset diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 91a5a8ce2c..fa03bb7512 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -41,7 +41,6 @@  #include "llstring.h"  #include "apr_env.h"  #include "llapr.h" -#include "llscopedvolatileaprpool.h"  static const U32 HTTP_STATUS_PIPE_ERROR = 499;  /** @@ -212,31 +211,27 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback)  // is called with use_proxy = FALSE  void LLURLRequest::useProxy(bool use_proxy)  { -    static std::string env_proxy; +    static char *env_proxy; -    if (use_proxy && env_proxy.empty()) +    if (use_proxy && (env_proxy == NULL))      { -		char* env_proxy_str; -        LLScopedVolatileAPRPool scoped_pool; -        apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool); +        apr_status_t status; +        LLAPRPool pool; +		status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool());          if (status != APR_SUCCESS)          { -			status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool); +			status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool());          }          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.empty() ? env_proxy : "(null)") << LL_ENDL; -    if (use_proxy && !env_proxy.empty()) +    lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl; + +    if (env_proxy && use_proxy)      {  		mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);      } diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 7d21e35f96..d0b0e178b8 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -97,10 +97,8 @@ 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 @@ -289,13 +287,20 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,  	}  //	LL_DEBUGS("Messaging") <<  << "*** port: " << mPort << llendl; -	mPollInfop = new LLMessagePollInfo; - +	// +	// 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(); +	}  	apr_socket_t *aprSocketp = NULL; -	apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool()); +	apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp); +	mPollInfop = new LLMessagePollInfo;  	mPollInfop->mAPRSocketp = aprSocketp; -	mPollInfop->mPollFD.p = mPollInfop->mPool(); +	mPollInfop->mPollFD.p = gAPRPoolp;  	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 23e1c791f4..2aff90ca1e 100644 --- a/indra/llmessage/tests/networkio.h +++ b/indra/llmessage/tests/networkio.h @@ -30,6 +30,7 @@  #define LL_NETWORKIO_H  #include "llmemory.h"               // LLSingleton +#include "llapr.h"  #include "llares.h"  #include "llpumpio.h"  #include "llhttpclient.h" @@ -47,8 +48,14 @@ 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; +        mServicePump = new LLPumpIO(gAPRPoolp);          LLHTTPClient::setPump(*mServicePump);          if (ll_init_ares() == NULL || !gAres->isInitialized())          { | 
