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:
@@ -36,8 +36,7 @@
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llplugininstance.h"
|
||||
|
||||
#include "llapr.h"
|
||||
#include "aiaprpool.h"
|
||||
|
||||
/** Virtual destructor. */
|
||||
LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener()
|
||||
@@ -86,7 +85,7 @@ int LLPluginInstance::load(std::string &plugin_file)
|
||||
|
||||
int result = apr_dso_load(&mDSOHandle,
|
||||
plugin_file.c_str(),
|
||||
gAPRPoolp);
|
||||
AIAPRRootPool::get()());
|
||||
if(result != APR_SUCCESS)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
@@ -99,8 +99,6 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
|
||||
}
|
||||
|
||||
LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
|
||||
mInputMutex(gAPRPoolp),
|
||||
mOutputMutex(gAPRPoolp),
|
||||
mOwner(owner),
|
||||
mSocket(socket)
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ LLPluginProcessChild::LLPluginProcessChild()
|
||||
{
|
||||
mState = STATE_UNINITIALIZED;
|
||||
mInstance = NULL;
|
||||
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
|
||||
mSocket = LLSocket::create(LLSocket::STREAM_TCP);
|
||||
mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz
|
||||
mCPUElapsed = 0.0f;
|
||||
mBlockingRequest = false;
|
||||
|
||||
@@ -49,6 +49,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
|
||||
|
||||
bool LLPluginProcessParent::sUseReadThread = false;
|
||||
apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
|
||||
AIAPRPool LLPluginProcessParent::sPollSetPool;
|
||||
bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
|
||||
LLMutex *LLPluginProcessParent::sInstancesMutex;
|
||||
std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances;
|
||||
@@ -59,7 +60,7 @@ class LLPluginProcessParentPollThread: public LLThread
|
||||
{
|
||||
public:
|
||||
LLPluginProcessParentPollThread() :
|
||||
LLThread("LLPluginProcessParentPollThread", gAPRPoolp)
|
||||
LLThread("LLPluginProcessParentPollThread")
|
||||
{
|
||||
}
|
||||
protected:
|
||||
@@ -84,12 +85,11 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
|
||||
mIncomingQueueMutex(gAPRPoolp)
|
||||
LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
|
||||
{
|
||||
if(!sInstancesMutex)
|
||||
{
|
||||
sInstancesMutex = new LLMutex(gAPRPoolp);
|
||||
sInstancesMutex = new LLMutex;
|
||||
}
|
||||
|
||||
mOwner = owner;
|
||||
@@ -102,6 +102,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
|
||||
mBlocked = false;
|
||||
mPolledInput = false;
|
||||
mPollFD.client_data = NULL;
|
||||
mPollFDPool.create();
|
||||
|
||||
mPluginLaunchTimeout = 60.0f;
|
||||
mPluginLockupTimeout = 15.0f;
|
||||
@@ -177,44 +178,28 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
|
||||
bool LLPluginProcessParent::accept()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
apr_status_t status = APR_EGENERAL;
|
||||
apr_socket_t *new_socket = NULL;
|
||||
|
||||
status = apr_socket_accept(
|
||||
&new_socket,
|
||||
mListenSocket->getSocket(),
|
||||
gAPRPoolp);
|
||||
|
||||
mSocket = LLSocket::create(status, mListenSocket);
|
||||
|
||||
if(status == APR_SUCCESS)
|
||||
{
|
||||
// llinfos << "SUCCESS" << llendl;
|
||||
// Success. Create a message pipe on the new socket
|
||||
|
||||
// we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor!
|
||||
apr_pool_t* new_pool = NULL;
|
||||
status = apr_pool_create(&new_pool, gAPRPoolp);
|
||||
|
||||
mSocket = LLSocket::create(new_socket, new_pool);
|
||||
new LLPluginMessagePipe(this, mSocket);
|
||||
|
||||
result = true;
|
||||
}
|
||||
else if(APR_STATUS_IS_EAGAIN(status))
|
||||
{
|
||||
// llinfos << "EAGAIN" << llendl;
|
||||
|
||||
// No incoming connections. This is not an error.
|
||||
status = APR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// llinfos << "Error:" << llendl;
|
||||
ll_apr_warn_status(status);
|
||||
|
||||
// Some other error.
|
||||
errorState();
|
||||
mSocket.reset();
|
||||
// EAGAIN means "No incoming connections". This is not an error.
|
||||
if (!APR_STATUS_IS_EAGAIN(status))
|
||||
{
|
||||
// Some other error.
|
||||
ll_apr_warn_status(status);
|
||||
errorState();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -283,7 +268,7 @@ void LLPluginProcessParent::idle(void)
|
||||
|
||||
apr_status_t status = APR_SUCCESS;
|
||||
apr_sockaddr_t* addr = NULL;
|
||||
mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
|
||||
mListenSocket = LLSocket::create(LLSocket::STREAM_TCP);
|
||||
mBoundPort = 0;
|
||||
|
||||
// This code is based on parts of LLSocket::create() in lliosocket.cpp.
|
||||
@@ -294,7 +279,7 @@ void LLPluginProcessParent::idle(void)
|
||||
APR_INET,
|
||||
0, // port 0 = ephemeral ("find me a port")
|
||||
0,
|
||||
gAPRPoolp);
|
||||
AIAPRRootPool::get()());
|
||||
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
@@ -617,7 +602,8 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe)
|
||||
if(message_pipe != NULL)
|
||||
{
|
||||
// Set up the apr_pollfd_t
|
||||
mPollFD.p = gAPRPoolp;
|
||||
|
||||
mPollFD.p = mPollFDPool();
|
||||
mPollFD.desc_type = APR_POLL_SOCKET;
|
||||
mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP;
|
||||
mPollFD.rtnevents = 0;
|
||||
@@ -664,6 +650,7 @@ void LLPluginProcessParent::updatePollset()
|
||||
// delete the existing pollset.
|
||||
apr_pollset_destroy(sPollSet);
|
||||
sPollSet = NULL;
|
||||
sPollSetPool.destroy();
|
||||
}
|
||||
|
||||
std::list<LLPluginProcessParent*>::iterator iter;
|
||||
@@ -686,12 +673,14 @@ void LLPluginProcessParent::updatePollset()
|
||||
{
|
||||
#ifdef APR_POLLSET_NOCOPY
|
||||
// The pollset doesn't exist yet. Create it now.
|
||||
apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY);
|
||||
sPollSetPool.create();
|
||||
apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY);
|
||||
if(status != APR_SUCCESS)
|
||||
{
|
||||
#endif // APR_POLLSET_NOCOPY
|
||||
LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL;
|
||||
sPollSet = NULL;
|
||||
sPollSetPool.destroy();
|
||||
#ifdef APR_POLLSET_NOCOPY
|
||||
}
|
||||
else
|
||||
|
||||
@@ -186,7 +186,9 @@ private:
|
||||
|
||||
static bool sUseReadThread;
|
||||
apr_pollfd_t mPollFD;
|
||||
AIAPRPool mPollFDPool;
|
||||
static apr_pollset_t *sPollSet;
|
||||
static AIAPRPool sPollSetPool;
|
||||
static bool sPollsetNeedsRebuild;
|
||||
static LLMutex *sInstancesMutex;
|
||||
static std::list<LLPluginProcessParent*> sInstances;
|
||||
|
||||
@@ -201,7 +201,8 @@ bool LLPluginSharedMemory::create(size_t size)
|
||||
mName += createName();
|
||||
mSize = size;
|
||||
|
||||
apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp );
|
||||
mPool.create();
|
||||
apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool());
|
||||
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
@@ -224,7 +225,7 @@ bool LLPluginSharedMemory::destroy(void)
|
||||
}
|
||||
mImpl->mAprSharedMemory = NULL;
|
||||
}
|
||||
|
||||
mPool.destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -233,7 +234,8 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
|
||||
mName = name;
|
||||
mSize = size;
|
||||
|
||||
apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp );
|
||||
mPool.create();
|
||||
apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() );
|
||||
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
@@ -255,6 +257,7 @@ bool LLPluginSharedMemory::detach(void)
|
||||
}
|
||||
mImpl->mAprSharedMemory = NULL;
|
||||
}
|
||||
mPool.destroy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#ifndef LL_LLPLUGINSHAREDMEMORY_H
|
||||
#define LL_LLPLUGINSHAREDMEMORY_H
|
||||
|
||||
#include "aiaprpool.h"
|
||||
|
||||
class LLPluginSharedMemoryPlatformImpl;
|
||||
|
||||
/**
|
||||
@@ -115,6 +117,7 @@ private:
|
||||
bool close(void);
|
||||
bool unlink(void);
|
||||
|
||||
AIAPRPool mPool;
|
||||
std::string mName;
|
||||
size_t mSize;
|
||||
void *mMappedAddress;
|
||||
|
||||
@@ -183,8 +183,6 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
|
||||
int main(int argc, char **argv)
|
||||
#endif
|
||||
{
|
||||
ll_init_apr();
|
||||
|
||||
// Set up llerror logging
|
||||
{
|
||||
LLError::initForApplication(".");
|
||||
@@ -400,8 +398,6 @@ int main(int argc, char **argv)
|
||||
|
||||
delete plugin;
|
||||
|
||||
ll_cleanup_apr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user