diff options
Diffstat (limited to 'indra/llmessage')
| -rw-r--r-- | indra/llmessage/llares.cpp | 17 | ||||
| -rw-r--r-- | indra/llmessage/llcurl.cpp | 6 | ||||
| -rw-r--r-- | indra/llmessage/lliohttpserver.cpp | 10 | ||||
| -rw-r--r-- | indra/llmessage/lliohttpserver.h | 2 | ||||
| -rw-r--r-- | indra/llmessage/lliosocket.cpp | 100 | ||||
| -rw-r--r-- | indra/llmessage/lliosocket.h | 37 | ||||
| -rw-r--r-- | indra/llmessage/llmail.cpp | 17 | ||||
| -rw-r--r-- | indra/llmessage/llmail.h | 4 | ||||
| -rw-r--r-- | indra/llmessage/llproxy.cpp | 11 | ||||
| -rw-r--r-- | indra/llmessage/llproxy.h | 3 | ||||
| -rw-r--r-- | indra/llmessage/llpumpio.cpp | 74 | ||||
| -rw-r--r-- | indra/llmessage/llpumpio.h | 31 | ||||
| -rw-r--r-- | indra/llmessage/llurlrequest.cpp | 24 | ||||
| -rw-r--r-- | indra/llmessage/message.cpp | 17 | ||||
| -rw-r--r-- | indra/llmessage/tests/networkio.h | 9 | 
15 files changed, 134 insertions, 228 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 bfdf49c74b..a3de178d78 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 3f4a6accbf..19f1fc6545 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -44,15 +44,14 @@ bool LLProxy::sUDPProxyEnabled = false;  // Some helpful TCP static functions.  static S32 tcp_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(), -		mPool(gAPRPoolp),  		mHTTPProxy(),  		mProxyType(LLPROXY_SOCKS),  		mAuthMethodSelected(METHOD_NOAUTH), @@ -203,7 +202,7 @@ S32 LLProxy::startSOCKSProxy(LLHost host)  	if (status == SOCKS_OK)  	{ -		mProxyControlChannel = tcp_open_channel(mPool, mTCPProxy); +		mProxyControlChannel = tcp_open_channel(mTCPProxy);  		if (!mProxyControlChannel)  		{  			status = SOCKS_HOST_CONNECT_FAILED; @@ -527,9 +526,9 @@ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outl   * @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/llproxy.h b/indra/llmessage/llproxy.h index 29e7e28567..621debb61d 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -315,9 +315,6 @@ private:  	// socket handle to proxy TCP control channel  	LLSocket::ptr_t mProxyControlChannel; -	// APR pool for the socket -	apr_pool_t* mPool; -  	// END OF UNSHARED MEMBERS  	// MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex! 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())          { | 
