AIAPRPool, AIAPRRootPool, AIVolatileAPRPool, AIThreadLocalData etc, were rebranded by LL. Merging change to clean up diffs.

This commit is contained in:
Shyotl
2011-09-20 22:08:48 -05:00
parent d917bf6b06
commit 244e30297f
25 changed files with 486 additions and 175 deletions

View File

@@ -15,11 +15,11 @@ include_directories(
)
set(llcommon_SOURCE_FILES
aiaprpool.cpp
imageids.cpp
indra_constants.cpp
llapp.cpp
llapr.cpp
llaprpool.cpp
llassettype.cpp
llavatarname.cpp
llbase32.cpp
@@ -60,6 +60,7 @@ set(llcommon_SOURCE_FILES
llrand.cpp
llrefcount.cpp
llrun.cpp
llscopedvolatileaprpool.h
llsd.cpp
llsdserialize.cpp
llsdserialize_xml.cpp
@@ -73,6 +74,7 @@ set(llcommon_SOURCE_FILES
llstringtable.cpp
llsys.cpp
llthread.cpp
llthreadsafequeue.cpp
lltimer.cpp
lluri.cpp
lluuid.cpp
@@ -87,7 +89,6 @@ set(llcommon_SOURCE_FILES
set(llcommon_HEADER_FILES
CMakeLists.txt
aiaprpool.h
aithreadsafe.h
bitpack.h
ctype_workaround.h
@@ -101,6 +102,7 @@ set(llcommon_HEADER_FILES
llavatarname.h
llapp.h
llapr.h
llaprpool.h
llassettype.h
llassoclist.h
llavatarconstants.h
@@ -171,10 +173,10 @@ set(llcommon_HEADER_FILES
llptrskipmap.h
llqueuedthread.h
llrand.h
llrefcount.h
llrun.h
llrefcount.h
llsafehandle.h
llscopedvolatileaprpool.h
llsd.h
llsdserialize.h
llsdserialize_xml.h
@@ -195,6 +197,7 @@ set(llcommon_HEADER_FILES
llstringtable.h
llsys.h
llthread.h
llthreadsafequeue.h
lltimer.h
lltreeiterators.h
lluri.h

View File

@@ -175,7 +175,7 @@ protected:
// For use by AIThreadSafeDC
AIThreadSafe(void) { }
AIThreadSafe(AIAPRPool& parent) : mRWLock(parent) { }
AIThreadSafe(LLAPRPool& parent) : mRWLock(parent) { }
public:
// Only for use by AITHREADSAFE, see below.
@@ -406,7 +406,7 @@ protected:
friend struct AIRegisteredStateMachinesList;
// For use by AIThreadSafeSimpleDC and AIRegisteredStateMachinesList.
AIThreadSafeSimple(void) { }
AIThreadSafeSimple(AIAPRPool& parent) : mMutex(parent) { }
AIThreadSafeSimple(LLAPRPool& parent) : mMutex(parent) { }
public:
// Only for use by AITHREADSAFESIMPLE, see below.
@@ -471,7 +471,7 @@ public:
protected:
// For use by AIThreadSafeSimpleDCRootPool
AIThreadSafeSimpleDC(AIAPRPool& parent) : AIThreadSafeSimple<T>(parent) { new (AIThreadSafeSimple<T>::ptr()) T; }
AIThreadSafeSimpleDC(LLAPRPool& parent) : AIThreadSafeSimple<T>(parent) { new (AIThreadSafeSimple<T>::ptr()) T; }
};
// Helper class for AIThreadSafeSimpleDCRootPool to assure initialization of
@@ -479,7 +479,7 @@ protected:
class AIThreadSafeSimpleDCRootPool_pbase
{
protected:
AIAPRRootPool mRootPool;
LLAPRRootPool mRootPool;
private:
template<typename T> friend class AIThreadSafeSimpleDCRootPool;
@@ -489,7 +489,7 @@ private:
/**
* @brief A wrapper class for objects that need to be accessed by more than one thread.
*
* The same as AIThreadSafeSimpleDC except that this class creates its own AIAPRRootPool
* The same as AIThreadSafeSimpleDC except that this class creates its own LLAPRRootPool
* for the internally used mutexes and condition, instead of using the current threads
* root pool. The advantage of this is that it can be used for objects that need to
* be accessed from the destructors of global objects (after main). The disadvantage

View File

@@ -151,15 +151,15 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc
if (access_type == short_lived)
{
// Use a "volatile" thread-local pool.
mVolatileFilePoolp = &AIThreadLocalData::tldata().mVolatileAPRPool;
mVolatileFilePoolp = &LLThreadLocalData::tldata().mVolatileAPRPool;
// Access the pool and increment it's reference count.
// The reference count of AIVolatileAPRPool objects will be decremented
// The reference count of LLVolatileAPRPool objects will be decremented
// again in LLAPRFile::close by calling mVolatileFilePoolp->clearVolatileAPRPool().
apr_file_open_pool = mVolatileFilePoolp->getVolatileAPRPool();
}
else
{
mRegularFilePoolp = new AIAPRPool(AIThreadLocalData::tldata().mRootPool);
mRegularFilePoolp = new LLAPRPool(LLThreadLocalData::tldata().mRootPool);
apr_file_open_pool = (*mRegularFilePoolp)();
}
status = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, apr_file_open_pool);

View File

@@ -48,8 +48,8 @@
#include "apr_atomic.h"
#include "llstring.h"
class AIAPRPool;
class AIVolatileAPRPool;
class LLAPRPool;
class LLVolatileAPRPool;
/**
* @class LLScopedLock
@@ -140,8 +140,8 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
// make this non copyable since a copy closes the file
private:
apr_file_t* mFile ;
AIVolatileAPRPool* mVolatileFilePoolp; // (Thread local) APR pool currently in use.
AIAPRPool* mRegularFilePoolp; // ...or a regular pool.
LLVolatileAPRPool* mVolatileFilePoolp; // (Thread local) APR pool currently in use.
LLAPRPool* mRegularFilePoolp; // ...or a regular pool.
public:
enum access_t {

View File

@@ -1,5 +1,5 @@
/**
* @file aiaprpool.cpp
* @file LLAPRPool.cpp
*
* Copyright (c) 2010, Aleric Inglewood.
*
@@ -36,18 +36,18 @@
#include "linden_common.h"
#include "llerror.h"
#include "aiaprpool.h"
#include "llaprpool.h"
#include "llthread.h"
// Create a subpool from parent.
void AIAPRPool::create(AIAPRPool& parent)
void LLAPRPool::create(LLAPRPool& parent)
{
llassert(!mPool); // Must be non-initialized.
mParent = &parent;
if (!mParent) // Using the default parameter?
{
// By default use the root pool of the current thread.
mParent = &AIThreadLocalData::tldata().mRootPool;
mParent = &LLThreadLocalData::tldata().mRootPool;
}
llassert(mParent->mPool); // Parent must be initialized.
#if APR_HAS_THREADS
@@ -72,7 +72,7 @@ void AIAPRPool::create(AIAPRPool& parent)
}
// Destroy the (sub)pool, if any.
void AIAPRPool::destroy(void)
void LLAPRPool::destroy(void)
{
// Only do anything if we are not already (being) destroyed.
if (mPool)
@@ -92,12 +92,12 @@ void AIAPRPool::destroy(void)
}
}
bool AIAPRPool::parent_is_being_destructed(void)
bool LLAPRPool::parent_is_being_destructed(void)
{
return mParent && (!mParent->mPool || mParent->parent_is_being_destructed());
}
AIAPRInitialization::AIAPRInitialization(void)
LLAPRInitialization::LLAPRInitialization(void)
{
static bool apr_initialized = false;
@@ -109,13 +109,13 @@ AIAPRInitialization::AIAPRInitialization(void)
apr_initialized = true;
}
bool AIAPRRootPool::sCountInitialized = false;
apr_uint32_t volatile AIAPRRootPool::sCount;
bool LLAPRRootPool::sCountInitialized = false;
apr_uint32_t volatile LLAPRRootPool::sCount;
extern apr_thread_mutex_t* gLogMutexp;
extern apr_thread_mutex_t* gCallStacksLogMutexp;
apr_thread_mutex_t* gLogMutexp;
apr_thread_mutex_t* gCallStacksLogMutexp;
AIAPRRootPool::AIAPRRootPool(void) : AIAPRInitialization(), AIAPRPool(0)
LLAPRRootPool::LLAPRRootPool(void) : LLAPRInitialization(), LLAPRPool(0)
{
// sCountInitialized don't need locking because when we get here there is still only a single thread.
if (!sCountInitialized)
@@ -130,14 +130,14 @@ AIAPRRootPool::AIAPRRootPool(void) : AIAPRInitialization(), AIAPRPool(0)
sCountInitialized = true;
// Initialize thread-local APR pool support.
// Because this recursively calls AIAPRRootPool::AIAPRRootPool(void)
// Because this recursively calls LLAPRRootPool::LLAPRRootPool(void)
// it must be done last, so that sCount is already initialized.
AIThreadLocalData::init();
LLThreadLocalData::init();
}
apr_atomic_inc32(&sCount);
}
AIAPRRootPool::~AIAPRRootPool()
LLAPRRootPool::~LLAPRRootPool()
{
if (!apr_atomic_dec32(&sCount))
{
@@ -161,21 +161,21 @@ AIAPRRootPool::~AIAPRRootPool()
gCallStacksLogMutexp = NULL;
}
// Must destroy ALL, and therefore this last AIAPRRootPool, before terminating APR.
static_cast<AIAPRRootPool*>(this)->destroy();
// Must destroy ALL, and therefore this last LLAPRRootPool, before terminating APR.
static_cast<LLAPRRootPool*>(this)->destroy();
apr_terminate();
}
}
//static
AIAPRRootPool& AIAPRRootPool::get(void)
LLAPRRootPool& LLAPRRootPool::get(void)
{
static AIAPRRootPool global_APRpool(0); // This is what used to be gAPRPoolp.
static LLAPRRootPool global_APRpool(0); // This is what used to be gAPRPoolp.
return global_APRpool;
}
void AIVolatileAPRPool::clearVolatileAPRPool()
void LLVolatileAPRPool::clearVolatileAPRPool()
{
llassert_always(mNumActiveRef > 0);
if (--mNumActiveRef == 0)

View File

@@ -1,6 +1,6 @@
/**
* @file aiaprpool.h
* @brief Implementation of AIAPRPool.
* @file LLAPRPool.h
* @brief Implementation of LLAPRPool.
*
* Copyright (c) 2010, Aleric Inglewood.
*
@@ -34,11 +34,15 @@
* of subpools by threads other than the parent pool owner.
*/
#ifndef AIAPRPOOL_H
#define AIAPRPOOL_H
#ifndef LL_LLAPRPOOL_H
#define LL_LLAPRPOOL_H
#ifdef LL_WINDOWS
#pragma warning(push)
#pragma warning(disable:4996)
#include <winsock2.h>
#include <ws2tcpip.h> // Needed before including apr_portable.h
#pragma warning(pop)
#endif
#include "apr_portable.h"
@@ -53,27 +57,27 @@ extern void ll_init_apr();
* Usage of this class should be restricted to passing it to libapr-1 function calls that need it.
*
*/
class LL_COMMON_API AIAPRPool
class LL_COMMON_API LLAPRPool
{
protected:
apr_pool_t* mPool; //!< Pointer to the underlaying pool. NULL if not initialized.
AIAPRPool* mParent; //!< Pointer to the parent pool, if any. Only valid when mPool is non-zero.
LLAPRPool* mParent; //!< Pointer to the parent pool, if any. Only valid when mPool is non-zero.
apr_os_thread_t mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero.
public:
//! Construct an uninitialized (destructed) pool.
AIAPRPool(void) : mPool(NULL) { }
LLAPRPool(void) : mPool(NULL) { }
//! Construct a subpool from an existing pool.
// This is not a copy-constructor, this class doesn't have one!
AIAPRPool(AIAPRPool& parent) : mPool(NULL) { create(parent); }
LLAPRPool(LLAPRPool& parent) : mPool(NULL) { create(parent); }
//! Destruct the memory pool (free all of it's subpools and allocated memory).
~AIAPRPool() { destroy(); }
~LLAPRPool() { destroy(); }
protected:
// Create a pool that is allocated from the Operating System. Only used by AIAPRRootPool.
AIAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current())
// Create a pool that is allocated from the Operating System. Only used by LLAPRRootPool.
LLAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current())
{
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL);
llassert_always(apr_pool_create_status == APR_SUCCESS);
@@ -84,15 +88,15 @@ protected:
public:
//! Create a subpool from parent. May only be called for an uninitialized/destroyed pool.
// The default parameter causes the root pool of the current thread to be used.
void create(AIAPRPool& parent = *static_cast<AIAPRPool*>(NULL));
void create(LLAPRPool& parent = *static_cast<LLAPRPool*>(NULL));
//! Destroy the (sub)pool, if any.
void destroy(void);
// Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool.
typedef apr_pool_t* const AIAPRPool::* const bool_type;
//! Return true if the pool is initialized.
operator bool_type() const { return mPool ? &AIAPRPool::mPool : 0; }
typedef LLAPRPool* const LLAPRPool::* const bool_type;
/// Return true if the pool is initialized.
operator bool_type() const { return mPool ? &LLAPRPool::mParent : 0; }
// Painful, but we have to either provide access to this, or wrap
// every APR function call that needs a apr_pool_t* to be passed.
@@ -133,7 +137,7 @@ public:
private:
bool parent_is_being_destructed(void);
static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<AIAPRPool*>(userdata)->plain_cleanup(); }
static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<LLAPRPool*>(userdata)->plain_cleanup(); }
apr_status_t plain_cleanup(void)
{
@@ -148,30 +152,30 @@ private:
}
};
class AIAPRInitialization
class LLAPRInitialization
{
public:
AIAPRInitialization(void);
LLAPRInitialization(void);
};
/**
* @brief Root memory pool (allocates memory from the operating system).
*
* This class should only be used by AIThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase
* This class should only be used by LLThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase
* (and LLMutexRootPool when APR_HAS_THREADS isn't defined).
*/
class LL_COMMON_API AIAPRRootPool : public AIAPRInitialization, public AIAPRPool
class LL_COMMON_API LLAPRRootPool : public LLAPRInitialization, public LLAPRPool
{
private:
friend class AIThreadLocalData;
friend class LLThreadLocalData;
friend class AIThreadSafeSimpleDCRootPool_pbase;
#if !APR_HAS_THREADS
friend class LLMutexRootPool;
#endif
//! Construct a root memory pool.
// Should only be used by AIThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase.
AIAPRRootPool(void);
~AIAPRRootPool();
// Should only be used by LLThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase.
LLAPRRootPool(void);
~LLAPRRootPool();
private:
// Keep track of how many root pools exist and when the last one is destructed.
@@ -179,10 +183,10 @@ private:
static apr_uint32_t volatile sCount;
public:
// Return a global root pool that is independent of AIThreadLocalData.
// Return a global root pool that is independent of LLThreadLocalData.
// Normally you should not use this. Only use for early initialization
// (before main) and deinitialization (after main).
static AIAPRRootPool& get(void);
static LLAPRRootPool& get(void);
#if APR_POOL_DEBUG
void grab_ownership(void)
@@ -194,11 +198,11 @@ public:
#endif
private:
// Used for constructing the Special Global Root Pool (returned by AIAPRRootPool::get).
// Used for constructing the Special Global Root Pool (returned by LLAPRRootPool::get).
// It is the same as the default constructor but omits to increment sCount. As a result,
// we must be sure that at least one other AIAPRRootPool is created before termination
// of the application (which is the case: we create one AIAPRRootPool per thread).
AIAPRRootPool(int) : AIAPRInitialization(), AIAPRPool(0) { }
// we must be sure that at least one other LLAPRRootPool is created before termination
// of the application (which is the case: we create one LLAPRRootPool per thread).
LLAPRRootPool(int) : LLAPRInitialization(), LLAPRPool(0) { }
};
//! Volatile memory pool
@@ -210,29 +214,33 @@ private:
// the system memory to be allocated more efficiently and not
// get scattered through RAM.
//
class LL_COMMON_API AIVolatileAPRPool : protected AIAPRPool
class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool
{
public:
AIVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { }
LLVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { }
apr_pool_t* getVolatileAPRPool(void)
{
if (!mPool) create();
++mNumActiveRef;
++mNumTotalRef;
return AIAPRPool::operator()();
}
void clearVolatileAPRPool(void);
bool isOld(void) const { return mNumTotalRef > FULL_VOLATILE_APR_POOL; }
bool isUnused() const { return mNumActiveRef == 0; }
private:
friend class LLScopedVolatileAPRPool;
friend class LLAPRFile;
apr_pool_t* getVolatileAPRPool(void) // The use of apr_pool_t is OK here.
{
if (!mPool) create();
++mNumActiveRef;
++mNumTotalRef;
return LLAPRPool::operator()();
}
private:
S32 mNumActiveRef; // Number of active uses of the pool.
S32 mNumTotalRef; // Number of total uses of the pool since last creation.
// Maximum number of references to AIVolatileAPRPool until the pool is recreated.
// Maximum number of references to LLVolatileAPRPool until the pool is recreated.
static S32 const FULL_VOLATILE_APR_POOL = 1024;
};
#endif // AIAPRPOOL_H
#endif // LLAPRPool_H

View File

@@ -56,9 +56,8 @@
#include "llsdserialize.h"
#include "llstl.h"
#include "lltimer.h"
#include "aithreadsafe.h"
extern apr_thread_mutex_t* gCallStacksLogMutexp;
#include "aithreadsafe.h"
namespace {
#if !LL_WINDOWS
@@ -881,8 +880,8 @@ You get:
*/
apr_thread_mutex_t* gLogMutexp;
apr_thread_mutex_t* gCallStacksLogMutexp;
extern apr_thread_mutex_t* gLogMutexp;
extern apr_thread_mutex_t* gCallStacksLogMutexp;
namespace {
bool checkLevelMap(const LevelMap& map, const std::string& key,

View File

@@ -36,7 +36,7 @@
#include <apr_file_io.h>
#include <apr_thread_proc.h>
#include "llprocesslauncher.h"
#include "aiaprpool.h"
#include "llaprpool.h"
#include <iostream>
#if LL_DARWIN || LL_LINUX
@@ -346,7 +346,7 @@ int LLProcessLauncher::launch(void)
// Set up a pipe to the child process for error reporting.
apr_file_t* in;
apr_file_t* out;
AIAPRPool pool;
LLAPRPool pool;
pool.create();
#if(APR_VERSION_MAJOR==1 && APR_VERSION_MINOR>=3 || APR_VERSION_MAJOR>1)
apr_status_t status = apr_file_pipe_create_ex(&in, &out, APR_FULL_BLOCK, pool());

View File

@@ -35,21 +35,21 @@
#include "llthread.h"
//! Scoped volatile memory pool.
//
// As the AIVolatileAPRPool should never keep allocations very
// long, it's most common use is for allocations with a lifetime
// equal to it's scope.
//
// This is a convenience class that makes just a little easier to type.
//
class LLScopedVolatileAPRPool
/** Scoped volatile memory pool.
*
* As the LLVolatileAPRPool should never keep allocations very
* long, its most common use is for allocations with a lifetime
* equal to it's scope.
*
* This is a convenience class that makes just a little easier to type.
*/
class LL_COMMON_API LLScopedVolatileAPRPool
{
private:
AIVolatileAPRPool& mPool;
LLVolatileAPRPool& mPool;
apr_pool_t* mScopedAPRpool;
public:
LLScopedVolatileAPRPool() : mPool(AIThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { }
LLScopedVolatileAPRPool() : mPool(LLThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { }
~LLScopedVolatileAPRPool() { mPool.clearVolatileAPRPool(); }
// Only use this to pass the pointer to a libapr-1 function that requires it.
operator apr_pool_t*() const { return mScopedAPRpool; }

View File

@@ -92,9 +92,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
sThreadID = threadp->mID;
#endif
// Create a thread local data.
AIThreadLocalData::create(threadp);
LLThreadLocalData::create(threadp);
// Run the user supplied function
threadp->run();
@@ -305,11 +304,11 @@ static apr_os_thread_t main_thread_id;
LL_COMMON_API bool is_main_thread() { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); }
#endif
// The thread private handle to access the AIThreadLocalData instance.
apr_threadkey_t* AIThreadLocalData::sThreadLocalDataKey;
// The thread private handle to access the LLThreadLocalData instance.
apr_threadkey_t* LLThreadLocalData::sThreadLocalDataKey;
//static
void AIThreadLocalData::init(void)
void LLThreadLocalData::init(void)
{
// Only do this once.
if (sThreadLocalDataKey)
@@ -317,13 +316,13 @@ void AIThreadLocalData::init(void)
return;
}
apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &AIThreadLocalData::destroy, AIAPRRootPool::get()());
apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &LLThreadLocalData::destroy, LLAPRRootPool::get()());
ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the
// total number of keys per process {PTHREAD_KEYS_MAX}
// total number of keys per process {PTHREAD_KEYS_MAX}
// has been exceeded.
// Create the thread-local data for the main thread (this function is called by the main thread).
AIThreadLocalData::create(NULL);
LLThreadLocalData::create(NULL);
#ifdef SHOW_ASSERT
// This function is called by the main thread.
@@ -333,15 +332,15 @@ void AIThreadLocalData::init(void)
// This is called once for every thread when the thread is destructed.
//static
void AIThreadLocalData::destroy(void* thread_local_data)
void LLThreadLocalData::destroy(void* thread_local_data)
{
delete reinterpret_cast<AIThreadLocalData*>(thread_local_data);
delete static_cast<LLThreadLocalData*>(thread_local_data);
}
//static
void AIThreadLocalData::create(LLThread* threadp)
void LLThreadLocalData::create(LLThread* threadp)
{
AIThreadLocalData* new_tld = new AIThreadLocalData;
LLThreadLocalData* new_tld = new LLThreadLocalData;
if (threadp)
{
threadp->mThreadLocalData = new_tld;
@@ -351,19 +350,49 @@ void AIThreadLocalData::create(LLThread* threadp)
}
//static
AIThreadLocalData& AIThreadLocalData::tldata(void)
LLThreadLocalData& LLThreadLocalData::tldata(void)
{
if (!sThreadLocalDataKey)
AIThreadLocalData::init();
{
LLThreadLocalData::init();
}
void* data;
apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey);
llassert_always(status == APR_SUCCESS);
return *static_cast<AIThreadLocalData*>(data);
return *static_cast<LLThreadLocalData*>(data);
}
//============================================================================
LLCondition::LLCondition(LLAPRPool& parent) : LLMutex(parent)
{
apr_thread_cond_create(&mAPRCondp, mPool());
}
LLCondition::~LLCondition()
{
apr_thread_cond_destroy(mAPRCondp);
mAPRCondp = NULL;
}
void LLCondition::wait()
{
apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
}
void LLCondition::signal()
{
apr_thread_cond_signal(mAPRCondp);
}
void LLCondition::broadcast()
{
apr_thread_cond_broadcast(mAPRCondp);
}
//============================================================================
void LLMutexBase::lock()
{
#if LL_DARWIN
@@ -429,36 +458,6 @@ U32 LLMutexBase::lockingThread() const
}
//============================================================================
LLCondition::LLCondition(AIAPRPool& parent) : LLMutex(parent)
{
apr_thread_cond_create(&mAPRCondp, mPool());
}
LLCondition::~LLCondition()
{
apr_thread_cond_destroy(mAPRCondp);
mAPRCondp = NULL;
}
void LLCondition::wait()
{
apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
}
void LLCondition::signal()
{
apr_thread_cond_signal(mAPRCondp);
}
void LLCondition::broadcast()
{
apr_thread_cond_broadcast(mAPRCondp);
}
//============================================================================
//----------------------------------------------------------------------------
//static

View File

@@ -33,12 +33,11 @@
#ifndef LL_LLTHREAD_H
#define LL_LLTHREAD_H
#include "llapr.h"
#include "llapp.h"
#include "llapr.h"
#include "llmemory.h"
#include "apr_thread_cond.h"
#include "aiaprpool.h"
#include "llaprpool.h"
#ifdef SHOW_ASSERT
extern LL_COMMON_API bool is_main_thread(void);
@@ -54,20 +53,20 @@ class LLCondition;
#define ll_thread_local __thread
#endif
class LL_COMMON_API AIThreadLocalData
class LL_COMMON_API LLThreadLocalData
{
private:
static apr_threadkey_t* sThreadLocalDataKey;
public:
// Thread-local memory pool.
AIAPRRootPool mRootPool;
AIVolatileAPRPool mVolatileAPRPool;
LLAPRRootPool mRootPool;
LLVolatileAPRPool mVolatileAPRPool;
static void init(void);
static void destroy(void* thread_local_data);
static void create(LLThread* pthread);
static AIThreadLocalData& tldata(void);
static LLThreadLocalData& tldata(void);
};
class LL_COMMON_API LLThread
@@ -113,7 +112,7 @@ public:
void start(void);
// Return thread-local data for the current thread.
static AIThreadLocalData& tldata(void) { return AIThreadLocalData::tldata(); }
static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); }
U32 getID() const { return mID; }
@@ -131,8 +130,8 @@ protected:
volatile EThreadStatus mStatus;
U32 mID;
friend void AIThreadLocalData::create(LLThread* threadp);
AIThreadLocalData* mThreadLocalData;
friend void LLThreadLocalData::create(LLThread* threadp);
LLThreadLocalData* mThreadLocalData;
void setQuitting();
@@ -188,7 +187,7 @@ protected:
class LL_COMMON_API LLMutex : public LLMutexBase
{
public:
LLMutex(AIAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent)
LLMutex(LLAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent)
{
apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mPool());
}
@@ -200,7 +199,7 @@ public:
}
protected:
AIAPRPool mPool;
LLAPRPool mPool;
private:
// Disable copy construction, as si teh bomb!!! -SG
LLMutex(const LLMutex&);
@@ -230,7 +229,7 @@ public:
}
protected:
AIAPRRootPool mRootPool;
LLAPRRootPool mRootPool;
};
#endif // APR_HAS_THREADS
@@ -238,7 +237,7 @@ protected:
class LL_COMMON_API LLCondition : public LLMutex
{
public:
LLCondition(AIAPRPool& parent = LLThread::tldata().mRootPool);
LLCondition(LLAPRPool& parent = LLThread::tldata().mRootPool);
~LLCondition();
void wait(); // blocks
@@ -268,7 +267,7 @@ private:
class AIRWLock
{
public:
AIRWLock(AIAPRPool& parent = LLThread::tldata().mRootPool) :
AIRWLock(LLAPRPool& parent = LLThread::tldata().mRootPool) :
mWriterWaitingMutex(parent), mNoHoldersCondition(parent), mHoldersCount(0), mWriterIsWaiting(false) { }
private:

View File

@@ -0,0 +1,100 @@
/**
* @file llthread.cpp
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include <apr_pools.h>
#include <apr_queue.h>
#include "llthreadsafequeue.h"
// LLThreadSafeQueueImplementation
//-----------------------------------------------------------------------------
LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(unsigned int capacity):
mQueue(0)
{
mPool.create();
apr_status_t status = apr_queue_create(&mQueue, capacity, mPool());
if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue");
}
LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
{
if(mQueue != 0) {
if(apr_queue_size(mQueue) != 0) llwarns <<
"terminating queue which still contains " << apr_queue_size(mQueue) <<
" elements;" << "memory will be leaked" << LL_ENDL;
apr_queue_term(mQueue);
}
}
void LLThreadSafeQueueImplementation::pushFront(void * element)
{
apr_status_t status = apr_queue_push(mQueue, element);
if(status == APR_EINTR) {
throw LLThreadSafeQueueInterrupt();
} else if(status != APR_SUCCESS) {
throw LLThreadSafeQueueError("push failed");
} else {
; // Success.
}
}
bool LLThreadSafeQueueImplementation::tryPushFront(void * element){
return apr_queue_trypush(mQueue, element) == APR_SUCCESS;
}
void * LLThreadSafeQueueImplementation::popBack(void)
{
void * element;
apr_status_t status = apr_queue_pop(mQueue, &element);
if(status == APR_EINTR) {
throw LLThreadSafeQueueInterrupt();
} else if(status != APR_SUCCESS) {
throw LLThreadSafeQueueError("pop failed");
} else {
return element;
}
}
bool LLThreadSafeQueueImplementation::tryPopBack(void *& element)
{
return apr_queue_trypop(mQueue, &element) == APR_SUCCESS;
}
size_t LLThreadSafeQueueImplementation::size()
{
return apr_queue_size(mQueue);
}

View File

@@ -0,0 +1,203 @@
/**
* @file llthreadsafequeue.h
* @brief Base classes for thread, mutex and condition handling.
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLTHREADSAFEQUEUE_H
#define LL_LLTHREADSAFEQUEUE_H
#include <string>
#include <stdexcept>
#include "llaprpool.h"
class LLThreadSafeQueueImplementation; // See below.
//
// A general queue exception.
//
class LL_COMMON_API LLThreadSafeQueueError:
public std::runtime_error
{
public:
LLThreadSafeQueueError(std::string const & message):
std::runtime_error(message)
{
; // No op.
}
};
//
// An exception raised when blocking operations are interrupted.
//
class LL_COMMON_API LLThreadSafeQueueInterrupt:
public LLThreadSafeQueueError
{
public:
LLThreadSafeQueueInterrupt(void):
LLThreadSafeQueueError("queue operation interrupted")
{
; // No op.
}
};
struct apr_queue_t; // From apr_queue.h
//
// Implementation details.
//
class LL_COMMON_API LLThreadSafeQueueImplementation
{
public:
LLThreadSafeQueueImplementation(unsigned int capacity);
~LLThreadSafeQueueImplementation();
void pushFront(void * element);
bool tryPushFront(void * element);
void * popBack(void);
bool tryPopBack(void *& element);
size_t size();
private:
LLAPRPool mPool; // The pool used for mQueue.
apr_queue_t * mQueue;
};
//
// Implements a thread safe FIFO.
//
template<typename ElementT>
class LLThreadSafeQueue
{
public:
typedef ElementT value_type;
// Constructor.
LLThreadSafeQueue(unsigned int capacity = 1024);
// Add an element to the front of queue (will block if the queue has
// reached capacity).
//
// This call will raise an interrupt error if the queue is deleted while
// the caller is blocked.
void pushFront(ElementT const & element);
// Try to add an element to the front ofqueue without blocking. Returns
// true only if the element was actually added.
bool tryPushFront(ElementT const & element);
// Pop the element at the end of the queue (will block if the queue is
// empty).
//
// This call will raise an interrupt error if the queue is deleted while
// the caller is blocked.
ElementT popBack(void);
// Pop an element from the end of the queue if there is one available.
// Returns true only if an element was popped.
bool tryPopBack(ElementT & element);
// Returns the size of the queue.
size_t size();
private:
LLThreadSafeQueueImplementation mImplementation;
};
// LLThreadSafeQueue
//-----------------------------------------------------------------------------
template<typename ElementT>
LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(unsigned int capacity) :
mImplementation(capacity)
{
; // No op.
}
template<typename ElementT>
void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element)
{
ElementT * elementCopy = new ElementT(element);
try {
mImplementation.pushFront(elementCopy);
} catch (LLThreadSafeQueueInterrupt) {
delete elementCopy;
throw;
}
}
template<typename ElementT>
bool LLThreadSafeQueue<ElementT>::tryPushFront(ElementT const & element)
{
ElementT * elementCopy = new ElementT(element);
bool result = mImplementation.tryPushFront(elementCopy);
if(!result) delete elementCopy;
return result;
}
template<typename ElementT>
ElementT LLThreadSafeQueue<ElementT>::popBack(void)
{
ElementT * element = reinterpret_cast<ElementT *> (mImplementation.popBack());
ElementT result(*element);
delete element;
return result;
}
template<typename ElementT>
bool LLThreadSafeQueue<ElementT>::tryPopBack(ElementT & element)
{
void * storedElement;
bool result = mImplementation.tryPopBack(storedElement);
if(result) {
ElementT * elementPtr = reinterpret_cast<ElementT *>(storedElement);
element = *elementPtr;
delete elementPtr;
} else {
; // No op.
}
return result;
}
template<typename ElementT>
size_t LLThreadSafeQueue<ElementT>::size(void)
{
return mImplementation.size();
}
#endif

View File

@@ -47,7 +47,7 @@ typedef const char* (*EngineInfoLLImageJ2CFunction)();
CreateLLImageJ2CFunction j2cimpl_create_func;
DestroyLLImageJ2CFunction j2cimpl_destroy_func;
EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func;
AIAPRPool j2cimpl_dso_memory_pool;
LLAPRPool j2cimpl_dso_memory_pool;
apr_dso_handle_t *j2cimpl_dso_handle;
//Declare the prototype for theses functions here, their functionality

View File

@@ -168,7 +168,7 @@ protected:
apr_socket_t* mSocket;
// Our memory pool.
AIAPRPool mPool;
LLAPRPool mPool;
// The port if we know it.
U16 mPort;

View File

@@ -56,7 +56,7 @@
#include "llstring.h"
#include "lluuid.h"
#include "net.h"
#include "aiaprpool.h"
#include "llaprpool.h"
//
// constants
@@ -64,7 +64,7 @@
const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
static bool gMailEnabled = true;
static AIAPRPool gMailPool;
static LLAPRPool gMailPool;
static apr_sockaddr_t* gSockAddr;
static apr_socket_t* gMailSocket;

View File

@@ -1136,7 +1136,7 @@ LLPumpIO::LLChainInfo::LLChainInfo() :
mInit(false),
mLock(0),
mEOS(false),
mDescriptorsPool(new AIAPRPool(LLThread::tldata().mRootPool))
mDescriptorsPool(new LLAPRPool(LLThread::tldata().mRootPool))
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);

View File

@@ -41,7 +41,7 @@
#include <sys/param.h>
#endif
#include "aiaprpool.h"
#include "llaprpool.h"
#include "llbuffer.h"
#include "llframetimer.h"
#include "lliopipe.h"
@@ -363,7 +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;
boost::shared_ptr<LLAPRPool> mDescriptorsPool;
};
// All the running chains & info
@@ -383,8 +383,8 @@ protected:
callbacks_t mCallbacks;
// Memory pool for pollsets & mutexes.
AIAPRPool mPool;
AIAPRPool mCurrentPool;
LLAPRPool mPool;
LLAPRPool mCurrentPool;
S32 mCurrentPoolReallocCount;
#if LL_THREADS_APR

View File

@@ -110,7 +110,7 @@ public:
LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { }
apr_socket_t *mAPRSocketp;
apr_pollfd_t mPollFD;
AIAPRPool mPool;
LLAPRPool mPool;
};
namespace

View File

@@ -36,7 +36,7 @@
#include "linden_common.h"
#include "llplugininstance.h"
#include "aiaprpool.h"
#include "llaprpool.h"
/** Virtual destructor. */
LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener()
@@ -85,7 +85,7 @@ int LLPluginInstance::load(std::string &plugin_file)
int result = apr_dso_load(&mDSOHandle,
plugin_file.c_str(),
AIAPRRootPool::get()());
LLAPRRootPool::get()());
if(result != APR_SUCCESS)
{
char buf[1024];

View File

@@ -52,7 +52,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
bool LLPluginProcessParent::sUseReadThread = false;
apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
AIAPRPool LLPluginProcessParent::sPollSetPool;
LLAPRPool LLPluginProcessParent::sPollSetPool;
bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
LLMutex *LLPluginProcessParent::sInstancesMutex;
std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances;
@@ -285,7 +285,7 @@ void LLPluginProcessParent::idle(void)
APR_INET,
0, // port 0 = ephemeral ("find me a port")
0,
AIAPRRootPool::get()());
LLAPRRootPool::get()());
if(ll_apr_warn_status(status))
{

View File

@@ -192,9 +192,9 @@ private:
static bool sUseReadThread;
apr_pollfd_t mPollFD;
AIAPRPool mPollFDPool;
LLAPRPool mPollFDPool;
static apr_pollset_t *sPollSet;
static AIAPRPool sPollSetPool;
static LLAPRPool sPollSetPool;
static bool sPollsetNeedsRebuild;
static LLMutex *sInstancesMutex;
static std::list<LLPluginProcessParent*> sInstances;

View File

@@ -35,7 +35,7 @@
#ifndef LL_LLPLUGINSHAREDMEMORY_H
#define LL_LLPLUGINSHAREDMEMORY_H
#include "aiaprpool.h"
#include "llaprpool.h"
class LLPluginSharedMemoryPlatformImpl;
@@ -117,7 +117,7 @@ private:
bool close(void);
bool unlink(void);
AIAPRPool mPool;
LLAPRPool mPool;
std::string mName;
size_t mSize;
void *mMappedAddress;

View File

@@ -50,7 +50,7 @@ extern "C" {
#include <pulse/subscribe.h>
#include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken.
#include "aiaprpool.h"
#include "llaprpool.h"
#include "apr_dso.h"
}
@@ -66,7 +66,7 @@ extern "C" {
#undef LL_PA_SYM
static bool sSymsGrabbed = false;
static AIAPRPool sSymPADSOMemoryPool;
static LLAPRPool sSymPADSOMemoryPool;
static apr_dso_handle_t *sSymPADSOHandleG = NULL;
bool grab_pa_syms(std::string pulse_dso_name)

View File

@@ -43,7 +43,7 @@
#include "linden_common.h"
#include "llerrorcontrol.h"
#include "lltut.h"
#include "aiaprpool.h"
#include "llaprpool.h"
#include "apr_getopt.h"
@@ -250,7 +250,7 @@ int main(int argc, char **argv)
ctype_workaround();
#endif
AIAPRPool pool;
LLAPRPool pool;
pool.create();
apr_getopt_t* os = NULL;
if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv))