Added a thread-safe and robust wrapper for APR pools.
See http://redmine.imprudenceviewer.org/issues/590 and https://jira.secondlife.com/browse/SNOW-596
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#include "llapr.h"
|
||||
#define CARES_STATICLIB
|
||||
#include "llares.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
# define ns_c_in 1
|
||||
@@ -467,11 +468,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;
|
||||
@@ -485,10 +481,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++)
|
||||
{
|
||||
@@ -505,7 +498,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);
|
||||
@@ -514,7 +507,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];
|
||||
|
||||
@@ -523,7 +516,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)
|
||||
{
|
||||
|
||||
@@ -1082,7 +1082,7 @@ void LLCurl::initClass()
|
||||
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);
|
||||
|
||||
@@ -960,13 +960,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;
|
||||
@@ -975,7 +971,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));
|
||||
|
||||
@@ -56,7 +56,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
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "llhost.h"
|
||||
#include "llmemtype.h"
|
||||
#include "llpumpio.h"
|
||||
#include "llthread.h"
|
||||
|
||||
//
|
||||
// constants
|
||||
@@ -104,51 +105,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;
|
||||
@@ -158,7 +139,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();
|
||||
@@ -166,8 +147,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();
|
||||
@@ -181,7 +162,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))
|
||||
{
|
||||
@@ -202,21 +183,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->setOptions();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
bool LLSocket::blockingConnect(const LLHost& host)
|
||||
{
|
||||
if(!mSocket) return false;
|
||||
@@ -229,7 +217,7 @@ bool LLSocket::blockingConnect(const LLHost& host)
|
||||
APR_UNSPEC,
|
||||
host.getPort(),
|
||||
0,
|
||||
mPool)))
|
||||
mPool())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -240,13 +228,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()
|
||||
@@ -258,10 +244,6 @@ LLSocket::~LLSocket()
|
||||
ll_debug_socket("Destroying socket", mSocket);
|
||||
apr_socket_close(mSocket);
|
||||
}
|
||||
if(mPool)
|
||||
{
|
||||
apr_pool_destroy(mPool);
|
||||
}
|
||||
}
|
||||
|
||||
void LLSocket::setOptions()
|
||||
@@ -522,10 +504,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),
|
||||
@@ -585,21 +565,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);
|
||||
@@ -614,7 +588,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
|
||||
{
|
||||
chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));
|
||||
pump->addChain(chain, mResponseTimeout);
|
||||
status = STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -623,7 +596,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;
|
||||
@@ -636,11 +610,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;
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
*/
|
||||
|
||||
#include "lliopipe.h"
|
||||
#include "apr_pools.h"
|
||||
#include "apr_network_io.h"
|
||||
#include "llchainio.h"
|
||||
|
||||
@@ -94,34 +93,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.
|
||||
@@ -156,7 +143,7 @@ protected:
|
||||
* @brief Protected constructor since should only make sockets
|
||||
* with one of the two <code>create()</code> calls.
|
||||
*/
|
||||
LLSocket(apr_socket_t* socket, apr_pool_t* pool);
|
||||
LLSocket(void);
|
||||
|
||||
/**
|
||||
* @brief Set default socket options.
|
||||
@@ -173,8 +160,8 @@ protected:
|
||||
// The apr socket.
|
||||
apr_socket_t* mSocket;
|
||||
|
||||
// our memory pool
|
||||
apr_pool_t* mPool;
|
||||
// Our memory pool.
|
||||
AIAPRPool mPool;
|
||||
|
||||
// The port if we know it.
|
||||
U16 mPort;
|
||||
@@ -299,7 +286,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();
|
||||
|
||||
/**
|
||||
@@ -331,7 +318,6 @@ protected:
|
||||
//@}
|
||||
|
||||
protected:
|
||||
apr_pool_t* mPool;
|
||||
socket_t mListenSocket;
|
||||
factory_t mReactor;
|
||||
bool mInitialized;
|
||||
@@ -365,8 +351,7 @@ public:
|
||||
*/
|
||||
LLIODataSocket(
|
||||
U16 suggested_port,
|
||||
U16 start_discovery_port,
|
||||
apr_pool_t* pool);
|
||||
U16 start_discovery_port);
|
||||
virtual ~LLIODataSocket();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "llstring.h"
|
||||
#include "lluuid.h"
|
||||
#include "net.h"
|
||||
#include "aiaprpool.h"
|
||||
|
||||
//
|
||||
// constants
|
||||
@@ -63,7 +64,7 @@
|
||||
const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
|
||||
|
||||
static bool gMailEnabled = true;
|
||||
static apr_pool_t* gMailPool;
|
||||
static AIAPRPool gMailPool;
|
||||
static apr_sockaddr_t* gSockAddr;
|
||||
static apr_socket_t* gMailSocket;
|
||||
|
||||
@@ -88,7 +89,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))
|
||||
@@ -145,19 +146,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.
|
||||
@@ -167,7 +168,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,15 +33,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);
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "llmemtype.h"
|
||||
#include "llstl.h"
|
||||
#include "llstat.h"
|
||||
#include "llthread.h"
|
||||
#include "llfasttimer.h"
|
||||
#include <iterator> //VS2010
|
||||
|
||||
@@ -170,14 +171,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),
|
||||
@@ -186,21 +185,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)
|
||||
@@ -360,8 +362,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);
|
||||
@@ -828,39 +829,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);
|
||||
apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
|
||||
apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
|
||||
#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()
|
||||
@@ -888,21 +865,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();
|
||||
@@ -1160,7 +1135,8 @@ bool LLPumpIO::handleChainError(
|
||||
LLPumpIO::LLChainInfo::LLChainInfo() :
|
||||
mInit(false),
|
||||
mLock(0),
|
||||
mEOS(false)
|
||||
mEOS(false),
|
||||
mDescriptorsPool(new AIAPRPool(LLThread::tldata().mRootPool))
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
|
||||
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
|
||||
|
||||
@@ -36,11 +36,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 "aiaprpool.h"
|
||||
#include "llbuffer.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lliopipe.h"
|
||||
@@ -64,9 +65,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
|
||||
@@ -85,24 +85,13 @@ public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
*/
|
||||
LLPumpIO(apr_pool_t* pool);
|
||||
LLPumpIO(void);
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
~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.
|
||||
*/
|
||||
@@ -374,6 +363,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<AIAPRPool> mDescriptorsPool;
|
||||
};
|
||||
|
||||
// All the running chains & info
|
||||
@@ -392,9 +382,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.
|
||||
AIAPRPool mPool;
|
||||
AIAPRPool mCurrentPool;
|
||||
S32 mCurrentPoolReallocCount;
|
||||
|
||||
#if LL_THREADS_APR
|
||||
@@ -406,8 +396,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
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "llstring.h"
|
||||
#include "apr_env.h"
|
||||
#include "llapr.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
static const U32 HTTP_STATUS_PIPE_ERROR = 499;
|
||||
|
||||
/**
|
||||
@@ -161,27 +162,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;
|
||||
}
|
||||
}
|
||||
|
||||
lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl;
|
||||
|
||||
lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl;
|
||||
|
||||
if (env_proxy && use_proxy)
|
||||
if (use_proxy)
|
||||
{
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
|
||||
}
|
||||
|
||||
@@ -107,8 +107,10 @@ std::string get_shared_secret();
|
||||
class LLMessagePollInfo
|
||||
{
|
||||
public:
|
||||
LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { }
|
||||
apr_socket_t *mAPRSocketp;
|
||||
apr_pollfd_t mPollFD;
|
||||
AIAPRPool mPool;
|
||||
};
|
||||
|
||||
namespace
|
||||
@@ -297,20 +299,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();
|
||||
}
|
||||
apr_socket_t *aprSocketp = NULL;
|
||||
apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp);
|
||||
|
||||
mPollInfop = new LLMessagePollInfo;
|
||||
|
||||
apr_socket_t *aprSocketp = NULL;
|
||||
apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool());
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user