Backed out changeset b782a75c99e6
parent
ef490e308c
commit
4331c112ab
|
|
@ -61,15 +61,11 @@ Aimee Trescothick
|
|||
Alejandro Rosenthal
|
||||
VWR-1184
|
||||
Aleric Inglewood
|
||||
SNOW-84
|
||||
SNOW-240
|
||||
SNOW-477
|
||||
SNOW-522
|
||||
SNOW-626
|
||||
SNOW-744
|
||||
SNOW-756
|
||||
SNOW-764
|
||||
SNOW-766
|
||||
VWR-10001
|
||||
VWR-10579
|
||||
VWR-10759
|
||||
|
|
@ -90,8 +86,11 @@ Aleric Inglewood
|
|||
VWR-24321
|
||||
VWR-24354
|
||||
VWR-24519
|
||||
SNOW-84
|
||||
SNOW-477
|
||||
SNOW-744
|
||||
SNOW-766
|
||||
STORM-163
|
||||
STORM-864
|
||||
Ales Beaumont
|
||||
VWR-9352
|
||||
SNOW-240
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!LLAPRFile::isExist(filename, LL_APR_RPB))
|
||||
if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
|
||||
{
|
||||
// File not found, abort.
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro
|
|||
error_msg.clear();
|
||||
|
||||
//********************************
|
||||
LLAPRFile infile(in_fname, LL_APR_RB);
|
||||
LLAPRFile infile ;
|
||||
infile.open(in_fname,LL_APR_RB);
|
||||
//********************************
|
||||
if (!infile.getFileHandle())
|
||||
{
|
||||
|
|
@ -232,7 +233,8 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname
|
|||
|
||||
S32 data_left = 0;
|
||||
|
||||
LLAPRFile infile(in_fname,LL_APR_RB);
|
||||
LLAPRFile infile ;
|
||||
infile.open(in_fname,LL_APR_RB);
|
||||
if (!infile.getFileHandle())
|
||||
{
|
||||
llwarns << "Couldn't open temporary ogg file for writing: " << in_fname
|
||||
|
|
@ -240,7 +242,8 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname
|
|||
return(LLVORBISENC_SOURCE_OPEN_ERR);
|
||||
}
|
||||
|
||||
LLAPRFile outfile(out_fname, LL_APR_WPB);
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(out_fname,LL_APR_WPB);
|
||||
if (!outfile.getFileHandle())
|
||||
{
|
||||
llwarns << "Couldn't open upload sound file for reading: " << in_fname
|
||||
|
|
|
|||
|
|
@ -219,7 +219,8 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
|
|||
//--------------------------------------------------------------------
|
||||
std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName);
|
||||
|
||||
LLAPRFile infile(path, LL_APR_R);
|
||||
LLAPRFile infile ;
|
||||
infile.open(path, LL_APR_R);
|
||||
apr_file_t *fp = infile.getFileHandle();
|
||||
if (!fp)
|
||||
return E_ST_NO_XLT_FILE;
|
||||
|
|
|
|||
|
|
@ -351,7 +351,8 @@ BOOL LLKeyframeMotionParam::loadMotions()
|
|||
// open the file
|
||||
//-------------------------------------------------------------------------
|
||||
S32 fileSize = 0;
|
||||
LLAPRFile infile(path, LL_APR_R, &fileSize);
|
||||
LLAPRFile infile ;
|
||||
infile.open(path, LL_APR_R, NULL, &fileSize);
|
||||
apr_file_t* fp = infile.getFileHandle() ;
|
||||
if (!fp || fileSize == 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -204,7 +204,8 @@ LLFSMState* LLStateDiagram::getState(U32 state_id)
|
|||
|
||||
BOOL LLStateDiagram::saveDotFile(const std::string& filename)
|
||||
{
|
||||
LLAPRFile outfile(filename, LL_APR_W);
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(filename, LL_APR_W);
|
||||
apr_file_t* dot_file = outfile.getFileHandle() ;
|
||||
|
||||
if (!dot_file)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ set(llcommon_SOURCE_FILES
|
|||
llallocator_heap_profile.cpp
|
||||
llapp.cpp
|
||||
llapr.cpp
|
||||
llaprpool.cpp
|
||||
llassettype.cpp
|
||||
llavatarname.cpp
|
||||
llbase32.cpp
|
||||
|
|
@ -81,7 +80,6 @@ set(llcommon_SOURCE_FILES
|
|||
llrand.cpp
|
||||
llrefcount.cpp
|
||||
llrun.cpp
|
||||
llscopedvolatileaprpool.h
|
||||
llsd.cpp
|
||||
llsdserialize.cpp
|
||||
llsdserialize_xml.cpp
|
||||
|
|
@ -123,7 +121,6 @@ set(llcommon_HEADER_FILES
|
|||
llavatarname.h
|
||||
llapp.h
|
||||
llapr.h
|
||||
llaprpool.h
|
||||
llassettype.h
|
||||
llassoclist.h
|
||||
llavatarconstants.h
|
||||
|
|
|
|||
|
|
@ -136,6 +136,10 @@ void LLApp::commonCtor()
|
|||
mOptions.append(sd);
|
||||
}
|
||||
|
||||
// Make sure we clean up APR when we exit
|
||||
// Don't need to do this if we're cleaning up APR in the destructor
|
||||
//atexit(ll_cleanup_apr);
|
||||
|
||||
// Set the application to this instance.
|
||||
sApplication = this;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,212 @@
|
|||
#include "linden_common.h"
|
||||
#include "llapr.h"
|
||||
#include "apr_dso.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
|
||||
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
|
||||
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
|
||||
apr_thread_mutex_t *gLogMutexp = NULL;
|
||||
apr_thread_mutex_t *gCallStacksLogMutexp = NULL;
|
||||
|
||||
const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
|
||||
|
||||
void ll_init_apr()
|
||||
{
|
||||
if (!gAPRPoolp)
|
||||
{
|
||||
// Initialize APR and create the global pool
|
||||
apr_initialize();
|
||||
apr_pool_create(&gAPRPoolp, NULL);
|
||||
|
||||
// Initialize the logging mutex
|
||||
apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
|
||||
apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
|
||||
}
|
||||
|
||||
if(!LLAPRFile::sAPRFilePoolp)
|
||||
{
|
||||
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ll_cleanup_apr()
|
||||
{
|
||||
LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
|
||||
|
||||
if (gLogMutexp)
|
||||
{
|
||||
// Clean up the logging mutex
|
||||
|
||||
// All other threads NEED to be done before we clean up APR, so this is okay.
|
||||
apr_thread_mutex_destroy(gLogMutexp);
|
||||
gLogMutexp = NULL;
|
||||
}
|
||||
if (gCallStacksLogMutexp)
|
||||
{
|
||||
// Clean up the logging mutex
|
||||
|
||||
// All other threads NEED to be done before we clean up APR, so this is okay.
|
||||
apr_thread_mutex_destroy(gCallStacksLogMutexp);
|
||||
gCallStacksLogMutexp = NULL;
|
||||
}
|
||||
if (gAPRPoolp)
|
||||
{
|
||||
apr_pool_destroy(gAPRPoolp);
|
||||
gAPRPoolp = NULL;
|
||||
}
|
||||
if (LLAPRFile::sAPRFilePoolp)
|
||||
{
|
||||
delete LLAPRFile::sAPRFilePoolp ;
|
||||
LLAPRFile::sAPRFilePoolp = NULL ;
|
||||
}
|
||||
apr_terminate();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//LLAPRPool
|
||||
//
|
||||
LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
|
||||
: mParent(parent),
|
||||
mReleasePoolFlag(releasePoolFlag),
|
||||
mMaxSize(size),
|
||||
mPool(NULL)
|
||||
{
|
||||
createAPRPool() ;
|
||||
}
|
||||
|
||||
LLAPRPool::~LLAPRPool()
|
||||
{
|
||||
releaseAPRPool() ;
|
||||
}
|
||||
|
||||
void LLAPRPool::createAPRPool()
|
||||
{
|
||||
if(mPool)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
mStatus = apr_pool_create(&mPool, mParent);
|
||||
ll_apr_warn_status(mStatus) ;
|
||||
|
||||
if(mMaxSize > 0) //size is the number of blocks (which is usually 4K), NOT bytes.
|
||||
{
|
||||
apr_allocator_t *allocator = apr_pool_allocator_get(mPool);
|
||||
if (allocator)
|
||||
{
|
||||
apr_allocator_max_free_set(allocator, mMaxSize) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLAPRPool::releaseAPRPool()
|
||||
{
|
||||
if(!mPool)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(!mParent || mReleasePoolFlag)
|
||||
{
|
||||
apr_pool_destroy(mPool) ;
|
||||
mPool = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
apr_pool_t* LLAPRPool::getAPRPool()
|
||||
{
|
||||
return mPool ;
|
||||
}
|
||||
|
||||
LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
|
||||
: LLAPRPool(parent, size, releasePoolFlag),
|
||||
mNumActiveRef(0),
|
||||
mNumTotalRef(0),
|
||||
mMutexPool(NULL),
|
||||
mMutexp(NULL)
|
||||
{
|
||||
//create mutex
|
||||
if(!is_local) //not a local apr_pool, that is: shared by multiple threads.
|
||||
{
|
||||
apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex
|
||||
apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool);
|
||||
}
|
||||
}
|
||||
|
||||
LLVolatileAPRPool::~LLVolatileAPRPool()
|
||||
{
|
||||
//delete mutex
|
||||
if(mMutexp)
|
||||
{
|
||||
apr_thread_mutex_destroy(mMutexp);
|
||||
apr_pool_destroy(mMutexPool);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool().
|
||||
//
|
||||
//virtual
|
||||
apr_pool_t* LLVolatileAPRPool::getAPRPool()
|
||||
{
|
||||
return LLVolatileAPRPool::getVolatileAPRPool() ;
|
||||
}
|
||||
|
||||
apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
|
||||
{
|
||||
LLScopedLock lock(mMutexp) ;
|
||||
|
||||
mNumTotalRef++ ;
|
||||
mNumActiveRef++ ;
|
||||
|
||||
if(!mPool)
|
||||
{
|
||||
createAPRPool() ;
|
||||
}
|
||||
|
||||
return mPool ;
|
||||
}
|
||||
|
||||
void LLVolatileAPRPool::clearVolatileAPRPool()
|
||||
{
|
||||
LLScopedLock lock(mMutexp) ;
|
||||
|
||||
if(mNumActiveRef > 0)
|
||||
{
|
||||
mNumActiveRef--;
|
||||
if(mNumActiveRef < 1)
|
||||
{
|
||||
if(isFull())
|
||||
{
|
||||
mNumTotalRef = 0 ;
|
||||
|
||||
//destroy the apr_pool.
|
||||
releaseAPRPool() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
//This does not actually free the memory,
|
||||
//it just allows the pool to re-use this memory for the next allocation.
|
||||
apr_pool_clear(mPool) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert_always(mNumActiveRef > 0) ;
|
||||
}
|
||||
|
||||
//paranoia check if the pool is jammed.
|
||||
//will remove the check before going to release.
|
||||
llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
|
||||
}
|
||||
|
||||
BOOL LLVolatileAPRPool::isFull()
|
||||
{
|
||||
return mNumTotalRef > FULL_VOLATILE_APR_POOL ;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// LLScopedLock
|
||||
|
|
@ -109,17 +313,15 @@ void ll_apr_assert_status(apr_status_t status, apr_dso_handle_t *handle)
|
|||
//
|
||||
LLAPRFile::LLAPRFile()
|
||||
: mFile(NULL),
|
||||
mVolatileFilePoolp(NULL),
|
||||
mRegularFilePoolp(NULL)
|
||||
mCurrentFilePoolp(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLAPRFile::LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep, access_t access_type)
|
||||
LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool)
|
||||
: mFile(NULL),
|
||||
mVolatileFilePoolp(NULL),
|
||||
mRegularFilePoolp(NULL)
|
||||
mCurrentFilePoolp(NULL)
|
||||
{
|
||||
open(filename, flags, access_type, sizep);
|
||||
open(filename, flags, pool);
|
||||
}
|
||||
|
||||
LLAPRFile::~LLAPRFile()
|
||||
|
|
@ -136,58 +338,36 @@ apr_status_t LLAPRFile::close()
|
|||
mFile = NULL ;
|
||||
}
|
||||
|
||||
if (mVolatileFilePoolp)
|
||||
if(mCurrentFilePoolp)
|
||||
{
|
||||
mVolatileFilePoolp->clearVolatileAPRPool() ;
|
||||
mVolatileFilePoolp = NULL ;
|
||||
}
|
||||
|
||||
if (mRegularFilePoolp)
|
||||
{
|
||||
delete mRegularFilePoolp;
|
||||
mRegularFilePoolp = NULL;
|
||||
mCurrentFilePoolp->clearVolatileAPRPool() ;
|
||||
mCurrentFilePoolp = NULL ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep)
|
||||
apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool, S32* sizep)
|
||||
{
|
||||
llassert_always(!mFile);
|
||||
llassert_always(!mVolatileFilePoolp && !mRegularFilePoolp);
|
||||
apr_status_t s ;
|
||||
|
||||
apr_status_t status;
|
||||
{
|
||||
apr_pool_t* apr_file_open_pool; // The use of apr_pool_t is OK here.
|
||||
// This is a temporary variable for a pool that is passed directly to apr_file_open below.
|
||||
if (access_type == short_lived)
|
||||
{
|
||||
// Use a "volatile" thread-local pool.
|
||||
mVolatileFilePoolp = &LLThreadLocalData::tldata().mVolatileAPRPool;
|
||||
// Access the pool and increment its reference count.
|
||||
// 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 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);
|
||||
}
|
||||
if (status != APR_SUCCESS || !mFile)
|
||||
//check if already open some file
|
||||
llassert_always(!mFile) ;
|
||||
llassert_always(!mCurrentFilePoolp) ;
|
||||
|
||||
apr_pool_t* apr_pool = pool ? pool->getVolatileAPRPool() : NULL ;
|
||||
s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(apr_pool));
|
||||
|
||||
if (s != APR_SUCCESS || !mFile)
|
||||
{
|
||||
mFile = NULL ;
|
||||
close() ;
|
||||
|
||||
if (sizep)
|
||||
{
|
||||
*sizep = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
if (sizep)
|
||||
else if (sizep)
|
||||
{
|
||||
S32 file_size = 0;
|
||||
apr_off_t offset = 0;
|
||||
|
|
@ -201,7 +381,49 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc
|
|||
*sizep = file_size;
|
||||
}
|
||||
|
||||
return status;
|
||||
if(!mCurrentFilePoolp)
|
||||
{
|
||||
mCurrentFilePoolp = pool ;
|
||||
|
||||
if(!mFile)
|
||||
{
|
||||
close() ;
|
||||
}
|
||||
}
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
//use gAPRPoolp.
|
||||
apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
|
||||
//check if already open some file
|
||||
llassert_always(!mFile) ;
|
||||
llassert_always(!mCurrentFilePoolp) ;
|
||||
llassert_always(use_global_pool) ; //be aware of using gAPRPoolp.
|
||||
|
||||
s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, gAPRPoolp);
|
||||
if (s != APR_SUCCESS || !mFile)
|
||||
{
|
||||
mFile = NULL ;
|
||||
close() ;
|
||||
return s;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool)
|
||||
{
|
||||
if(!pool)
|
||||
{
|
||||
mCurrentFilePoolp = sAPRFilePoolp ;
|
||||
return mCurrentFilePoolp->getVolatileAPRPool() ;
|
||||
}
|
||||
|
||||
return pool ;
|
||||
}
|
||||
|
||||
// File I/O
|
||||
|
|
@ -259,6 +481,45 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset)
|
|||
//static components of LLAPRFile
|
||||
//
|
||||
|
||||
//static
|
||||
apr_status_t LLAPRFile::close(apr_file_t* file_handle, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t ret = APR_SUCCESS ;
|
||||
if(file_handle)
|
||||
{
|
||||
ret = apr_file_close(file_handle);
|
||||
file_handle = NULL ;
|
||||
}
|
||||
|
||||
if(pool)
|
||||
{
|
||||
pool->clearVolatileAPRPool() ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
//static
|
||||
apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
|
||||
{
|
||||
apr_status_t s;
|
||||
apr_file_t* file_handle ;
|
||||
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
|
||||
s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
if (s != APR_SUCCESS || !file_handle)
|
||||
{
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " Attempting to open filename: " << filename << LL_ENDL;
|
||||
file_handle = NULL ;
|
||||
close(file_handle, pool) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return file_handle ;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
|
||||
{
|
||||
|
|
@ -292,15 +553,13 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
|
|||
}
|
||||
|
||||
//static
|
||||
S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes)
|
||||
S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_file_t* file_handle;
|
||||
LLScopedVolatileAPRPool pool;
|
||||
apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool);
|
||||
if (s != APR_SUCCESS || !file_handle)
|
||||
//*****************************************
|
||||
apr_file_t* file_handle = open(filename, pool, APR_READ|APR_BINARY);
|
||||
//*****************************************
|
||||
if (!file_handle)
|
||||
{
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -330,13 +589,14 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb
|
|||
}
|
||||
}
|
||||
|
||||
apr_file_close(file_handle);
|
||||
|
||||
//*****************************************
|
||||
close(file_handle, pool) ;
|
||||
//*****************************************
|
||||
return (S32)bytes_read;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes)
|
||||
S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
|
||||
if (offset < 0)
|
||||
|
|
@ -345,13 +605,11 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
|
|||
offset = 0;
|
||||
}
|
||||
|
||||
apr_file_t* file_handle;
|
||||
LLScopedVolatileAPRPool pool;
|
||||
apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
|
||||
if (s != APR_SUCCESS || !file_handle)
|
||||
//*****************************************
|
||||
apr_file_t* file_handle = open(filename, pool, flags);
|
||||
//*****************************************
|
||||
if (!file_handle)
|
||||
{
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -381,18 +639,21 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
|
|||
}
|
||||
}
|
||||
|
||||
apr_file_close(file_handle);
|
||||
//*****************************************
|
||||
LLAPRFile::close(file_handle, pool);
|
||||
//*****************************************
|
||||
|
||||
return (S32)bytes_written;
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLAPRFile::remove(const std::string& filename)
|
||||
bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
|
||||
LLScopedVolatileAPRPool pool;
|
||||
s = apr_file_remove(filename.c_str(), pool);
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_remove(filename.c_str(), pool->getVolatileAPRPool());
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
|
|
@ -404,12 +665,13 @@ bool LLAPRFile::remove(const std::string& filename)
|
|||
}
|
||||
|
||||
//static
|
||||
bool LLAPRFile::rename(const std::string& filename, const std::string& newname)
|
||||
bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
|
||||
LLScopedVolatileAPRPool pool;
|
||||
s = apr_file_rename(filename.c_str(), newname.c_str(), pool);
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_rename(filename.c_str(), newname.c_str(), pool->getVolatileAPRPool());
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
|
|
@ -421,44 +683,49 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname)
|
|||
}
|
||||
|
||||
//static
|
||||
bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags)
|
||||
bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
|
||||
{
|
||||
apr_file_t* file_handle;
|
||||
apr_file_t* apr_file;
|
||||
apr_status_t s;
|
||||
|
||||
LLScopedVolatileAPRPool pool;
|
||||
s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool);
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
|
||||
if (s != APR_SUCCESS || !file_handle)
|
||||
if (s != APR_SUCCESS || !apr_file)
|
||||
{
|
||||
pool->clearVolatileAPRPool() ;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
apr_file_close(file_handle);
|
||||
apr_file_close(apr_file) ;
|
||||
pool->clearVolatileAPRPool() ;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLAPRFile::size(const std::string& filename)
|
||||
S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_file_t* file_handle;
|
||||
apr_file_t* apr_file;
|
||||
apr_finfo_t info;
|
||||
apr_status_t s;
|
||||
|
||||
LLScopedVolatileAPRPool pool;
|
||||
s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool);
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
|
||||
if (s != APR_SUCCESS || !file_handle)
|
||||
if (s != APR_SUCCESS || !apr_file)
|
||||
{
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, file_handle);
|
||||
apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
|
||||
|
||||
apr_file_close(file_handle) ;
|
||||
apr_file_close(apr_file) ;
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s == APR_SUCCESS)
|
||||
{
|
||||
|
|
@ -472,29 +739,31 @@ S32 LLAPRFile::size(const std::string& filename)
|
|||
}
|
||||
|
||||
//static
|
||||
bool LLAPRFile::makeDir(const std::string& dirname)
|
||||
bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
|
||||
LLScopedVolatileAPRPool pool;
|
||||
s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool);
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " while attempting to make directory: " << dirname << LL_ENDL;
|
||||
LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLAPRFile::removeDir(const std::string& dirname)
|
||||
bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
|
||||
LLScopedVolatileAPRPool pool;
|
||||
s = apr_file_remove(dirname.c_str(), pool);
|
||||
pool = pool ? pool : LLAPRFile::sAPRFilePoolp ;
|
||||
s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool());
|
||||
pool->clearVolatileAPRPool() ;
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,9 +50,71 @@
|
|||
#include "apr_atomic.h"
|
||||
#include "llstring.h"
|
||||
|
||||
extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
|
||||
extern apr_thread_mutex_t* gCallStacksLogMutexp;
|
||||
|
||||
struct apr_dso_handle_t;
|
||||
class LLAPRPool;
|
||||
class LLVolatileAPRPool;
|
||||
|
||||
/**
|
||||
* @brief initialize the common apr constructs -- apr itself, the
|
||||
* global pool, and a mutex.
|
||||
*/
|
||||
void LL_COMMON_API ll_init_apr();
|
||||
|
||||
/**
|
||||
* @brief Cleanup those common apr constructs.
|
||||
*/
|
||||
void LL_COMMON_API ll_cleanup_apr();
|
||||
|
||||
//
|
||||
//LL apr_pool
|
||||
//manage apr_pool_t, destroy allocated apr_pool in the destruction function.
|
||||
//
|
||||
class LL_COMMON_API LLAPRPool
|
||||
{
|
||||
public:
|
||||
LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ;
|
||||
virtual ~LLAPRPool() ;
|
||||
|
||||
virtual apr_pool_t* getAPRPool() ;
|
||||
apr_status_t getStatus() {return mStatus ; }
|
||||
|
||||
protected:
|
||||
void releaseAPRPool() ;
|
||||
void createAPRPool() ;
|
||||
|
||||
protected:
|
||||
apr_pool_t* mPool ; //pointing to an apr_pool
|
||||
apr_pool_t* mParent ; //parent pool
|
||||
apr_size_t mMaxSize ; //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work.
|
||||
apr_status_t mStatus ; //status when creating the pool
|
||||
BOOL mReleasePoolFlag ; //if set, mPool is destroyed when LLAPRPool is deleted. default value is true.
|
||||
};
|
||||
|
||||
//
|
||||
//volatile LL apr_pool
|
||||
//which clears memory automatically.
|
||||
//so it can not hold static data or data after memory is cleared
|
||||
//
|
||||
class LL_COMMON_API LLVolatileAPRPool : public LLAPRPool
|
||||
{
|
||||
public:
|
||||
LLVolatileAPRPool(BOOL is_local = TRUE, apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
|
||||
virtual ~LLVolatileAPRPool();
|
||||
|
||||
/*virtual*/ apr_pool_t* getAPRPool() ; //define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool().
|
||||
apr_pool_t* getVolatileAPRPool() ;
|
||||
void clearVolatileAPRPool() ;
|
||||
|
||||
BOOL isFull() ;
|
||||
|
||||
private:
|
||||
S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
|
||||
S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating.
|
||||
|
||||
apr_thread_mutex_t *mMutexp;
|
||||
apr_pool_t *mMutexPool;
|
||||
} ;
|
||||
|
||||
/**
|
||||
* @class LLScopedLock
|
||||
|
|
@ -143,20 +205,15 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
|
|||
// make this non copyable since a copy closes the file
|
||||
private:
|
||||
apr_file_t* mFile ;
|
||||
LLVolatileAPRPool* mVolatileFilePoolp; // (Thread local) APR pool currently in use.
|
||||
LLAPRPool* mRegularFilePoolp; // ...or a regular pool.
|
||||
LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool.
|
||||
|
||||
public:
|
||||
enum access_t {
|
||||
long_lived, // Use a global pool for long-lived file accesses.
|
||||
short_lived // Use a volatile pool for short-lived file accesses.
|
||||
};
|
||||
|
||||
LLAPRFile() ;
|
||||
LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep = NULL, access_t access_type = short_lived);
|
||||
LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL);
|
||||
~LLAPRFile() ;
|
||||
|
||||
apr_status_t open(const std::string& filename, apr_int32_t flags, access_t access_type, S32* sizep = NULL);
|
||||
|
||||
apr_status_t open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL, S32* sizep = NULL);
|
||||
apr_status_t open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool); //use gAPRPoolp.
|
||||
apr_status_t close() ;
|
||||
|
||||
// Returns actual offset, -1 if seek fails
|
||||
|
|
@ -169,24 +226,32 @@ public:
|
|||
|
||||
apr_file_t* getFileHandle() {return mFile;}
|
||||
|
||||
private:
|
||||
apr_pool_t* getAPRFilePool(apr_pool_t* pool) ;
|
||||
|
||||
//
|
||||
//*******************************************************************************************************************************
|
||||
//static components
|
||||
//
|
||||
public:
|
||||
static LLVolatileAPRPool *sAPRFilePoolp ; //a global apr_pool for APRFile, which is used only when local pool does not exist.
|
||||
|
||||
private:
|
||||
static apr_file_t* open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags);
|
||||
static apr_status_t close(apr_file_t* file, LLVolatileAPRPool* pool) ;
|
||||
static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset);
|
||||
public:
|
||||
// returns false if failure:
|
||||
static bool remove(const std::string& filename);
|
||||
static bool rename(const std::string& filename, const std::string& newname);
|
||||
static bool isExist(const std::string& filename, apr_int32_t flags = APR_READ);
|
||||
static S32 size(const std::string& filename);
|
||||
static bool makeDir(const std::string& dirname);
|
||||
static bool removeDir(const std::string& dirname);
|
||||
static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL);
|
||||
static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL);
|
||||
static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ);
|
||||
static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL);
|
||||
static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
|
||||
static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
|
||||
|
||||
// Returns bytes read/written, 0 if read/write fails:
|
||||
static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes);
|
||||
static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes); // offset<0 means append
|
||||
static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);
|
||||
static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); // offset<0 means append
|
||||
//*******************************************************************************************************************************
|
||||
};
|
||||
|
||||
|
|
@ -202,4 +267,6 @@ bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* han
|
|||
void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
|
||||
void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle);
|
||||
|
||||
extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
|
||||
|
||||
#endif // LL_LLAPR_H
|
||||
|
|
|
|||
|
|
@ -1,202 +0,0 @@
|
|||
/**
|
||||
* @file llaprpool.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, 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$
|
||||
*
|
||||
* CHANGELOG
|
||||
* and additional copyright holders.
|
||||
*
|
||||
* 04/04/2010
|
||||
* - Initial version, written by Aleric Inglewood @ SL
|
||||
*
|
||||
* 10/11/2010
|
||||
* - Added APR_HAS_THREADS #if's to allow creation and destruction
|
||||
* of subpools by threads other than the parent pool owner.
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llaprpool.h"
|
||||
#include "llthread.h"
|
||||
|
||||
// Create a subpool from 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 = &LLThreadLocalData::tldata().mRootPool;
|
||||
}
|
||||
llassert(mParent->mPool); // Parent must be initialized.
|
||||
#if APR_HAS_THREADS
|
||||
// As per the documentation of APR (ie http://apr.apache.org/docs/apr/1.4/apr__pools_8h.html):
|
||||
//
|
||||
// Note that most operations on pools are not thread-safe: a single pool should only be
|
||||
// accessed by a single thread at any given time. The one exception to this rule is creating
|
||||
// a subpool of a given pool: one or more threads can safely create subpools at the same
|
||||
// time that another thread accesses the parent pool.
|
||||
//
|
||||
// In other words, it's safe for any thread to create a (sub)pool, independent of who
|
||||
// owns the parent pool.
|
||||
mOwner = apr_os_thread_current();
|
||||
#else
|
||||
mOwner = mParent->mOwner;
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
#endif
|
||||
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
|
||||
llassert_always(apr_pool_create_status == APR_SUCCESS);
|
||||
llassert(mPool); // Initialized.
|
||||
apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null);
|
||||
}
|
||||
|
||||
// Destroy the (sub)pool, if any.
|
||||
void LLAPRPool::destroy(void)
|
||||
{
|
||||
// Only do anything if we are not already (being) destroyed.
|
||||
if (mPool)
|
||||
{
|
||||
#if !APR_HAS_THREADS
|
||||
// If we are a root pool, then every thread may destruct us: in that case
|
||||
// we have to assume that no other thread will use this pool concurrently,
|
||||
// of course. Otherwise, if we are a subpool, only the thread that owns
|
||||
// the parent may destruct us, since that is the pool that is still alive,
|
||||
// possibly being used by others and being altered here.
|
||||
llassert(!mParent || apr_os_thread_equal(mParent->mOwner, apr_os_thread_current()));
|
||||
#endif
|
||||
apr_pool_t* pool = mPool; // The use of apr_pool_t is OK here.
|
||||
// Temporary store before destroying the pool.
|
||||
mPool = NULL; // Mark that we are BEING destructed.
|
||||
apr_pool_cleanup_kill(pool, this, &s_plain_cleanup);
|
||||
apr_pool_destroy(pool);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLAPRPool::parent_is_being_destructed(void)
|
||||
{
|
||||
return mParent && (!mParent->mPool || mParent->parent_is_being_destructed());
|
||||
}
|
||||
|
||||
LLAPRInitialization::LLAPRInitialization(void)
|
||||
{
|
||||
static bool apr_initialized = false;
|
||||
|
||||
if (!apr_initialized)
|
||||
{
|
||||
apr_initialize();
|
||||
}
|
||||
|
||||
apr_initialized = true;
|
||||
}
|
||||
|
||||
bool LLAPRRootPool::sCountInitialized = false;
|
||||
apr_uint32_t volatile LLAPRRootPool::sCount;
|
||||
|
||||
apr_thread_mutex_t* gLogMutexp;
|
||||
apr_thread_mutex_t* gCallStacksLogMutexp;
|
||||
|
||||
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)
|
||||
{
|
||||
// Initialize the logging mutex
|
||||
apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool);
|
||||
apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool);
|
||||
|
||||
apr_status_t status = apr_atomic_init(mPool);
|
||||
llassert_always(status == APR_SUCCESS);
|
||||
apr_atomic_set32(&sCount, 1); // Set to 1 to account for the global root pool.
|
||||
sCountInitialized = true;
|
||||
|
||||
// Initialize thread-local APR pool support.
|
||||
// Because this recursively calls LLAPRRootPool::LLAPRRootPool(void)
|
||||
// it must be done last, so that sCount is already initialized.
|
||||
LLThreadLocalData::init();
|
||||
}
|
||||
apr_atomic_inc32(&sCount);
|
||||
}
|
||||
|
||||
LLAPRRootPool::~LLAPRRootPool()
|
||||
{
|
||||
if (!apr_atomic_dec32(&sCount))
|
||||
{
|
||||
// The last pool was destructed. Cleanup remainder of APR.
|
||||
LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
|
||||
|
||||
if (gLogMutexp)
|
||||
{
|
||||
// Clean up the logging mutex
|
||||
|
||||
// All other threads NEED to be done before we clean up APR, so this is okay.
|
||||
apr_thread_mutex_destroy(gLogMutexp);
|
||||
gLogMutexp = NULL;
|
||||
}
|
||||
if (gCallStacksLogMutexp)
|
||||
{
|
||||
// Clean up the logging mutex
|
||||
|
||||
// All other threads NEED to be done before we clean up APR, so this is okay.
|
||||
apr_thread_mutex_destroy(gCallStacksLogMutexp);
|
||||
gCallStacksLogMutexp = NULL;
|
||||
}
|
||||
|
||||
// Must destroy ALL, and therefore this last LLAPRRootPool, before terminating APR.
|
||||
static_cast<LLAPRRootPool*>(this)->destroy();
|
||||
|
||||
apr_terminate();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
// 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).
|
||||
LLAPRRootPool& LLAPRRootPool::get(void)
|
||||
{
|
||||
static LLAPRRootPool global_APRpool(0);
|
||||
return global_APRpool;
|
||||
}
|
||||
|
||||
void LLVolatileAPRPool::clearVolatileAPRPool()
|
||||
{
|
||||
llassert_always(mNumActiveRef > 0);
|
||||
if (--mNumActiveRef == 0)
|
||||
{
|
||||
if (isOld())
|
||||
{
|
||||
destroy();
|
||||
mNumTotalRef = 0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This does not actually free the memory,
|
||||
// it just allows the pool to re-use this memory for the next allocation.
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Paranoia check if the pool is jammed.
|
||||
llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
|
||||
}
|
||||
|
|
@ -1,256 +0,0 @@
|
|||
/**
|
||||
* @file llaprpool.h
|
||||
* @brief Implementation of LLAPRPool
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, 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$
|
||||
*
|
||||
* CHANGELOG
|
||||
* and additional copyright holders.
|
||||
*
|
||||
* 04/04/2010
|
||||
* - Initial version, written by Aleric Inglewood @ SL
|
||||
*
|
||||
* 10/11/2010
|
||||
* - Added APR_HAS_THREADS #if's to allow creation and destruction
|
||||
* of subpools by threads other than the parent pool owner.
|
||||
*
|
||||
* 05/02/2011
|
||||
* - Fixed compilation on windows: Suppress compile warning 4996
|
||||
* and include <winsock2.h> before including <ws2tcpip.h>,
|
||||
* by Merov Linden @ SL.
|
||||
*/
|
||||
|
||||
#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"
|
||||
#include "apr_pools.h"
|
||||
#include "llerror.h"
|
||||
|
||||
extern void ll_init_apr();
|
||||
|
||||
/**
|
||||
* @brief A wrapper around the APR memory pool API.
|
||||
*
|
||||
* Usage of this class should be restricted to passing it to libapr-1 function calls that need it.
|
||||
*
|
||||
*/
|
||||
class LL_COMMON_API LLAPRPool
|
||||
{
|
||||
protected:
|
||||
//! Pointer to the underlaying pool. NULL if not initialized.
|
||||
apr_pool_t* mPool; // The use of apr_pool_t is OK here.
|
||||
// This is the wrapped pointer that it is all about!
|
||||
//! Pointer to the parent pool, if any. Only valid when mPool is non-zero.
|
||||
LLAPRPool* mParent;
|
||||
//! The thread that owns this memory pool. Only valid when mPool is non-zero.
|
||||
apr_os_thread_t mOwner;
|
||||
|
||||
public:
|
||||
/// Construct an uninitialized (destructed) pool.
|
||||
LLAPRPool(void) : mPool(NULL) { }
|
||||
|
||||
/// Construct a subpool from an existing pool.
|
||||
/// This is not a copy-constructor, this class doesn't have one!
|
||||
LLAPRPool(LLAPRPool& parent) : mPool(NULL) { create(parent); }
|
||||
|
||||
/// Destruct the memory pool (free all of its subpools and allocated memory).
|
||||
~LLAPRPool() { destroy(); }
|
||||
|
||||
protected:
|
||||
/// 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);
|
||||
llassert(mPool);
|
||||
apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null);
|
||||
}
|
||||
|
||||
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(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 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 an apr pool as argument.
|
||||
/// NEVER destroy a pool that is returned by this function!
|
||||
apr_pool_t* operator()(void) const // The use of apr_pool_t is OK here.
|
||||
// This is the accessor for passing the pool to libapr-1 functions.
|
||||
{
|
||||
llassert(mPool);
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
return mPool;
|
||||
}
|
||||
|
||||
/// Free all memory without destructing the pool.
|
||||
void clear(void)
|
||||
{
|
||||
llassert(mPool);
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
apr_pool_clear(mPool);
|
||||
}
|
||||
|
||||
// These methods would make this class 'complete' (as wrapper around the libapr
|
||||
// pool functions), but we don't use memory pools in the viewer (only when
|
||||
// we are forced to pass one to a libapr call), so don't define them in order
|
||||
// not to encourage people to use them.
|
||||
#if 0
|
||||
void* palloc(size_t size)
|
||||
{
|
||||
llassert(mPool);
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
return apr_palloc(mPool, size);
|
||||
}
|
||||
void* pcalloc(size_t size)
|
||||
{
|
||||
llassert(mPool);
|
||||
llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
|
||||
return apr_pcalloc(mPool, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool parent_is_being_destructed(void);
|
||||
static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<LLAPRPool*>(userdata)->plain_cleanup(); }
|
||||
|
||||
apr_status_t plain_cleanup(void)
|
||||
{
|
||||
if (mPool && // We are not being destructed,
|
||||
parent_is_being_destructed()) // but our parent is.
|
||||
// This means the pool is being destructed recursively by libapr
|
||||
// because one of its parents is being destructed.
|
||||
{
|
||||
mPool = NULL; // Stop destroy() from destructing the pool again.
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAPRInitialization
|
||||
{
|
||||
public:
|
||||
LLAPRInitialization(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Root memory pool (allocates memory from the operating system).
|
||||
*
|
||||
* This class should only be used by LLThreadLocalData
|
||||
* (and LLMutexRootPool when APR_HAS_THREADS isn't defined).
|
||||
*/
|
||||
class LL_COMMON_API LLAPRRootPool : public LLAPRInitialization, public LLAPRPool
|
||||
{
|
||||
private:
|
||||
/// Construct a root memory pool. Should only be used by LLThreadLocalData and LLMutexRootPool.
|
||||
friend class LLThreadLocalData;
|
||||
#if !APR_HAS_THREADS
|
||||
friend class LLMutexRootPool;
|
||||
#endif
|
||||
/// Construct a root memory pool.
|
||||
/// Should only be used by LLThreadLocalData.
|
||||
LLAPRRootPool(void);
|
||||
~LLAPRRootPool();
|
||||
|
||||
private:
|
||||
// Keep track of how many root pools exist and when the last one is destructed.
|
||||
static bool sCountInitialized;
|
||||
static apr_uint32_t volatile sCount;
|
||||
|
||||
public:
|
||||
// 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 LLAPRRootPool& get(void);
|
||||
|
||||
#if APR_POOL_DEBUG
|
||||
void grab_ownership(void)
|
||||
{
|
||||
// You need a patched libapr to use this.
|
||||
// See http://web.archiveorange.com/archive/v/5XO9y2zoxUOMt6Gmi1OI
|
||||
apr_pool_owner_set(mPool);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
// 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 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
|
||||
*
|
||||
* 'Volatile' APR memory pool which normally only clears memory,
|
||||
* and does not destroy the pool (the same pool is reused) for
|
||||
* greater efficiency. However, as a safe guard the apr pool
|
||||
* is destructed every FULL_VOLATILE_APR_POOL uses to allow
|
||||
* the system memory to be allocated more efficiently and not
|
||||
* get scattered through RAM.
|
||||
*/
|
||||
class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool
|
||||
{
|
||||
public:
|
||||
LLVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { }
|
||||
|
||||
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 LLVolatileAPRPool until the pool is recreated.
|
||||
static S32 const FULL_VOLATILE_APR_POOL = 1024;
|
||||
};
|
||||
|
||||
#endif // LL_LLAPRPOOL_H
|
||||
|
|
@ -30,10 +30,18 @@
|
|||
#include "llmemory.h"
|
||||
#include "llthread.h"
|
||||
|
||||
//static
|
||||
BOOL LLCommon::sAprInitialized = FALSE;
|
||||
|
||||
//static
|
||||
void LLCommon::initClass()
|
||||
{
|
||||
LLMemory::initClass();
|
||||
if (!sAprInitialized)
|
||||
{
|
||||
ll_init_apr();
|
||||
sAprInitialized = TRUE;
|
||||
}
|
||||
LLTimer::initClass();
|
||||
LLThreadSafeRefCount::initThreadSafeRefCount();
|
||||
// LLWorkerThread::initClass();
|
||||
|
|
@ -47,5 +55,10 @@ void LLCommon::cleanupClass()
|
|||
// LLWorkerThread::cleanupClass();
|
||||
LLThreadSafeRefCount::cleanupThreadSafeRefCount();
|
||||
LLTimer::cleanupClass();
|
||||
if (sAprInitialized)
|
||||
{
|
||||
ll_cleanup_apr();
|
||||
sAprInitialized = FALSE;
|
||||
}
|
||||
LLMemory::cleanupClass();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ class LL_COMMON_API LLCommon
|
|||
public:
|
||||
static void initClass();
|
||||
static void cleanupClass();
|
||||
private:
|
||||
static BOOL sAprInitialized;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -866,9 +866,6 @@ You get:
|
|||
|
||||
*/
|
||||
|
||||
extern apr_thread_mutex_t* gLogMutexp;
|
||||
extern apr_thread_mutex_t* gCallStacksLogMutexp;
|
||||
|
||||
namespace {
|
||||
bool checkLevelMap(const LevelMap& map, const std::string& key,
|
||||
LLError::ELevel& level)
|
||||
|
|
|
|||
|
|
@ -296,4 +296,5 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
|
|||
Such computation is done iff the message will be logged.
|
||||
*/
|
||||
|
||||
|
||||
#endif // LL_LLERROR_H
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@
|
|||
|
||||
LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
|
||||
: LLLineBuffer(),
|
||||
mMaxLines(max_lines)
|
||||
mMaxLines(max_lines),
|
||||
mMutex(NULL)
|
||||
{
|
||||
mTimer.reset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
* @file llscopedvolatileaprpool.h
|
||||
* @brief Implementation of LLScopedVolatileAPRPool
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, 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_LLSCOPEDVOLATILEAPRPOOL_H
|
||||
#define LL_LLSCOPEDVOLATILEAPRPOOL_H
|
||||
|
||||
#include "llthread.h"
|
||||
|
||||
/** 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:
|
||||
LLVolatileAPRPool& mPool;
|
||||
apr_pool_t* mScopedAPRpool; // The use of apr_pool_t is OK here.
|
||||
public:
|
||||
LLScopedVolatileAPRPool() : mPool(LLThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { }
|
||||
~LLScopedVolatileAPRPool() { mPool.clearVolatileAPRPool(); }
|
||||
//! @attention Only use this to pass the underlaying pointer to a libapr-1 function that requires it.
|
||||
operator apr_pool_t*() const { return mScopedAPRpool; } // The use of apr_pool_t is OK here.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -63,9 +63,6 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
|
|||
{
|
||||
LLThread *threadp = (LLThread *)datap;
|
||||
|
||||
// Create a thread local data.
|
||||
LLThreadLocalData::create(threadp);
|
||||
|
||||
// Run the user supplied function
|
||||
threadp->run();
|
||||
|
||||
|
|
@ -78,20 +75,38 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
|
|||
}
|
||||
|
||||
|
||||
LLThread::LLThread(std::string const& name) :
|
||||
mPaused(false),
|
||||
LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
|
||||
mPaused(FALSE),
|
||||
mName(name),
|
||||
mAPRThreadp(NULL),
|
||||
mStatus(STOPPED),
|
||||
mThreadLocalData(NULL)
|
||||
mStatus(STOPPED)
|
||||
{
|
||||
mRunCondition = new LLCondition;
|
||||
// Thread creation probably CAN be paranoid about APR being initialized, if necessary
|
||||
if (poolp)
|
||||
{
|
||||
mIsLocalPool = FALSE;
|
||||
mAPRPoolp = poolp;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsLocalPool = TRUE;
|
||||
apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
|
||||
}
|
||||
mRunCondition = new LLCondition(mAPRPoolp);
|
||||
|
||||
mLocalAPRFilePoolp = NULL ;
|
||||
}
|
||||
|
||||
|
||||
LLThread::~LLThread()
|
||||
{
|
||||
shutdown();
|
||||
|
||||
if(mLocalAPRFilePoolp)
|
||||
{
|
||||
delete mLocalAPRFilePoolp ;
|
||||
mLocalAPRFilePoolp = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
void LLThread::shutdown()
|
||||
|
|
@ -128,7 +143,7 @@ void LLThread::shutdown()
|
|||
if (!isStopped())
|
||||
{
|
||||
// This thread just wouldn't stop, even though we gave it time
|
||||
llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl;
|
||||
llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl;
|
||||
// Put a stake in its heart.
|
||||
apr_thread_exit(mAPRThreadp, -1);
|
||||
return;
|
||||
|
|
@ -138,8 +153,15 @@ void LLThread::shutdown()
|
|||
|
||||
delete mRunCondition;
|
||||
mRunCondition = 0;
|
||||
|
||||
if (mIsLocalPool && mAPRPoolp)
|
||||
{
|
||||
apr_pool_destroy(mAPRPoolp);
|
||||
mAPRPoolp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLThread::start()
|
||||
{
|
||||
llassert(isStopped());
|
||||
|
|
@ -148,7 +170,7 @@ void LLThread::start()
|
|||
mStatus = RUNNING;
|
||||
|
||||
apr_status_t status =
|
||||
apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool());
|
||||
apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
|
||||
|
||||
if(status == APR_SUCCESS)
|
||||
{
|
||||
|
|
@ -173,7 +195,7 @@ void LLThread::pause()
|
|||
if (!mPaused)
|
||||
{
|
||||
// this will cause the thread to stop execution as soon as checkPause() is called
|
||||
mPaused = true; // Does not need to be atomic since this is only set/unset from the main thread
|
||||
mPaused = 1; // Does not need to be atomic since this is only set/unset from the main thread
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +203,7 @@ void LLThread::unpause()
|
|||
{
|
||||
if (mPaused)
|
||||
{
|
||||
mPaused = false;
|
||||
mPaused = 0;
|
||||
}
|
||||
|
||||
wake(); // wake up the thread if necessary
|
||||
|
|
@ -258,76 +280,85 @@ void LLThread::wakeLocked()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread.
|
||||
static apr_os_thread_t main_thread_id;
|
||||
LL_COMMON_API bool is_main_thread(void) { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); }
|
||||
#endif
|
||||
//============================================================================
|
||||
|
||||
// The thread private handle to access the LLThreadLocalData instance.
|
||||
apr_threadkey_t* LLThreadLocalData::sThreadLocalDataKey;
|
||||
|
||||
//static
|
||||
void LLThreadLocalData::init(void)
|
||||
LLMutex::LLMutex(apr_pool_t *poolp) :
|
||||
mAPRMutexp(NULL)
|
||||
{
|
||||
// Only do this once.
|
||||
if (sThreadLocalDataKey)
|
||||
//if (poolp)
|
||||
//{
|
||||
// mIsLocalPool = FALSE;
|
||||
// mAPRPoolp = poolp;
|
||||
//}
|
||||
//else
|
||||
{
|
||||
return;
|
||||
mIsLocalPool = TRUE;
|
||||
apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
|
||||
}
|
||||
apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
|
||||
}
|
||||
|
||||
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}
|
||||
// has been exceeded.
|
||||
|
||||
// Create the thread-local data for the main thread (this function is called by the main thread).
|
||||
LLThreadLocalData::create(NULL);
|
||||
LLMutex::~LLMutex()
|
||||
{
|
||||
#if MUTEX_DEBUG
|
||||
llassert_always(!isLocked()); // better not be locked!
|
||||
#endif
|
||||
apr_thread_mutex_destroy(mAPRMutexp);
|
||||
mAPRMutexp = NULL;
|
||||
if (mIsLocalPool)
|
||||
{
|
||||
apr_pool_destroy(mAPRPoolp);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
// This function is called by the main thread.
|
||||
main_thread_id = apr_os_thread_current();
|
||||
|
||||
void LLMutex::lock()
|
||||
{
|
||||
apr_thread_mutex_lock(mAPRMutexp);
|
||||
#if MUTEX_DEBUG
|
||||
// Have to have the lock before we can access the debug info
|
||||
U32 id = LLThread::currentID();
|
||||
if (mIsLocked[id] != FALSE)
|
||||
llerrs << "Already locked in Thread: " << id << llendl;
|
||||
mIsLocked[id] = TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This is called once for every thread when the thread is destructed.
|
||||
//static
|
||||
void LLThreadLocalData::destroy(void* thread_local_data)
|
||||
void LLMutex::unlock()
|
||||
{
|
||||
delete static_cast<LLThreadLocalData*>(thread_local_data);
|
||||
#if MUTEX_DEBUG
|
||||
// Access the debug info while we have the lock
|
||||
U32 id = LLThread::currentID();
|
||||
if (mIsLocked[id] != TRUE)
|
||||
llerrs << "Not locked in Thread: " << id << llendl;
|
||||
mIsLocked[id] = FALSE;
|
||||
#endif
|
||||
apr_thread_mutex_unlock(mAPRMutexp);
|
||||
}
|
||||
|
||||
//static
|
||||
void LLThreadLocalData::create(LLThread* threadp)
|
||||
bool LLMutex::isLocked()
|
||||
{
|
||||
LLThreadLocalData* new_tld = new LLThreadLocalData;
|
||||
if (threadp)
|
||||
apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
|
||||
if (APR_STATUS_IS_EBUSY(status))
|
||||
{
|
||||
threadp->mThreadLocalData = new_tld;
|
||||
return true;
|
||||
}
|
||||
apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey);
|
||||
llassert_always(status == APR_SUCCESS);
|
||||
}
|
||||
|
||||
//static
|
||||
LLThreadLocalData& LLThreadLocalData::tldata(void)
|
||||
{
|
||||
if (!sThreadLocalDataKey)
|
||||
else
|
||||
{
|
||||
LLThreadLocalData::init();
|
||||
apr_thread_mutex_unlock(mAPRMutexp);
|
||||
return false;
|
||||
}
|
||||
|
||||
void* data;
|
||||
apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey);
|
||||
llassert_always(status == APR_SUCCESS);
|
||||
return *static_cast<LLThreadLocalData*>(data);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
LLCondition::LLCondition(LLAPRPool& parent) : LLMutex(parent)
|
||||
LLCondition::LLCondition(apr_pool_t *poolp) :
|
||||
LLMutex(poolp)
|
||||
{
|
||||
apr_thread_cond_create(&mAPRCondp, mPool());
|
||||
// base class (LLMutex) has already ensured that mAPRPoolp is set up.
|
||||
|
||||
apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -365,7 +396,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount()
|
|||
{
|
||||
if (!sMutex)
|
||||
{
|
||||
sMutex = new LLMutex;
|
||||
sMutex = new LLMutex(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,34 +29,12 @@
|
|||
|
||||
#include "llapp.h"
|
||||
#include "llapr.h"
|
||||
#include "llmemory.h"
|
||||
#include "apr_thread_cond.h"
|
||||
#include "llaprpool.h"
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
extern LL_COMMON_API bool is_main_thread(void);
|
||||
#endif
|
||||
|
||||
class LLThread;
|
||||
class LLMutex;
|
||||
class LLCondition;
|
||||
|
||||
class LL_COMMON_API LLThreadLocalData
|
||||
{
|
||||
private:
|
||||
static apr_threadkey_t* sThreadLocalDataKey;
|
||||
|
||||
public:
|
||||
// Thread-local memory pools.
|
||||
LLAPRRootPool mRootPool;
|
||||
LLVolatileAPRPool mVolatileAPRPool;
|
||||
|
||||
static void init(void);
|
||||
static void destroy(void* thread_local_data);
|
||||
static void create(LLThread* pthread);
|
||||
static LLThreadLocalData& tldata(void);
|
||||
};
|
||||
|
||||
class LL_COMMON_API LLThread
|
||||
{
|
||||
public:
|
||||
|
|
@ -67,7 +45,7 @@ public:
|
|||
QUITTING= 2 // Someone wants this thread to quit
|
||||
} EThreadStatus;
|
||||
|
||||
LLThread(std::string const& name);
|
||||
LLThread(const std::string& name, apr_pool_t *poolp = NULL);
|
||||
virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
|
||||
virtual void shutdown(); // stops the thread
|
||||
|
||||
|
|
@ -82,7 +60,7 @@ public:
|
|||
// Called from MAIN THREAD.
|
||||
void pause();
|
||||
void unpause();
|
||||
bool isPaused() { return isStopped() || mPaused; }
|
||||
bool isPaused() { return isStopped() || mPaused == TRUE; }
|
||||
|
||||
// Cause the thread to wake up and check its condition
|
||||
void wake();
|
||||
|
|
@ -96,11 +74,11 @@ public:
|
|||
// this kicks off the apr thread
|
||||
void start(void);
|
||||
|
||||
// Return thread-local data for the current thread.
|
||||
static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); }
|
||||
apr_pool_t *getAPRPool() { return mAPRPoolp; }
|
||||
LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
|
||||
|
||||
private:
|
||||
bool mPaused;
|
||||
BOOL mPaused;
|
||||
|
||||
// static function passed to APR thread creation routine
|
||||
static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap);
|
||||
|
|
@ -110,10 +88,14 @@ protected:
|
|||
LLCondition* mRunCondition;
|
||||
|
||||
apr_thread_t *mAPRThreadp;
|
||||
apr_pool_t *mAPRPoolp;
|
||||
BOOL mIsLocalPool;
|
||||
EThreadStatus mStatus;
|
||||
|
||||
friend void LLThreadLocalData::create(LLThread* threadp);
|
||||
LLThreadLocalData* mThreadLocalData;
|
||||
//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
|
||||
//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
|
||||
// otherwise it will cause severe memory leaking!!! --bao
|
||||
LLVolatileAPRPool *mLocalAPRFilePoolp ;
|
||||
|
||||
void setQuitting();
|
||||
|
||||
|
|
@ -143,80 +125,30 @@ protected:
|
|||
|
||||
#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
|
||||
|
||||
#ifdef MUTEX_DEBUG
|
||||
// We really shouldn't be using recursive locks. Make sure of that in debug mode.
|
||||
#define MUTEX_FLAG APR_THREAD_MUTEX_UNNESTED
|
||||
#else
|
||||
// Use the fastest platform-optimal lock behavior (can be recursive or non-recursive).
|
||||
#define MUTEX_FLAG APR_THREAD_MUTEX_DEFAULT
|
||||
class LL_COMMON_API LLMutex
|
||||
{
|
||||
public:
|
||||
LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
|
||||
virtual ~LLMutex();
|
||||
|
||||
void lock(); // blocks
|
||||
void unlock();
|
||||
bool isLocked(); // non-blocking, but does do a lock/unlock so not free
|
||||
|
||||
protected:
|
||||
apr_thread_mutex_t *mAPRMutexp;
|
||||
apr_pool_t *mAPRPoolp;
|
||||
BOOL mIsLocalPool;
|
||||
#if MUTEX_DEBUG
|
||||
std::map<U32, BOOL> mIsLocked;
|
||||
#endif
|
||||
|
||||
class LL_COMMON_API LLMutexBase
|
||||
{
|
||||
public:
|
||||
void lock() { apr_thread_mutex_lock(mAPRMutexp); }
|
||||
void unlock() { apr_thread_mutex_unlock(mAPRMutexp); }
|
||||
// Returns true if lock was obtained successfully.
|
||||
bool trylock() { return !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)); }
|
||||
|
||||
// non-blocking, but does do a lock/unlock so not free
|
||||
bool isLocked() { bool is_not_locked = trylock(); if (is_not_locked) unlock(); return !is_not_locked; }
|
||||
|
||||
protected:
|
||||
// mAPRMutexp is initialized and uninitialized in the derived class.
|
||||
apr_thread_mutex_t* mAPRMutexp;
|
||||
};
|
||||
|
||||
class LL_COMMON_API LLMutex : public LLMutexBase
|
||||
{
|
||||
public:
|
||||
LLMutex(LLAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent)
|
||||
{
|
||||
apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mPool());
|
||||
}
|
||||
~LLMutex()
|
||||
{
|
||||
llassert(!isLocked()); // better not be locked!
|
||||
apr_thread_mutex_destroy(mAPRMutexp);
|
||||
mAPRMutexp = NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
LLAPRPool mPool;
|
||||
};
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
// No need to use a root pool in this case.
|
||||
typedef LLMutex LLMutexRootPool;
|
||||
#else // APR_HAS_THREADS
|
||||
class LL_COMMON_API LLMutexRootPool : public LLMutexBase
|
||||
{
|
||||
public:
|
||||
LLMutexRootPool(void)
|
||||
{
|
||||
apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mRootPool());
|
||||
}
|
||||
~LLMutexRootPool()
|
||||
{
|
||||
#if APR_POOL_DEBUG
|
||||
// It is allowed to destruct root pools from a different thread.
|
||||
mRootPool.grab_ownership();
|
||||
#endif
|
||||
llassert(!isLocked());
|
||||
apr_thread_mutex_destroy(mAPRMutexp);
|
||||
mAPRMutexp = NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
LLAPRRootPool mRootPool;
|
||||
};
|
||||
#endif // APR_HAS_THREADS
|
||||
|
||||
// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
|
||||
class LL_COMMON_API LLCondition : public LLMutex
|
||||
{
|
||||
public:
|
||||
LLCondition(LLAPRPool& parent = LLThread::tldata().mRootPool);
|
||||
LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well.
|
||||
~LLCondition();
|
||||
|
||||
void wait(); // blocks
|
||||
|
|
@ -227,10 +159,10 @@ protected:
|
|||
apr_thread_cond_t *mAPRCondp;
|
||||
};
|
||||
|
||||
class LL_COMMON_API LLMutexLock
|
||||
class LLMutexLock
|
||||
{
|
||||
public:
|
||||
LLMutexLock(LLMutexBase* mutex)
|
||||
LLMutexLock(LLMutex* mutex)
|
||||
{
|
||||
mMutex = mutex;
|
||||
mMutex->lock();
|
||||
|
|
@ -240,7 +172,7 @@ public:
|
|||
mMutex->unlock();
|
||||
}
|
||||
private:
|
||||
LLMutexBase* mMutex;
|
||||
LLMutex* mMutex;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -34,11 +34,19 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(unsigned int capacity):
|
||||
LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity):
|
||||
mOwnsPool(pool == 0),
|
||||
mPool(pool),
|
||||
mQueue(0)
|
||||
{
|
||||
mPool.create();
|
||||
apr_status_t status = apr_queue_create(&mQueue, capacity, mPool());
|
||||
if(mOwnsPool) {
|
||||
apr_status_t status = apr_pool_create(&mPool, 0);
|
||||
if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool");
|
||||
} else {
|
||||
; // No op.
|
||||
}
|
||||
|
||||
apr_status_t status = apr_queue_create(&mQueue, capacity, mPool);
|
||||
if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue");
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +59,7 @@ LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
|
|||
" elements;" << "memory will be leaked" << LL_ENDL;
|
||||
apr_queue_term(mQueue);
|
||||
}
|
||||
if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@
|
|||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include "llaprpool.h"
|
||||
|
||||
|
||||
struct apr_pool_t; // From apr_pools.h
|
||||
class LLThreadSafeQueueImplementation; // See below.
|
||||
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ struct apr_queue_t; // From apr_queue.h
|
|||
class LL_COMMON_API LLThreadSafeQueueImplementation
|
||||
{
|
||||
public:
|
||||
LLThreadSafeQueueImplementation(unsigned int capacity);
|
||||
LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
|
||||
~LLThreadSafeQueueImplementation();
|
||||
void pushFront(void * element);
|
||||
bool tryPushFront(void * element);
|
||||
|
|
@ -84,7 +84,8 @@ public:
|
|||
size_t size();
|
||||
|
||||
private:
|
||||
LLAPRPool mPool; // The pool used for mQueue.
|
||||
bool mOwnsPool;
|
||||
apr_pool_t * mPool;
|
||||
apr_queue_t * mQueue;
|
||||
};
|
||||
|
||||
|
|
@ -98,8 +99,9 @@ class LLThreadSafeQueue
|
|||
public:
|
||||
typedef ElementT value_type;
|
||||
|
||||
// Constructor.
|
||||
LLThreadSafeQueue(unsigned int capacity = 1024);
|
||||
// If the pool is set to NULL one will be allocated and managed by this
|
||||
// queue.
|
||||
LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024);
|
||||
|
||||
// Add an element to the front of queue (will block if the queue has
|
||||
// reached capacity).
|
||||
|
|
@ -137,8 +139,8 @@ private:
|
|||
|
||||
|
||||
template<typename ElementT>
|
||||
LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(unsigned int capacity) :
|
||||
mImplementation(capacity)
|
||||
LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity):
|
||||
mImplementation(pool, capacity)
|
||||
{
|
||||
; // No op.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,12 @@
|
|||
LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) :
|
||||
LLQueuedThread(name, threaded)
|
||||
{
|
||||
mDeleteMutex = new LLMutex;
|
||||
mDeleteMutex = new LLMutex(NULL);
|
||||
|
||||
if(!mLocalAPRFilePoolp)
|
||||
{
|
||||
mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
|
||||
}
|
||||
}
|
||||
|
||||
LLWorkerThread::~LLWorkerThread()
|
||||
|
|
@ -199,6 +204,7 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
|
|||
mWorkerClassName(name),
|
||||
mRequestHandle(LLWorkerThread::nullHandle()),
|
||||
mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
|
||||
mMutex(NULL),
|
||||
mWorkFlags(0)
|
||||
{
|
||||
if (!mWorkerThread)
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ public:
|
|||
|
||||
private:
|
||||
void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
|
||||
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -193,7 +194,7 @@ protected:
|
|||
U32 mRequestPriority; // last priority set
|
||||
|
||||
private:
|
||||
LLMutexRootPool mMutex; // Use LLMutexRootPool since this object is created and destructed by multiple threads.
|
||||
LLMutex mMutex;
|
||||
LLAtomicU32 mWorkFlags;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -390,7 +390,8 @@ bool LLCrashLogger::init()
|
|||
return false;
|
||||
}
|
||||
|
||||
gServicePump = new LLPumpIO;
|
||||
gServicePump = new LLPumpIO(gAPRPoolp);
|
||||
gServicePump->prime(gAPRPoolp);
|
||||
LLHTTPClient::setPump(*gServicePump);
|
||||
|
||||
//If we've opened the crash logger, assume we can delete the marker file if it exists
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ LLMutex* LLImage::sMutex = NULL;
|
|||
//static
|
||||
void LLImage::initClass()
|
||||
{
|
||||
sMutex = new LLMutex;
|
||||
sMutex = new LLMutex(NULL);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -1557,7 +1557,8 @@ BOOL LLImageFormatted::load(const std::string &filename)
|
|||
resetLastError();
|
||||
|
||||
S32 file_size = 0;
|
||||
LLAPRFile infile(filename, LL_APR_RB, &file_size);
|
||||
LLAPRFile infile ;
|
||||
infile.open(filename, LL_APR_RB, NULL, &file_size);
|
||||
apr_file_t* apr_file = infile.getFileHandle();
|
||||
if (!apr_file)
|
||||
{
|
||||
|
|
@ -1592,7 +1593,8 @@ BOOL LLImageFormatted::save(const std::string &filename)
|
|||
{
|
||||
resetLastError();
|
||||
|
||||
LLAPRFile outfile(filename, LL_APR_WB);
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(filename, LL_APR_WB);
|
||||
if (!outfile.getFileHandle())
|
||||
{
|
||||
setLastError("Unable to open file for writing", filename);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
|
|||
mSrcFilename = src_filename;
|
||||
|
||||
S32 file_size = 0;
|
||||
apr_status_t s = mInfile.open(src_filename, LL_APR_RB, LLAPRFile::long_lived, &file_size);
|
||||
apr_status_t s = mInfile.open(src_filename, LL_APR_RB, NULL, &file_size);
|
||||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -358,7 +358,8 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
|
|||
resetLastError();
|
||||
|
||||
S32 file_size = 0;
|
||||
LLAPRFile infile(filename, LL_APR_RB, &file_size);
|
||||
LLAPRFile infile ;
|
||||
infile.open(filename, LL_APR_RB, NULL, &file_size);
|
||||
apr_file_t* apr_file = infile.getFileHandle() ;
|
||||
if (!apr_file)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,18 +35,20 @@
|
|||
LLImageDecodeThread::LLImageDecodeThread(bool threaded)
|
||||
: LLQueuedThread("imagedecode", threaded)
|
||||
{
|
||||
mCreationMutex = new LLMutex(getAPRPool());
|
||||
}
|
||||
|
||||
//virtual
|
||||
LLImageDecodeThread::~LLImageDecodeThread()
|
||||
{
|
||||
delete mCreationMutex ;
|
||||
}
|
||||
|
||||
// MAIN THREAD
|
||||
// virtual
|
||||
S32 LLImageDecodeThread::update(U32 max_time_ms)
|
||||
{
|
||||
LLMutexLock lock(&mCreationMutex);
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
for (creation_list_t::iterator iter = mCreationList.begin();
|
||||
iter != mCreationList.end(); ++iter)
|
||||
{
|
||||
|
|
@ -69,7 +71,7 @@ S32 LLImageDecodeThread::update(U32 max_time_ms)
|
|||
LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
|
||||
{
|
||||
LLMutexLock lock(&mCreationMutex);
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
handle_t handle = generateHandle();
|
||||
mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
|
||||
return handle;
|
||||
|
|
@ -79,7 +81,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted*
|
|||
// Returns the size of the mutex guarded list as an indication of sanity
|
||||
S32 LLImageDecodeThread::tut_size()
|
||||
{
|
||||
LLMutexLock lock(&mCreationMutex);
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
S32 res = mCreationList.size();
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ private:
|
|||
};
|
||||
typedef std::list<creation_info> creation_list_t;
|
||||
creation_list_t mCreationList;
|
||||
LLMutex mCreationMutex;
|
||||
LLMutex* mCreationMutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ LLVolumeMgr::LLVolumeMgr()
|
|||
{
|
||||
// the LLMutex magic interferes with easy unit testing,
|
||||
// so you now must manually call useMutex() to use it
|
||||
//mDataMutex = new LLMutex;
|
||||
//mDataMutex = new LLMutex(gAPRPoolp);
|
||||
}
|
||||
|
||||
LLVolumeMgr::~LLVolumeMgr()
|
||||
|
|
@ -216,7 +216,7 @@ void LLVolumeMgr::useMutex()
|
|||
{
|
||||
if (!mDataMutex)
|
||||
{
|
||||
mDataMutex = new LLMutex;
|
||||
mDataMutex = new LLMutex(gAPRPoolp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
#include "llares.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
|
||||
#include <ares_dns.h>
|
||||
#include <ares_version.h>
|
||||
|
|
@ -465,6 +464,11 @@ void LLAres::search(const std::string &query, LLResType type,
|
|||
|
||||
bool LLAres::process(U64 timeout)
|
||||
{
|
||||
if (!gAPRPoolp)
|
||||
{
|
||||
ll_init_apr();
|
||||
}
|
||||
|
||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||
apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];
|
||||
apr_int32_t nsds = 0;
|
||||
|
|
@ -478,7 +482,10 @@ bool LLAres::process(U64 timeout)
|
|||
return nsds > 0;
|
||||
}
|
||||
|
||||
LLScopedVolatileAPRPool scoped_pool;
|
||||
apr_status_t status;
|
||||
LLAPRPool pool;
|
||||
status = pool.getStatus() ;
|
||||
ll_apr_assert_status(status);
|
||||
|
||||
for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++)
|
||||
{
|
||||
|
|
@ -495,7 +502,7 @@ bool LLAres::process(U64 timeout)
|
|||
|
||||
apr_socket_t *aprSock = NULL;
|
||||
|
||||
apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool);
|
||||
status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool());
|
||||
if (status != APR_SUCCESS)
|
||||
{
|
||||
ll_apr_warn_status(status);
|
||||
|
|
@ -504,7 +511,7 @@ bool LLAres::process(U64 timeout)
|
|||
|
||||
aprFds[nactive].desc.s = aprSock;
|
||||
aprFds[nactive].desc_type = APR_POLL_SOCKET;
|
||||
aprFds[nactive].p = scoped_pool;
|
||||
aprFds[nactive].p = pool.getAPRPool();
|
||||
aprFds[nactive].rtnevents = 0;
|
||||
aprFds[nactive].client_data = &socks[i];
|
||||
|
||||
|
|
@ -513,7 +520,7 @@ bool LLAres::process(U64 timeout)
|
|||
|
||||
if (nactive > 0)
|
||||
{
|
||||
apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout);
|
||||
status = apr_poll(aprFds, nactive, &nsds, timeout);
|
||||
|
||||
if (status != APR_SUCCESS && status != APR_TIMEUP)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1039,7 +1039,7 @@ void LLCurl::initClass()
|
|||
S32 mutex_count = CRYPTO_num_locks();
|
||||
for (S32 i=0; i<mutex_count; i++)
|
||||
{
|
||||
sSSLMutex.push_back(new LLMutex);
|
||||
sSSLMutex.push_back(new LLMutex(NULL));
|
||||
}
|
||||
CRYPTO_set_id_callback(&LLCurl::ssl_thread_id);
|
||||
CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback);
|
||||
|
|
|
|||
|
|
@ -954,9 +954,13 @@ private:
|
|||
|
||||
|
||||
// static
|
||||
LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)
|
||||
LLHTTPNode& LLIOHTTPServer::create(
|
||||
apr_pool_t* pool, LLPumpIO& pump, U16 port)
|
||||
{
|
||||
LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port);
|
||||
LLSocket::ptr_t socket = LLSocket::create(
|
||||
pool,
|
||||
LLSocket::STREAM_TCP,
|
||||
port);
|
||||
if(!socket)
|
||||
{
|
||||
llerrs << "Unable to initialize socket" << llendl;
|
||||
|
|
@ -965,7 +969,7 @@ LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port)
|
|||
LLHTTPResponseFactory* factory = new LLHTTPResponseFactory;
|
||||
boost::shared_ptr<LLChainIOFactory> factory_ptr(factory);
|
||||
|
||||
LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr);
|
||||
LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr);
|
||||
|
||||
LLPumpIO::chain_t chain;
|
||||
chain.push_back(LLIOPipe::ptr_t(server));
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class LLIOHTTPServer
|
|||
public:
|
||||
typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data);
|
||||
|
||||
static LLHTTPNode& create(LLPumpIO& pump, U16 port);
|
||||
static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port);
|
||||
/**< Creates an HTTP wire server on the pump for the given TCP port.
|
||||
*
|
||||
* Returns the root node of the new server. Add LLHTTPNode instances
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
#include "llhost.h"
|
||||
#include "llmemtype.h"
|
||||
#include "llpumpio.h"
|
||||
#include "llthread.h"
|
||||
|
||||
//
|
||||
// constants
|
||||
|
|
@ -99,31 +98,51 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock)
|
|||
///
|
||||
|
||||
// static
|
||||
LLSocket::ptr_t LLSocket::create(EType type, U16 port)
|
||||
LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_TCP);
|
||||
LLSocket::ptr_t rv;
|
||||
apr_socket_t* socket = NULL;
|
||||
apr_pool_t* new_pool = NULL;
|
||||
apr_status_t status = APR_EGENERAL;
|
||||
LLSocket::ptr_t rv(new LLSocket);
|
||||
|
||||
// create a pool for the socket
|
||||
status = apr_pool_create(&new_pool, pool);
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
if(new_pool) apr_pool_destroy(new_pool);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if(STREAM_TCP == type)
|
||||
{
|
||||
status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool());
|
||||
status = apr_socket_create(
|
||||
&socket,
|
||||
APR_INET,
|
||||
SOCK_STREAM,
|
||||
APR_PROTO_TCP,
|
||||
new_pool);
|
||||
}
|
||||
else if(DATAGRAM_UDP == type)
|
||||
{
|
||||
status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool());
|
||||
status = apr_socket_create(
|
||||
&socket,
|
||||
APR_INET,
|
||||
SOCK_DGRAM,
|
||||
APR_PROTO_UDP,
|
||||
new_pool);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv.reset();
|
||||
if(new_pool) apr_pool_destroy(new_pool);
|
||||
return rv;
|
||||
}
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
rv->mSocket = NULL;
|
||||
rv.reset();
|
||||
if(new_pool) apr_pool_destroy(new_pool);
|
||||
return rv;
|
||||
}
|
||||
rv = ptr_t(new LLSocket(socket, new_pool));
|
||||
if(port > 0)
|
||||
{
|
||||
apr_sockaddr_t* sa = NULL;
|
||||
|
|
@ -133,7 +152,7 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)
|
|||
APR_UNSPEC,
|
||||
port,
|
||||
0,
|
||||
rv->mPool());
|
||||
new_pool);
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
rv.reset();
|
||||
|
|
@ -141,8 +160,8 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)
|
|||
}
|
||||
// This allows us to reuse the address on quick down/up. This
|
||||
// is unlikely to create problems.
|
||||
ll_apr_warn_status(apr_socket_opt_set(rv->mSocket, APR_SO_REUSEADDR, 1));
|
||||
status = apr_socket_bind(rv->mSocket, sa);
|
||||
ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1));
|
||||
status = apr_socket_bind(socket, sa);
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
rv.reset();
|
||||
|
|
@ -156,7 +175,7 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)
|
|||
// to keep a queue of incoming connections for ACCEPT.
|
||||
lldebugs << "Setting listen state for socket." << llendl;
|
||||
status = apr_socket_listen(
|
||||
rv->mSocket,
|
||||
socket,
|
||||
LL_DEFAULT_LISTEN_BACKLOG);
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
|
|
@ -177,28 +196,21 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port)
|
|||
}
|
||||
|
||||
// static
|
||||
LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket)
|
||||
LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_TCP);
|
||||
if (!listen_socket->getSocket())
|
||||
LLSocket::ptr_t rv;
|
||||
if(!socket)
|
||||
{
|
||||
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;
|
||||
|
|
@ -211,7 +223,7 @@ bool LLSocket::blockingConnect(const LLHost& host)
|
|||
APR_UNSPEC,
|
||||
host.getPort(),
|
||||
0,
|
||||
mPool())))
|
||||
mPool)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -222,11 +234,13 @@ bool LLSocket::blockingConnect(const LLHost& host)
|
|||
return true;
|
||||
}
|
||||
|
||||
LLSocket::LLSocket() :
|
||||
mSocket(NULL),
|
||||
mPool(LLThread::tldata().mRootPool),
|
||||
LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) :
|
||||
mSocket(socket),
|
||||
mPool(pool),
|
||||
mPort(PORT_INVALID)
|
||||
{
|
||||
ll_debug_socket("Constructing wholely formed socket", mSocket);
|
||||
LLMemType m1(LLMemType::MTYPE_IO_TCP);
|
||||
}
|
||||
|
||||
LLSocket::~LLSocket()
|
||||
|
|
@ -238,6 +252,10 @@ LLSocket::~LLSocket()
|
|||
ll_debug_socket("Destroying socket", mSocket);
|
||||
apr_socket_close(mSocket);
|
||||
}
|
||||
if(mPool)
|
||||
{
|
||||
apr_pool_destroy(mPool);
|
||||
}
|
||||
}
|
||||
|
||||
void LLSocket::setOptions()
|
||||
|
|
@ -498,8 +516,10 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
|
|||
///
|
||||
|
||||
LLIOServerSocket::LLIOServerSocket(
|
||||
apr_pool_t* pool,
|
||||
LLIOServerSocket::socket_t listener,
|
||||
factory_t factory) :
|
||||
mPool(pool),
|
||||
mListenSocket(listener),
|
||||
mReactor(factory),
|
||||
mInitialized(false),
|
||||
|
|
@ -559,15 +579,21 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
|
|||
lldebugs << "accepting socket" << llendl;
|
||||
|
||||
PUMP_DEBUG;
|
||||
apr_status_t status;
|
||||
LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket));
|
||||
apr_pool_t* new_pool = NULL;
|
||||
apr_status_t status = apr_pool_create(&new_pool, mPool);
|
||||
apr_socket_t* socket = NULL;
|
||||
status = apr_socket_accept(
|
||||
&socket,
|
||||
mListenSocket->getSocket(),
|
||||
new_pool);
|
||||
LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool));
|
||||
//EStatus rv = STATUS_ERROR;
|
||||
if(llsocket && status == APR_SUCCESS)
|
||||
if(llsocket)
|
||||
{
|
||||
PUMP_DEBUG;
|
||||
|
||||
apr_sockaddr_t* remote_addr;
|
||||
apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket());
|
||||
apr_socket_addr_get(&remote_addr, APR_REMOTE, socket);
|
||||
|
||||
char* remote_host_string;
|
||||
apr_sockaddr_ip_get(&remote_host_string, remote_addr);
|
||||
|
|
@ -582,6 +608,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
|
|||
{
|
||||
chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));
|
||||
pump->addChain(chain, mResponseTimeout);
|
||||
status = STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -590,8 +617,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
|
|||
}
|
||||
else
|
||||
{
|
||||
char buf[256];
|
||||
llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl;
|
||||
llwarns << "Unable to create linden socket." << llendl;
|
||||
}
|
||||
|
||||
PUMP_DEBUG;
|
||||
|
|
@ -604,10 +630,11 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
|
|||
#if 0
|
||||
LLIODataSocket::LLIODataSocket(
|
||||
U16 suggested_port,
|
||||
U16 start_discovery_port) :
|
||||
U16 start_discovery_port,
|
||||
apr_pool_t* pool) :
|
||||
mSocket(NULL)
|
||||
{
|
||||
if(PORT_INVALID == suggested_port) return;
|
||||
if(!pool || (PORT_INVALID == suggested_port)) return;
|
||||
if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return;
|
||||
apr_sockaddr_t* sa = NULL;
|
||||
if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
*/
|
||||
|
||||
#include "lliopipe.h"
|
||||
#include "apr_pools.h"
|
||||
#include "apr_network_io.h"
|
||||
#include "llchainio.h"
|
||||
|
||||
|
|
@ -87,22 +88,34 @@ public:
|
|||
* socket. If you intend the socket to be known to external
|
||||
* clients without prior port notification, do not use
|
||||
* PORT_EPHEMERAL.
|
||||
* @param pool The apr pool to use. A child pool will be created
|
||||
* and associated with the socket.
|
||||
* @param type The type of socket to create
|
||||
* @param port The port for the socket
|
||||
* @return A valid socket shared pointer if the call worked.
|
||||
*/
|
||||
static ptr_t create(
|
||||
apr_pool_t* pool,
|
||||
EType type,
|
||||
U16 port = PORT_EPHEMERAL);
|
||||
|
||||
/**
|
||||
* @brief Create a LLSocket by accepting a connection from a listen socket.
|
||||
* @brief Create a LLSocket when you already have an apr socket.
|
||||
*
|
||||
* @param status Output. Status of the accept if a valid listen socket was passed.
|
||||
* @param listen_socket The listen socket to use.
|
||||
* This method assumes an ephemeral port. This is typically used
|
||||
* by calls which spawn a socket such as a call to
|
||||
* <code>accept()</code> as in the server socket. This call should
|
||||
* not fail if you have a valid apr socket.
|
||||
* Because of the nature of how accept() works, you are expected
|
||||
* to create a new pool for the socket, use that pool for the
|
||||
* accept, and pass it in here where it will be bound with the
|
||||
* socket and destroyed at the same time.
|
||||
* @param socket The apr socket to use
|
||||
* @param pool The pool used to create the socket. *NOTE: The pool
|
||||
* passed in will be DESTROYED.
|
||||
* @return A valid socket shared pointer if the call worked.
|
||||
*/
|
||||
static ptr_t create(apr_status_t& status, ptr_t& listen_socket);
|
||||
static ptr_t create(apr_socket_t* socket, apr_pool_t* pool);
|
||||
|
||||
/**
|
||||
* @brief Perform a blocking connect to a host. Do not use in production.
|
||||
|
|
@ -137,7 +150,7 @@ protected:
|
|||
* @brief Protected constructor since should only make sockets
|
||||
* with one of the two <code>create()</code> calls.
|
||||
*/
|
||||
LLSocket(void);
|
||||
LLSocket(apr_socket_t* socket, apr_pool_t* pool);
|
||||
|
||||
/**
|
||||
* @brief Set default socket options.
|
||||
|
|
@ -154,8 +167,8 @@ protected:
|
|||
// The apr socket.
|
||||
apr_socket_t* mSocket;
|
||||
|
||||
// Our memory pool.
|
||||
LLAPRPool mPool;
|
||||
// our memory pool
|
||||
apr_pool_t* mPool;
|
||||
|
||||
// The port if we know it.
|
||||
U16 mPort;
|
||||
|
|
@ -280,7 +293,7 @@ class LLIOServerSocket : public LLIOPipe
|
|||
public:
|
||||
typedef LLSocket::ptr_t socket_t;
|
||||
typedef boost::shared_ptr<LLChainIOFactory> factory_t;
|
||||
LLIOServerSocket(socket_t listener, factory_t reactor);
|
||||
LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor);
|
||||
virtual ~LLIOServerSocket();
|
||||
|
||||
/**
|
||||
|
|
@ -312,6 +325,7 @@ protected:
|
|||
//@}
|
||||
|
||||
protected:
|
||||
apr_pool_t* mPool;
|
||||
socket_t mListenSocket;
|
||||
factory_t mReactor;
|
||||
bool mInitialized;
|
||||
|
|
@ -345,7 +359,8 @@ public:
|
|||
*/
|
||||
LLIODataSocket(
|
||||
U16 suggested_port,
|
||||
U16 start_discovery_port);
|
||||
U16 start_discovery_port,
|
||||
apr_pool_t* pool);
|
||||
virtual ~LLIODataSocket();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@
|
|||
#include "llstring.h"
|
||||
#include "lluuid.h"
|
||||
#include "net.h"
|
||||
#include "llaprpool.h"
|
||||
|
||||
//
|
||||
// constants
|
||||
|
|
@ -58,7 +57,7 @@
|
|||
const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
|
||||
|
||||
static bool gMailEnabled = true;
|
||||
static LLAPRPool gMailPool;
|
||||
static apr_pool_t* gMailPool;
|
||||
static apr_sockaddr_t* gSockAddr;
|
||||
static apr_socket_t* gMailSocket;
|
||||
|
||||
|
|
@ -83,7 +82,7 @@ bool connect_smtp()
|
|||
gSockAddr->sa.sin.sin_family,
|
||||
SOCK_STREAM,
|
||||
APR_PROTO_TCP,
|
||||
gMailPool());
|
||||
gMailPool);
|
||||
if(ll_apr_warn_status(status)) return false;
|
||||
status = apr_socket_connect(gMailSocket, gSockAddr);
|
||||
if(ll_apr_warn_status(status))
|
||||
|
|
@ -140,19 +139,19 @@ BOOL LLMail::send(
|
|||
}
|
||||
|
||||
// static
|
||||
void LLMail::init(const std::string& hostname)
|
||||
void LLMail::init(const std::string& hostname, apr_pool_t* pool)
|
||||
{
|
||||
gMailSocket = NULL;
|
||||
if (hostname.empty())
|
||||
if(hostname.empty() || !pool)
|
||||
{
|
||||
gMailPool = NULL;
|
||||
gSockAddr = NULL;
|
||||
gMailPool.destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
gMailPool.create();
|
||||
gMailPool = pool;
|
||||
|
||||
// Collect all the information into a sockaddr structure. the
|
||||
// collect all the information into a socaddr sturcture. the
|
||||
// documentation is a bit unclear, but I either have to
|
||||
// specify APR_UNSPEC or not specify any flags. I am not sure
|
||||
// which option is better.
|
||||
|
|
@ -162,7 +161,7 @@ void LLMail::init(const std::string& hostname)
|
|||
APR_UNSPEC,
|
||||
25,
|
||||
APR_IPV4_ADDR_OK,
|
||||
gMailPool());
|
||||
gMailPool);
|
||||
ll_apr_warn_status(status);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,15 @@
|
|||
#ifndef LL_LLMAIL_H
|
||||
#define LL_LLMAIL_H
|
||||
|
||||
typedef struct apr_pool_t apr_pool_t;
|
||||
|
||||
#include "llsd.h"
|
||||
|
||||
class LLMail
|
||||
{
|
||||
public:
|
||||
// if hostname is NULL, then the host is resolved as 'mail'
|
||||
static void init(const std::string& hostname);
|
||||
static void init(const std::string& hostname, apr_pool_t* pool);
|
||||
|
||||
// Allow all email transmission to be disabled/enabled.
|
||||
static void enable(bool mail_enabled);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#include "llmemtype.h"
|
||||
#include "llstl.h"
|
||||
#include "llstat.h"
|
||||
#include "llthread.h"
|
||||
|
||||
// These should not be enabled in production, but they can be
|
||||
// intensely useful during development for finding certain kinds of
|
||||
|
|
@ -163,12 +162,14 @@ struct ll_delete_apr_pollset_fd_client_data
|
|||
/**
|
||||
* LLPumpIO
|
||||
*/
|
||||
LLPumpIO::LLPumpIO(void) :
|
||||
LLPumpIO::LLPumpIO(apr_pool_t* pool) :
|
||||
mState(LLPumpIO::NORMAL),
|
||||
mRebuildPollset(false),
|
||||
mPollset(NULL),
|
||||
mPollsetClientID(0),
|
||||
mNextLock(0),
|
||||
mPool(NULL),
|
||||
mCurrentPool(NULL),
|
||||
mCurrentPoolReallocCount(0),
|
||||
mChainsMutex(NULL),
|
||||
mCallbackMutex(NULL),
|
||||
|
|
@ -177,24 +178,21 @@ LLPumpIO::LLPumpIO(void) :
|
|||
mCurrentChain = mRunningChains.end();
|
||||
|
||||
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
|
||||
initialize();
|
||||
initialize(pool);
|
||||
}
|
||||
|
||||
LLPumpIO::~LLPumpIO()
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
|
||||
#if LL_THREADS_APR
|
||||
if (mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
|
||||
if (mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
|
||||
#endif
|
||||
mChainsMutex = NULL;
|
||||
mCallbackMutex = NULL;
|
||||
if(mPollset)
|
||||
{
|
||||
// lldebugs << "cleaning up pollset" << llendl;
|
||||
apr_pollset_destroy(mPollset);
|
||||
mPollset = NULL;
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
bool LLPumpIO::prime(apr_pool_t* pool)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
|
||||
cleanup();
|
||||
initialize(pool);
|
||||
return ((pool == NULL) ? false : true);
|
||||
}
|
||||
|
||||
bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
|
||||
|
|
@ -354,7 +352,8 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll)
|
|||
{
|
||||
// each fd needs a pool to work with, so if one was
|
||||
// not specified, use this pool.
|
||||
value.second.p = (*mCurrentChain).mDescriptorsPool->operator()();
|
||||
// *FIX: Should it always be this pool?
|
||||
value.second.p = mPool;
|
||||
}
|
||||
value.second.client_data = new S32(++mPollsetClientID);
|
||||
(*mCurrentChain).mDescriptors.push_back(value);
|
||||
|
|
@ -826,15 +825,39 @@ void LLPumpIO::control(LLPumpIO::EControl op)
|
|||
}
|
||||
}
|
||||
|
||||
void LLPumpIO::initialize(void)
|
||||
void LLPumpIO::initialize(apr_pool_t* pool)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
|
||||
mPool.create();
|
||||
if(!pool) return;
|
||||
#if LL_THREADS_APR
|
||||
// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
|
||||
apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
|
||||
apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool());
|
||||
apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
|
||||
apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
|
||||
#endif
|
||||
mPool = pool;
|
||||
}
|
||||
|
||||
void LLPumpIO::cleanup()
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
|
||||
#if LL_THREADS_APR
|
||||
if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
|
||||
if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
|
||||
#endif
|
||||
mChainsMutex = NULL;
|
||||
mCallbackMutex = NULL;
|
||||
if(mPollset)
|
||||
{
|
||||
// lldebugs << "cleaning up pollset" << llendl;
|
||||
apr_pollset_destroy(mPollset);
|
||||
mPollset = NULL;
|
||||
}
|
||||
if(mCurrentPool)
|
||||
{
|
||||
apr_pool_destroy(mCurrentPool);
|
||||
mCurrentPool = NULL;
|
||||
}
|
||||
mPool = NULL;
|
||||
}
|
||||
|
||||
void LLPumpIO::rebuildPollset()
|
||||
|
|
@ -862,19 +885,21 @@ void LLPumpIO::rebuildPollset()
|
|||
if(mCurrentPool
|
||||
&& (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT)))
|
||||
{
|
||||
mCurrentPool.destroy();
|
||||
apr_pool_destroy(mCurrentPool);
|
||||
mCurrentPool = NULL;
|
||||
mCurrentPoolReallocCount = 0;
|
||||
}
|
||||
if(!mCurrentPool)
|
||||
{
|
||||
mCurrentPool.create(mPool);
|
||||
apr_status_t status = apr_pool_create(&mCurrentPool, mPool);
|
||||
(void)ll_apr_warn_status(status);
|
||||
}
|
||||
|
||||
// add all of the file descriptors
|
||||
run_it = mRunningChains.begin();
|
||||
LLChainInfo::conditionals_t::iterator fd_it;
|
||||
LLChainInfo::conditionals_t::iterator fd_end;
|
||||
apr_pollset_create(&mPollset, size, mCurrentPool(), 0);
|
||||
apr_pollset_create(&mPollset, size, mCurrentPool, 0);
|
||||
for(; run_it != run_end; ++run_it)
|
||||
{
|
||||
fd_it = (*run_it).mDescriptors.begin();
|
||||
|
|
@ -1132,8 +1157,7 @@ bool LLPumpIO::handleChainError(
|
|||
LLPumpIO::LLChainInfo::LLChainInfo() :
|
||||
mInit(false),
|
||||
mLock(0),
|
||||
mEOS(false),
|
||||
mDescriptorsPool(new LLAPRPool(LLThread::tldata().mRootPool))
|
||||
mEOS(false)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
|
||||
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
|
||||
|
|
|
|||
|
|
@ -30,12 +30,11 @@
|
|||
#define LL_LLPUMPIO_H
|
||||
|
||||
#include <set>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#if LL_LINUX // needed for PATH_MAX in APR.
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include "llaprpool.h"
|
||||
#include "apr_pools.h"
|
||||
#include "llbuffer.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lliopipe.h"
|
||||
|
|
@ -59,8 +58,9 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS;
|
|||
* <code>pump()</code> on a thread used for IO and call
|
||||
* <code>respond()</code> on a thread that is expected to do higher
|
||||
* level processing. You can call almost any other method from any
|
||||
* thread - see notes for each method for details.
|
||||
*
|
||||
* thread - see notes for each method for details. In order for the
|
||||
* threading abstraction to work, you need to call <code>prime()</code>
|
||||
* with a valid apr pool.
|
||||
* A pump instance manages much of the state for the pipe, including
|
||||
* the list of pipes in the chain, the channel for each element in the
|
||||
* chain, the buffer, and if any pipe has marked the stream or process
|
||||
|
|
@ -79,13 +79,24 @@ public:
|
|||
/**
|
||||
* @brief Constructor.
|
||||
*/
|
||||
LLPumpIO(void);
|
||||
LLPumpIO(apr_pool_t* pool);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
|
@ -357,7 +368,6 @@ protected:
|
|||
typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t;
|
||||
typedef std::vector<pipe_conditional_t> conditionals_t;
|
||||
conditionals_t mDescriptors;
|
||||
boost::shared_ptr<LLAPRPool> mDescriptorsPool;
|
||||
};
|
||||
|
||||
// All the running chains & info
|
||||
|
|
@ -376,9 +386,9 @@ protected:
|
|||
callbacks_t mPendingCallbacks;
|
||||
callbacks_t mCallbacks;
|
||||
|
||||
// Memory pool for pollsets & mutexes.
|
||||
LLAPRPool mPool;
|
||||
LLAPRPool mCurrentPool;
|
||||
// memory allocator for pollsets & mutexes.
|
||||
apr_pool_t* mPool;
|
||||
apr_pool_t* mCurrentPool;
|
||||
S32 mCurrentPoolReallocCount;
|
||||
|
||||
#if LL_THREADS_APR
|
||||
|
|
@ -390,7 +400,8 @@ protected:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
void initialize();
|
||||
void initialize(apr_pool_t* pool);
|
||||
void cleanup();
|
||||
|
||||
/**
|
||||
* @brief Given the internal state of the chains, rebuild the pollset
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#include "llstring.h"
|
||||
#include "apr_env.h"
|
||||
#include "llapr.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
static const U32 HTTP_STATUS_PIPE_ERROR = 499;
|
||||
|
||||
/**
|
||||
|
|
@ -211,31 +210,27 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback)
|
|||
// is called with use_proxy = FALSE
|
||||
void LLURLRequest::useProxy(bool use_proxy)
|
||||
{
|
||||
static std::string env_proxy;
|
||||
static char *env_proxy;
|
||||
|
||||
if (use_proxy && env_proxy.empty())
|
||||
if (use_proxy && (env_proxy == NULL))
|
||||
{
|
||||
char* env_proxy_str;
|
||||
LLScopedVolatileAPRPool scoped_pool;
|
||||
apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool);
|
||||
apr_status_t status;
|
||||
LLAPRPool pool;
|
||||
status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool());
|
||||
if (status != APR_SUCCESS)
|
||||
{
|
||||
status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool);
|
||||
status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool());
|
||||
}
|
||||
if (status != APR_SUCCESS)
|
||||
{
|
||||
use_proxy = false;
|
||||
use_proxy = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// env_proxy_str is stored in the scoped_pool, so we have to make a copy.
|
||||
env_proxy = env_proxy_str;
|
||||
}
|
||||
}
|
||||
|
||||
lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl;
|
||||
|
||||
if (use_proxy)
|
||||
lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl;
|
||||
|
||||
if (env_proxy && use_proxy)
|
||||
{
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,10 +97,8 @@ std::string get_shared_secret();
|
|||
class LLMessagePollInfo
|
||||
{
|
||||
public:
|
||||
LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { }
|
||||
apr_socket_t *mAPRSocketp;
|
||||
apr_pollfd_t mPollFD;
|
||||
LLAPRPool mPool;
|
||||
};
|
||||
|
||||
namespace
|
||||
|
|
@ -289,13 +287,20 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,
|
|||
}
|
||||
// LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl;
|
||||
|
||||
mPollInfop = new LLMessagePollInfo;
|
||||
|
||||
//
|
||||
// Create the data structure that we can poll on
|
||||
//
|
||||
if (!gAPRPoolp)
|
||||
{
|
||||
LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl;
|
||||
ll_init_apr();
|
||||
}
|
||||
apr_socket_t *aprSocketp = NULL;
|
||||
apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool());
|
||||
apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp);
|
||||
|
||||
mPollInfop = new LLMessagePollInfo;
|
||||
mPollInfop->mAPRSocketp = aprSocketp;
|
||||
mPollInfop->mPollFD.p = mPollInfop->mPool();
|
||||
mPollInfop->mPollFD.p = gAPRPoolp;
|
||||
mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET;
|
||||
mPollInfop->mPollFD.reqevents = APR_POLLIN;
|
||||
mPollInfop->mPollFD.rtnevents = 0;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#define LL_NETWORKIO_H
|
||||
|
||||
#include "llmemory.h" // LLSingleton
|
||||
#include "llapr.h"
|
||||
#include "llares.h"
|
||||
#include "llpumpio.h"
|
||||
#include "llhttpclient.h"
|
||||
|
|
@ -47,8 +48,14 @@ public:
|
|||
mServicePump(NULL),
|
||||
mDone(false)
|
||||
{
|
||||
ll_init_apr();
|
||||
if (! gAPRPoolp)
|
||||
{
|
||||
throw std::runtime_error("Can't initialize APR");
|
||||
}
|
||||
|
||||
// Create IO Pump to use for HTTP Requests.
|
||||
mServicePump = new LLPumpIO;
|
||||
mServicePump = new LLPumpIO(gAPRPoolp);
|
||||
LLHTTPClient::setPump(*mServicePump);
|
||||
if (ll_init_ares() == NULL || !gAres->isInitialized())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@
|
|||
#include "linden_common.h"
|
||||
|
||||
#include "llplugininstance.h"
|
||||
#include "llthread.h" // Needed for LLThread::tldata().mRootPool
|
||||
|
||||
#include "llapr.h"
|
||||
|
||||
/** Virtual destructor. */
|
||||
LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener()
|
||||
|
|
@ -47,7 +48,6 @@ const char *LLPluginInstance::PLUGIN_INIT_FUNCTION_NAME = "LLPluginInitEntryPoin
|
|||
* @param[in] owner Plugin instance. TODO:DOC is this a good description of what "owner" is?
|
||||
*/
|
||||
LLPluginInstance::LLPluginInstance(LLPluginInstanceMessageListener *owner) :
|
||||
mDSOHandlePool(LLThread::tldata().mRootPool),
|
||||
mDSOHandle(NULL),
|
||||
mPluginUserData(NULL),
|
||||
mPluginSendMessageFunction(NULL)
|
||||
|
|
@ -79,7 +79,7 @@ int LLPluginInstance::load(std::string &plugin_file)
|
|||
|
||||
int result = apr_dso_load(&mDSOHandle,
|
||||
plugin_file.c_str(),
|
||||
mDSOHandlePool());
|
||||
gAPRPoolp);
|
||||
if(result != APR_SUCCESS)
|
||||
{
|
||||
char buf[1024];
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include "llstring.h"
|
||||
#include "llapr.h"
|
||||
#include "llaprpool.h"
|
||||
|
||||
#include "apr_dso.h"
|
||||
|
||||
|
|
@ -89,7 +88,6 @@ private:
|
|||
static void staticReceiveMessage(const char *message_string, void **user_data);
|
||||
void receiveMessage(const char *message_string);
|
||||
|
||||
LLAPRPool mDSOHandlePool;
|
||||
apr_dso_handle_t *mDSOHandle;
|
||||
|
||||
void *mPluginUserData;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
|
|||
}
|
||||
|
||||
LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
|
||||
mInputMutex(gAPRPoolp),
|
||||
mOutputMutex(gAPRPoolp),
|
||||
mOwner(owner),
|
||||
mSocket(socket)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ LLPluginProcessChild::LLPluginProcessChild()
|
|||
{
|
||||
mState = STATE_UNINITIALIZED;
|
||||
mInstance = NULL;
|
||||
mSocket = LLSocket::create(LLSocket::STREAM_TCP);
|
||||
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
|
||||
mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz
|
||||
mCPUElapsed = 0.0f;
|
||||
mBlockingRequest = false;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include "llpluginmessageclasses.h"
|
||||
|
||||
#include "llapr.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
|
||||
//virtual
|
||||
LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
|
||||
|
|
@ -43,7 +42,6 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
|
|||
|
||||
bool LLPluginProcessParent::sUseReadThread = false;
|
||||
apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
|
||||
LLAPRPool LLPluginProcessParent::sPollSetPool;
|
||||
bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
|
||||
LLMutex *LLPluginProcessParent::sInstancesMutex;
|
||||
std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances;
|
||||
|
|
@ -54,7 +52,7 @@ class LLPluginProcessParentPollThread: public LLThread
|
|||
{
|
||||
public:
|
||||
LLPluginProcessParentPollThread() :
|
||||
LLThread("LLPluginProcessParentPollThread")
|
||||
LLThread("LLPluginProcessParentPollThread", gAPRPoolp)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
|
|
@ -79,11 +77,12 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner* owner)
|
||||
LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
|
||||
mIncomingQueueMutex(gAPRPoolp)
|
||||
{
|
||||
if(!sInstancesMutex)
|
||||
{
|
||||
sInstancesMutex = new LLMutex;
|
||||
sInstancesMutex = new LLMutex(gAPRPoolp);
|
||||
}
|
||||
|
||||
mOwner = owner;
|
||||
|
|
@ -96,7 +95,6 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner* owner)
|
|||
mBlocked = false;
|
||||
mPolledInput = false;
|
||||
mPollFD.client_data = NULL;
|
||||
mPollFDPool.create();
|
||||
|
||||
mPluginLaunchTimeout = 60.0f;
|
||||
mPluginLockupTimeout = 15.0f;
|
||||
|
|
@ -171,28 +169,44 @@ 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
|
||||
{
|
||||
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();
|
||||
}
|
||||
// llinfos << "Error:" << llendl;
|
||||
ll_apr_warn_status(status);
|
||||
|
||||
// Some other error.
|
||||
errorState();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -258,10 +272,10 @@ void LLPluginProcessParent::idle(void)
|
|||
|
||||
case STATE_INITIALIZED:
|
||||
{
|
||||
|
||||
apr_status_t status = APR_SUCCESS;
|
||||
LLScopedVolatileAPRPool addr_pool;
|
||||
apr_sockaddr_t* addr = NULL;
|
||||
mListenSocket = LLSocket::create(LLSocket::STREAM_TCP);
|
||||
mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
|
||||
mBoundPort = 0;
|
||||
|
||||
// This code is based on parts of LLSocket::create() in lliosocket.cpp.
|
||||
|
|
@ -272,7 +286,7 @@ void LLPluginProcessParent::idle(void)
|
|||
APR_INET,
|
||||
0, // port 0 = ephemeral ("find me a port")
|
||||
0,
|
||||
addr_pool);
|
||||
gAPRPoolp);
|
||||
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
|
|
@ -584,7 +598,7 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe)
|
|||
if(message_pipe != NULL)
|
||||
{
|
||||
// Set up the apr_pollfd_t
|
||||
mPollFD.p = mPollFDPool();
|
||||
mPollFD.p = gAPRPoolp;
|
||||
mPollFD.desc_type = APR_POLL_SOCKET;
|
||||
mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP;
|
||||
mPollFD.rtnevents = 0;
|
||||
|
|
@ -631,7 +645,6 @@ void LLPluginProcessParent::updatePollset()
|
|||
// delete the existing pollset.
|
||||
apr_pollset_destroy(sPollSet);
|
||||
sPollSet = NULL;
|
||||
sPollSetPool.destroy();
|
||||
}
|
||||
|
||||
std::list<LLPluginProcessParent*>::iterator iter;
|
||||
|
|
@ -654,14 +667,12 @@ void LLPluginProcessParent::updatePollset()
|
|||
{
|
||||
#ifdef APR_POLLSET_NOCOPY
|
||||
// The pollset doesn't exist yet. Create it now.
|
||||
sPollSetPool.create();
|
||||
apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY);
|
||||
apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, 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
|
||||
|
|
|
|||
|
|
@ -176,9 +176,7 @@ private:
|
|||
|
||||
static bool sUseReadThread;
|
||||
apr_pollfd_t mPollFD;
|
||||
LLAPRPool mPollFDPool;
|
||||
static apr_pollset_t *sPollSet;
|
||||
static LLAPRPool sPollSetPool;
|
||||
static bool sPollsetNeedsRebuild;
|
||||
static LLMutex *sInstancesMutex;
|
||||
static std::list<LLPluginProcessParent*> sInstances;
|
||||
|
|
|
|||
|
|
@ -187,8 +187,7 @@ bool LLPluginSharedMemory::create(size_t size)
|
|||
mName += createName();
|
||||
mSize = size;
|
||||
|
||||
mPool.create();
|
||||
apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool());
|
||||
apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp );
|
||||
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
|
|
@ -211,7 +210,7 @@ bool LLPluginSharedMemory::destroy(void)
|
|||
}
|
||||
mImpl->mAprSharedMemory = NULL;
|
||||
}
|
||||
mPool.destroy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -220,8 +219,7 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
|
|||
mName = name;
|
||||
mSize = size;
|
||||
|
||||
mPool.create();
|
||||
apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() );
|
||||
apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp );
|
||||
|
||||
if(ll_apr_warn_status(status))
|
||||
{
|
||||
|
|
@ -243,7 +241,6 @@ bool LLPluginSharedMemory::detach(void)
|
|||
}
|
||||
mImpl->mAprSharedMemory = NULL;
|
||||
}
|
||||
mPool.destroy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
#ifndef LL_LLPLUGINSHAREDMEMORY_H
|
||||
#define LL_LLPLUGINSHAREDMEMORY_H
|
||||
|
||||
#include "llaprpool.h"
|
||||
|
||||
class LLPluginSharedMemoryPlatformImpl;
|
||||
|
||||
/**
|
||||
|
|
@ -110,7 +108,6 @@ private:
|
|||
bool close(void);
|
||||
bool unlink(void);
|
||||
|
||||
LLAPRPool mPool;
|
||||
std::string mName;
|
||||
size_t mSize;
|
||||
void *mMappedAddress;
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ 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(".");
|
||||
|
|
@ -391,6 +393,8 @@ int main(int argc, char **argv)
|
|||
|
||||
delete plugin;
|
||||
|
||||
ll_cleanup_apr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ LLLFSThread::LLLFSThread(bool threaded) :
|
|||
LLQueuedThread("LFS", threaded),
|
||||
mPriorityCounter(PRIORITY_LOWBITS)
|
||||
{
|
||||
if(!mLocalAPRFilePoolp)
|
||||
{
|
||||
mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
|
||||
}
|
||||
}
|
||||
|
||||
LLLFSThread::~LLLFSThread()
|
||||
|
|
@ -178,7 +182,8 @@ bool LLLFSThread::Request::processRequest()
|
|||
if (mOperation == FILE_READ)
|
||||
{
|
||||
llassert(mOffset >= 0);
|
||||
LLAPRFile infile(mFileName, LL_APR_RB);
|
||||
LLAPRFile infile ; // auto-closes
|
||||
infile.open(mFileName, LL_APR_RB, mThread->getLocalAPRFilePool());
|
||||
if (!infile.getFileHandle())
|
||||
{
|
||||
llwarns << "LLLFS: Unable to read file: " << mFileName << llendl;
|
||||
|
|
@ -200,7 +205,8 @@ bool LLLFSThread::Request::processRequest()
|
|||
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
|
||||
if (mOffset < 0)
|
||||
flags |= APR_APPEND;
|
||||
LLAPRFile outfile(mFileName, flags);
|
||||
LLAPRFile outfile ; // auto-closes
|
||||
outfile.open(mFileName, flags, mThread->getLocalAPRFilePool());
|
||||
if (!outfile.getFileHandle())
|
||||
{
|
||||
llwarns << "LLLFS: Unable to write file: " << mFileName << llendl;
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
|
|||
mDataFP(NULL),
|
||||
mIndexFP(NULL)
|
||||
{
|
||||
mDataMutex = new LLMutex;
|
||||
mDataMutex = new LLMutex(0);
|
||||
|
||||
S32 i;
|
||||
for (i = 0; i < VFSLOCK_COUNT; i++)
|
||||
|
|
@ -2094,7 +2094,8 @@ void LLVFS::dumpFiles()
|
|||
std::string filename = id.asString() + extension;
|
||||
llinfos << " Writing " << filename << llendl;
|
||||
|
||||
LLAPRFile outfile(filename, LL_APR_WB);
|
||||
LLAPRFile outfile;
|
||||
outfile.open(filename, LL_APR_WB);
|
||||
outfile.write(&buffer[0], size);
|
||||
outfile.close();
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ extern "C" {
|
|||
#include <stdio.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "apr_pools.h"
|
||||
#include "apr_dso.h"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,18 +28,16 @@
|
|||
|
||||
#if LL_GSTREAMER010_ENABLED
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "apr_pools.h"
|
||||
#include "apr_dso.h"
|
||||
}
|
||||
|
||||
#include "llmediaimplgstreamertriviallogging.h"
|
||||
#include "llaprpool.h"
|
||||
|
||||
#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL
|
||||
#include "llmediaimplgstreamer_syms_raw.inc"
|
||||
|
|
@ -58,7 +56,7 @@ void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname)
|
|||
}
|
||||
|
||||
static bool sSymsGrabbed = false;
|
||||
static LLAPRPool sSymGSTDSOMemoryPool;
|
||||
static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
|
||||
static apr_dso_handle_t *sSymGSTDSOHandleG = NULL;
|
||||
static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;
|
||||
|
||||
|
|
@ -80,11 +78,11 @@ bool grab_gst_syms(std::string gst_dso_name,
|
|||
#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0)
|
||||
|
||||
//attempt to load the shared libraries
|
||||
sSymGSTDSOMemoryPool.create();
|
||||
apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
|
||||
|
||||
if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
|
||||
gst_dso_name.c_str(),
|
||||
sSymGSTDSOMemoryPool()) ))
|
||||
sSymGSTDSOMemoryPool) ))
|
||||
{
|
||||
INFOMSG("Found DSO: %s", gst_dso_name.c_str());
|
||||
#include "llmediaimplgstreamer_syms_raw.inc"
|
||||
|
|
@ -98,7 +96,7 @@ bool grab_gst_syms(std::string gst_dso_name,
|
|||
if ( APR_SUCCESS ==
|
||||
(rv = apr_dso_load(&sSymGSTDSOHandle,
|
||||
gst_dso_name_vid.c_str(),
|
||||
sSymGSTDSOMemoryPool()) ))
|
||||
sSymGSTDSOMemoryPool) ))
|
||||
{
|
||||
INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str());
|
||||
#include "llmediaimplgstreamer_syms_rawv.inc"
|
||||
|
|
@ -152,7 +150,8 @@ void ungrab_gst_syms()
|
|||
|
||||
if ( sSymGSTDSOMemoryPool )
|
||||
{
|
||||
sSymGSTDSOMemoryPool.destroy();
|
||||
apr_pool_destroy(sSymGSTDSOMemoryPool);
|
||||
sSymGSTDSOMemoryPool = NULL;
|
||||
}
|
||||
|
||||
// NULL-out all of the symbols we'd grabbed
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ extern "C" {
|
|||
#undef LL_PA_SYM
|
||||
|
||||
static bool sSymsGrabbed = false;
|
||||
static LLAPRPool sSymPADSOMemoryPool;
|
||||
static apr_pool_t *sSymPADSOMemoryPool = NULL;
|
||||
static apr_dso_handle_t *sSymPADSOHandleG = NULL;
|
||||
|
||||
bool grab_pa_syms(std::string pulse_dso_name)
|
||||
|
|
@ -84,11 +84,11 @@ bool grab_pa_syms(std::string pulse_dso_name)
|
|||
#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0)
|
||||
|
||||
//attempt to load the shared library
|
||||
sSymPADSOMemoryPool.create();
|
||||
apr_pool_create(&sSymPADSOMemoryPool, NULL);
|
||||
|
||||
if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle,
|
||||
pulse_dso_name.c_str(),
|
||||
sSymPADSOMemoryPool()) ))
|
||||
sSymPADSOMemoryPool) ))
|
||||
{
|
||||
INFOMSG("Found DSO: %s", pulse_dso_name.c_str());
|
||||
|
||||
|
|
@ -130,8 +130,12 @@ void ungrab_pa_syms()
|
|||
apr_dso_unload(sSymPADSOHandleG);
|
||||
sSymPADSOHandleG = NULL;
|
||||
}
|
||||
|
||||
sSymPADSOMemoryPool.destroy();
|
||||
|
||||
if ( sSymPADSOMemoryPool )
|
||||
{
|
||||
apr_pool_destroy(sSymPADSOMemoryPool);
|
||||
sSymPADSOMemoryPool = NULL;
|
||||
}
|
||||
|
||||
// NULL-out all of the symbols we'd grabbed
|
||||
#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0)
|
||||
|
|
|
|||
|
|
@ -1026,7 +1026,7 @@ bool LLAppViewer::mainLoop()
|
|||
//-------------------------------------------
|
||||
|
||||
// Create IO Pump to use for HTTP Requests.
|
||||
gServicePump = new LLPumpIO;
|
||||
gServicePump = new LLPumpIO(gAPRPoolp);
|
||||
LLHTTPClient::setPump(*gServicePump);
|
||||
LLCurl::setCAFile(gDirUtilp->getCAFile());
|
||||
|
||||
|
|
@ -1387,16 +1387,16 @@ bool LLAppViewer::cleanup()
|
|||
}
|
||||
|
||||
// *TODO - generalize this and move DSO wrangling to a helper class -brad
|
||||
for(std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> >::iterator plugin = mPlugins.begin();
|
||||
plugin != mPlugins.end(); ++plugin)
|
||||
std::set<struct apr_dso_handle_t *>::const_iterator i;
|
||||
for(i = mPlugins.begin(); i != mPlugins.end(); ++i)
|
||||
{
|
||||
int (*ll_plugin_stop_func)(void) = NULL;
|
||||
apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, plugin->first, "ll_plugin_stop");
|
||||
apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop");
|
||||
ll_plugin_stop_func();
|
||||
|
||||
rv = apr_dso_unload(plugin->first);
|
||||
rv = apr_dso_unload(*i);
|
||||
}
|
||||
mPlugins.clear(); // Forget handles and destroy all memory pools.
|
||||
mPlugins.clear();
|
||||
|
||||
//flag all elements as needing to be destroyed immediately
|
||||
// to ensure shutdown order
|
||||
|
|
@ -1828,7 +1828,7 @@ bool LLAppViewer::initThreads()
|
|||
|
||||
if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
|
||||
{
|
||||
LLFastTimer::sLogLock = new LLMutex;
|
||||
LLFastTimer::sLogLock = new LLMutex(NULL);
|
||||
mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName);
|
||||
mFastTimerLogThread->start();
|
||||
}
|
||||
|
|
@ -2969,7 +2969,8 @@ void LLAppViewer::handleViewerCrash()
|
|||
else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME);
|
||||
llinfos << "Creating crash marker file " << crash_file_name << llendl;
|
||||
|
||||
LLAPRFile crash_file(crash_file_name, LL_APR_W);
|
||||
LLAPRFile crash_file ;
|
||||
crash_file.open(crash_file_name, LL_APR_W);
|
||||
if (crash_file.getFileHandle())
|
||||
{
|
||||
LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
|
||||
|
|
@ -3033,10 +3034,11 @@ bool LLAppViewer::anotherInstanceRunning()
|
|||
LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
|
||||
|
||||
//Freeze case checks
|
||||
if (LLAPRFile::isExist(marker_file, LL_APR_RB))
|
||||
if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
|
||||
{
|
||||
// File exists, try opening with write permissions
|
||||
LLAPRFile outfile(marker_file, LL_APR_WB);
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(marker_file, LL_APR_WB);
|
||||
apr_file_t* fMarker = outfile.getFileHandle() ;
|
||||
if (!fMarker)
|
||||
{
|
||||
|
|
@ -3075,25 +3077,25 @@ void LLAppViewer::initMarkerFile()
|
|||
std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
|
||||
std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
|
||||
|
||||
if (LLAPRFile::isExist(mMarkerFileName, LL_APR_RB) && !anotherInstanceRunning())
|
||||
if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())
|
||||
{
|
||||
gLastExecEvent = LAST_EXEC_FROZE;
|
||||
LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;
|
||||
}
|
||||
if(LLAPRFile::isExist(logout_marker_file, LL_APR_RB))
|
||||
if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
|
||||
{
|
||||
gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
|
||||
LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
|
||||
LLAPRFile::remove(logout_marker_file);
|
||||
}
|
||||
if(LLAPRFile::isExist(llerror_marker_file, LL_APR_RB))
|
||||
if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
|
||||
{
|
||||
if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
|
||||
else gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
|
||||
LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
|
||||
LLAPRFile::remove(llerror_marker_file);
|
||||
}
|
||||
if(LLAPRFile::isExist(error_marker_file, LL_APR_RB))
|
||||
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
|
||||
{
|
||||
if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
|
||||
else gLastExecEvent = LAST_EXEC_OTHER_CRASH;
|
||||
|
|
@ -3109,7 +3111,7 @@ void LLAppViewer::initMarkerFile()
|
|||
|
||||
// Create the marker file for this execution & lock it
|
||||
apr_status_t s;
|
||||
s = mMarkerFile.open(mMarkerFileName, LL_APR_W, LLAPRFile::long_lived);
|
||||
s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);
|
||||
|
||||
if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
|
||||
{
|
||||
|
|
@ -4325,7 +4327,8 @@ void LLAppViewer::sendLogoutRequest()
|
|||
gLogoutInProgress = TRUE;
|
||||
mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
|
||||
|
||||
LLAPRFile outfile(mLogoutMarkerFileName, LL_APR_W);
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(mLogoutMarkerFileName, LL_APR_W);
|
||||
mLogoutMarkerFile = outfile.getFileHandle() ;
|
||||
if (mLogoutMarkerFile)
|
||||
{
|
||||
|
|
@ -4775,15 +4778,14 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
|
|||
}
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
boost::shared_ptr<LLAPRPool> eventhost_dso_memory_pool_ptr(new LLAPRPool);
|
||||
LLAPRPool& eventhost_dso_memory_pool(*eventhost_dso_memory_pool_ptr);
|
||||
apr_dso_handle_t* eventhost_dso_handle = NULL;
|
||||
apr_dso_handle_t * eventhost_dso_handle = NULL;
|
||||
apr_pool_t * eventhost_dso_memory_pool = NULL;
|
||||
|
||||
//attempt to load the shared library
|
||||
eventhost_dso_memory_pool.create();
|
||||
apr_pool_create(&eventhost_dso_memory_pool, NULL);
|
||||
apr_status_t rv = apr_dso_load(&eventhost_dso_handle,
|
||||
dso_path.c_str(),
|
||||
eventhost_dso_memory_pool());
|
||||
eventhost_dso_memory_pool);
|
||||
llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle));
|
||||
llassert_always(eventhost_dso_handle != NULL);
|
||||
|
||||
|
|
@ -4803,8 +4805,7 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
|
|||
llerrs << "problem loading eventhost plugin, status: " << status << llendl;
|
||||
}
|
||||
|
||||
// Store the handle and link it to the pool that was used to allocate it.
|
||||
mPlugins[eventhost_dso_handle] = eventhost_dso_memory_pool_ptr;
|
||||
mPlugins.insert(eventhost_dso_handle);
|
||||
}
|
||||
|
||||
void LLAppViewer::launchUpdater()
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ private:
|
|||
|
||||
LLAllocator mAlloc;
|
||||
|
||||
std::map<apr_dso_handle_t*, boost::shared_ptr<LLAPRPool> > mPlugins;
|
||||
std::set<struct apr_dso_handle_t*> mPlugins;
|
||||
|
||||
U32 mAvailPhysicalMemInKB ;
|
||||
U32 mAvailVirtualMemInKB ;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ int main( int argc, char **argv )
|
|||
}
|
||||
delete viewer_app_ptr;
|
||||
viewer_app_ptr = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@
|
|||
#if LL_DBUS_ENABLED
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llaprpool.h"
|
||||
|
||||
extern "C" {
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#include "apr_pools.h"
|
||||
#include "apr_dso.h"
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ extern "C" {
|
|||
#undef LL_DBUS_SYM
|
||||
|
||||
static bool sSymsGrabbed = false;
|
||||
static LLAPRPool sSymDBUSDSOMemoryPool;
|
||||
static apr_pool_t *sSymDBUSDSOMemoryPool = NULL;
|
||||
static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL;
|
||||
|
||||
bool grab_dbus_syms(std::string dbus_dso_name)
|
||||
|
|
@ -63,11 +63,11 @@ bool grab_dbus_syms(std::string dbus_dso_name)
|
|||
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0)
|
||||
|
||||
//attempt to load the shared library
|
||||
sSymDBUSDSOMemoryPool.create();
|
||||
apr_pool_create(&sSymDBUSDSOMemoryPool, NULL);
|
||||
|
||||
if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle,
|
||||
dbus_dso_name.c_str(),
|
||||
sSymDBUSDSOMemoryPool()) ))
|
||||
sSymDBUSDSOMemoryPool) ))
|
||||
{
|
||||
INFOMSG("Found DSO: %s", dbus_dso_name.c_str());
|
||||
|
||||
|
|
@ -109,7 +109,11 @@ void ungrab_dbus_syms()
|
|||
sSymDBUSDSOHandleG = NULL;
|
||||
}
|
||||
|
||||
sSymDBUSDSOMemoryPool.destroy();
|
||||
if ( sSymDBUSDSOMemoryPool )
|
||||
{
|
||||
apr_pool_destroy(sSymDBUSDSOMemoryPool);
|
||||
sSymDBUSDSOMemoryPool = NULL;
|
||||
}
|
||||
|
||||
// NULL-out all of the symbols we'd grabbed
|
||||
#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0)
|
||||
|
|
|
|||
|
|
@ -113,7 +113,6 @@ int main( int argc, char **argv )
|
|||
}
|
||||
delete viewer_app_ptr;
|
||||
viewer_app_ptr = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -223,7 +223,8 @@ BOOL LLFloaterAnimPreview::postBuild()
|
|||
// now load bvh file
|
||||
S32 file_size;
|
||||
|
||||
LLAPRFile infile(mFilenameAndPath, LL_APR_RB, &file_size);
|
||||
LLAPRFile infile ;
|
||||
infile.open(mFilenameAndPath, LL_APR_RB, NULL, &file_size);
|
||||
|
||||
if (!infile.getFileHandle())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ void LLMainLoopRepeater::start(void)
|
|||
{
|
||||
if(mQueue != 0) return;
|
||||
|
||||
mQueue = new LLThreadSafeQueue<LLSD>(1024);
|
||||
mQueue = new LLThreadSafeQueue<LLSD>(gAPRPoolp, 1024);
|
||||
mMainLoopConnection = LLEventPumps::instance().
|
||||
obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
|
||||
mRepeaterConnection = LLEventPumps::instance().
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ private:
|
|||
|
||||
bool LLTextureCacheLocalFileWorker::doRead()
|
||||
{
|
||||
S32 local_size = LLAPRFile::size(mFileName);
|
||||
S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());
|
||||
|
||||
if (local_size > 0 && mFileName.size() > 4)
|
||||
{
|
||||
|
|
@ -250,7 +250,7 @@ bool LLTextureCacheLocalFileWorker::doRead()
|
|||
}
|
||||
mReadData = new U8[mDataSize];
|
||||
|
||||
S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize);
|
||||
S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
|
||||
|
||||
if (bytes_read != mDataSize)
|
||||
{
|
||||
|
|
@ -331,7 +331,7 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||
// Is it a JPEG2000 file?
|
||||
{
|
||||
local_filename = filename + ".j2c";
|
||||
local_size = LLAPRFile::size(local_filename);
|
||||
local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
|
||||
if (local_size > 0)
|
||||
{
|
||||
mImageFormat = IMG_CODEC_J2C;
|
||||
|
|
@ -341,7 +341,7 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||
if (local_size == 0)
|
||||
{
|
||||
local_filename = filename + ".jpg";
|
||||
local_size = LLAPRFile::size(local_filename);
|
||||
local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
|
||||
if (local_size > 0)
|
||||
{
|
||||
mImageFormat = IMG_CODEC_JPEG;
|
||||
|
|
@ -352,7 +352,7 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||
if (local_size == 0)
|
||||
{
|
||||
local_filename = filename + ".tga";
|
||||
local_size = LLAPRFile::size(local_filename);
|
||||
local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool());
|
||||
if (local_size > 0)
|
||||
{
|
||||
mImageFormat = IMG_CODEC_TGA;
|
||||
|
|
@ -378,7 +378,8 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||
}
|
||||
// Allocate read buffer
|
||||
mReadData = new U8[mDataSize];
|
||||
S32 bytes_read = LLAPRFile::readEx(local_filename, mReadData, mOffset, mDataSize);
|
||||
S32 bytes_read = LLAPRFile::readEx(local_filename,
|
||||
mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
|
||||
if (bytes_read != mDataSize)
|
||||
{
|
||||
llwarns << "Error reading file from local cache: " << local_filename
|
||||
|
|
@ -429,7 +430,8 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||
size = llmin(size, mDataSize);
|
||||
// Allocate the read buffer
|
||||
mReadData = new U8[size];
|
||||
S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, mReadData, offset, size);
|
||||
S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName,
|
||||
mReadData, offset, size, mCache->getLocalAPRFilePool());
|
||||
if (bytes_read != size)
|
||||
{
|
||||
llwarns << "LLTextureCacheWorker: " << mID
|
||||
|
|
@ -455,7 +457,7 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||
if (!done && (mState == BODY))
|
||||
{
|
||||
std::string filename = mCache->getTextureFileName(mID);
|
||||
S32 filesize = LLAPRFile::size(filename);
|
||||
S32 filesize = LLAPRFile::size(filename, mCache->getLocalAPRFilePool());
|
||||
|
||||
if (filesize && (filesize + TEXTURE_CACHE_ENTRY_SIZE) > mOffset)
|
||||
{
|
||||
|
|
@ -497,7 +499,8 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||
// Read the data at last
|
||||
S32 bytes_read = LLAPRFile::readEx(filename,
|
||||
mReadData + data_offset,
|
||||
file_offset, file_size);
|
||||
file_offset, file_size,
|
||||
mCache->getLocalAPRFilePool());
|
||||
if (bytes_read != file_size)
|
||||
{
|
||||
llwarns << "LLTextureCacheWorker: " << mID
|
||||
|
|
@ -598,13 +601,13 @@ bool LLTextureCacheRemoteWorker::doWrite()
|
|||
U8* padBuffer = new U8[TEXTURE_CACHE_ENTRY_SIZE];
|
||||
memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros
|
||||
memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer
|
||||
bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size);
|
||||
bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool());
|
||||
delete [] padBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file
|
||||
bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size);
|
||||
bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool());
|
||||
}
|
||||
|
||||
if (bytes_written <= 0)
|
||||
|
|
@ -639,7 +642,8 @@ bool LLTextureCacheRemoteWorker::doWrite()
|
|||
// llinfos << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << llendl;
|
||||
S32 bytes_written = LLAPRFile::writeEx( filename,
|
||||
mWriteData + TEXTURE_CACHE_ENTRY_SIZE,
|
||||
0, file_size);
|
||||
0, file_size,
|
||||
mCache->getLocalAPRFilePool());
|
||||
if (bytes_written <= 0)
|
||||
{
|
||||
llwarns << "LLTextureCacheWorker: " << mID
|
||||
|
|
@ -736,6 +740,9 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted)
|
|||
|
||||
LLTextureCache::LLTextureCache(bool threaded)
|
||||
: LLWorkerThread("TextureCache", threaded),
|
||||
mWorkersMutex(NULL),
|
||||
mHeaderMutex(NULL),
|
||||
mListMutex(NULL),
|
||||
mHeaderAPRFile(NULL),
|
||||
mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called.
|
||||
mTexturesSizeTotal(0),
|
||||
|
|
@ -839,7 +846,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
|
|||
// Is it a JPEG2000 file?
|
||||
{
|
||||
local_filename = filename + ".j2c";
|
||||
local_size = LLAPRFile::size(local_filename);
|
||||
local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
|
||||
if (local_size > 0)
|
||||
{
|
||||
return TRUE ;
|
||||
|
|
@ -849,7 +856,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
|
|||
// If not, is it a jpeg file?
|
||||
{
|
||||
local_filename = filename + ".jpg";
|
||||
local_size = LLAPRFile::size(local_filename);
|
||||
local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
|
||||
if (local_size > 0)
|
||||
{
|
||||
return TRUE ;
|
||||
|
|
@ -859,7 +866,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
|
|||
// Hmm... What about a targa file? (used for UI texture mostly)
|
||||
{
|
||||
local_filename = filename + ".tga";
|
||||
local_size = LLAPRFile::size(local_filename);
|
||||
local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool());
|
||||
if (local_size > 0)
|
||||
{
|
||||
return TRUE ;
|
||||
|
|
@ -905,10 +912,10 @@ void LLTextureCache::purgeCache(ELLPath location)
|
|||
if(LLFile::isdir(mTexturesDirName))
|
||||
{
|
||||
std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
|
||||
LLAPRFile::remove(file_name);
|
||||
LLAPRFile::remove(file_name, getLocalAPRFilePool());
|
||||
|
||||
file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
|
||||
LLAPRFile::remove(file_name);
|
||||
LLAPRFile::remove(file_name, getLocalAPRFilePool());
|
||||
|
||||
purgeAllTextures(true);
|
||||
}
|
||||
|
|
@ -984,9 +991,7 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
|
|||
{
|
||||
llassert_always(mHeaderAPRFile == NULL);
|
||||
apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY;
|
||||
// All code calling openHeaderEntriesFile, immediately calls closeHeaderEntriesFile,
|
||||
// so this file is very short-lived.
|
||||
mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags);
|
||||
mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, getLocalAPRFilePool());
|
||||
if(offset > 0)
|
||||
{
|
||||
mHeaderAPRFile->seek(APR_SET, offset);
|
||||
|
|
@ -1009,9 +1014,10 @@ void LLTextureCache::readEntriesHeader()
|
|||
{
|
||||
// mHeaderEntriesInfo initializes to default values so safe not to read it
|
||||
llassert_always(mHeaderAPRFile == NULL);
|
||||
if (LLAPRFile::isExist(mHeaderEntriesFileName))
|
||||
if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool()))
|
||||
{
|
||||
LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
|
||||
LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
|
||||
getLocalAPRFilePool());
|
||||
}
|
||||
else //create an empty entries header.
|
||||
{
|
||||
|
|
@ -1026,7 +1032,8 @@ void LLTextureCache::writeEntriesHeader()
|
|||
llassert_always(mHeaderAPRFile == NULL);
|
||||
if (!mReadOnly)
|
||||
{
|
||||
LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
|
||||
LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
|
||||
getLocalAPRFilePool());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1616,7 +1623,7 @@ void LLTextureCache::purgeTextures(bool validate)
|
|||
if (uuididx == validate_idx)
|
||||
{
|
||||
LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
|
||||
S32 bodysize = LLAPRFile::size(filename);
|
||||
S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool());
|
||||
if (bodysize != entries[idx].mBodySize)
|
||||
{
|
||||
LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
|
||||
|
|
@ -1851,7 +1858,7 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
|
|||
mTexturesSizeMap.erase(id);
|
||||
}
|
||||
mHeaderIDMap.erase(id);
|
||||
LLAPRFile::remove(getTextureFileName(id));
|
||||
LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool());
|
||||
}
|
||||
|
||||
//called after mHeaderMutex is locked.
|
||||
|
|
@ -1863,7 +1870,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
|
|||
{
|
||||
if (entry.mBodySize == 0) // Always attempt to remove when mBodySize > 0.
|
||||
{
|
||||
if (LLAPRFile::isExist(filename)) // Sanity check. Shouldn't exist when body size is 0.
|
||||
if (LLAPRFile::isExist(filename, getLocalAPRFilePool())) // Sanity check. Shouldn't exist when body size is 0.
|
||||
{
|
||||
LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL;
|
||||
}
|
||||
|
|
@ -1884,7 +1891,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
|
|||
|
||||
if (file_maybe_exists)
|
||||
{
|
||||
LLAPRFile::remove(filename);
|
||||
LLAPRFile::remove(filename, getLocalAPRFilePool());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,6 +142,9 @@ protected:
|
|||
std::string getTextureFileName(const LLUUID& id);
|
||||
void addCompleted(Responder* responder, bool success);
|
||||
|
||||
protected:
|
||||
//void setFileAPRPool(apr_pool_t* pool) { mFileAPRPool = pool ; }
|
||||
|
||||
private:
|
||||
void setDirNames(ELLPath location);
|
||||
void readHeaderCache();
|
||||
|
|
|
|||
|
|
@ -674,6 +674,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
|
|||
mRetryAttempt(0),
|
||||
mActiveCount(0),
|
||||
mGetStatus(0),
|
||||
mWorkMutex(NULL),
|
||||
mFirstPacket(0),
|
||||
mLastPacket(-1),
|
||||
mTotalPackets(0),
|
||||
|
|
@ -1815,6 +1816,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||
mDebugPause(FALSE),
|
||||
mPacketCount(0),
|
||||
mBadPacketCount(0),
|
||||
mQueueMutex(getAPRPool()),
|
||||
mNetworkQueueMutex(getAPRPool()),
|
||||
mTextureCache(cache),
|
||||
mImageDecodeThread(imagedecodethread),
|
||||
mTextureBandwidth(0),
|
||||
|
|
|
|||
|
|
@ -736,7 +736,8 @@ void upload_new_resource(const std::string& src_filename, std::string name,
|
|||
uuid = tid.makeAssetID(gAgent.getSecureSessionID());
|
||||
// copy this file into the vfs for upload
|
||||
S32 file_size;
|
||||
LLAPRFile infile(filename, LL_APR_RB, &file_size);
|
||||
LLAPRFile infile ;
|
||||
infile.open(filename, LL_APR_RB, NULL, &file_size);
|
||||
if (infile.getFileHandle())
|
||||
{
|
||||
LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
|
||||
|
|
|
|||
|
|
@ -7190,7 +7190,8 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
|
|||
// static
|
||||
void LLVOAvatar::dumpArchetypeXML( void* )
|
||||
{
|
||||
LLAPRFile outfile(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER, "new archetype.xml"), LL_APR_WB);
|
||||
LLAPRFile outfile;
|
||||
outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB );
|
||||
apr_file_t* file = outfile.getFileHandle() ;
|
||||
if (!file)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,14 +30,14 @@
|
|||
#include "llregionhandle.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
static BOOL check_read(LLAPRFile& apr_file, void* src, S32 n_bytes)
|
||||
BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
|
||||
{
|
||||
return apr_file.read(src, n_bytes) == n_bytes ;
|
||||
return apr_file->read(src, n_bytes) == n_bytes ;
|
||||
}
|
||||
|
||||
static BOOL check_write(LLAPRFile& apr_file, void* src, S32 n_bytes)
|
||||
BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
|
||||
{
|
||||
return apr_file.write(src, n_bytes) == n_bytes ;
|
||||
return apr_file->write(src, n_bytes) == n_bytes ;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ LLVOCacheEntry::LLVOCacheEntry()
|
|||
mDP.assignBuffer(mBuffer, 0);
|
||||
}
|
||||
|
||||
LLVOCacheEntry::LLVOCacheEntry(LLAPRFile& apr_file)
|
||||
LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
|
||||
{
|
||||
S32 size = -1;
|
||||
BOOL success;
|
||||
|
|
@ -185,7 +185,7 @@ void LLVOCacheEntry::dump() const
|
|||
<< llendl;
|
||||
}
|
||||
|
||||
BOOL LLVOCacheEntry::writeToFile(LLAPRFile& apr_file) const
|
||||
BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
|
||||
{
|
||||
BOOL success;
|
||||
success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));
|
||||
|
|
@ -266,6 +266,7 @@ LLVOCache::LLVOCache():
|
|||
mCacheSize(1)
|
||||
{
|
||||
mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
|
||||
mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
|
||||
}
|
||||
|
||||
LLVOCache::~LLVOCache()
|
||||
|
|
@ -275,6 +276,7 @@ LLVOCache::~LLVOCache()
|
|||
writeCacheHeader();
|
||||
clearCacheInMemory();
|
||||
}
|
||||
delete mLocalAPRFilePoolp;
|
||||
}
|
||||
|
||||
void LLVOCache::setDirNames(ELLPath location)
|
||||
|
|
@ -435,7 +437,7 @@ void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
|
|||
|
||||
std::string filename;
|
||||
getObjectCacheFilename(entry->mHandle, filename);
|
||||
LLAPRFile::remove(filename);
|
||||
LLAPRFile::remove(filename, mLocalAPRFilePoolp);
|
||||
entry->mTime = INVALID_TIME ;
|
||||
updateEntry(entry) ; //update the head file.
|
||||
}
|
||||
|
|
@ -452,12 +454,12 @@ void LLVOCache::readCacheHeader()
|
|||
clearCacheInMemory();
|
||||
|
||||
bool success = true ;
|
||||
if (LLAPRFile::isExist(mHeaderFileName))
|
||||
if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
|
||||
{
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY);
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
//read the meta element
|
||||
success = check_read(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
|
||||
success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
|
||||
|
||||
if(success)
|
||||
{
|
||||
|
|
@ -470,7 +472,7 @@ void LLVOCache::readCacheHeader()
|
|||
{
|
||||
entry = new HeaderEntryInfo() ;
|
||||
}
|
||||
success = check_read(apr_file, entry, sizeof(HeaderEntryInfo));
|
||||
success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo));
|
||||
|
||||
if(!success) //failed
|
||||
{
|
||||
|
|
@ -539,17 +541,17 @@ void LLVOCache::writeCacheHeader()
|
|||
|
||||
bool success = true ;
|
||||
{
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY);
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
//write the meta element
|
||||
success = check_write(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
|
||||
success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
|
||||
|
||||
|
||||
mNumEntries = 0 ;
|
||||
for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
|
||||
{
|
||||
(*iter)->mIndex = mNumEntries++ ;
|
||||
success = check_write(apr_file, (void*)*iter, sizeof(HeaderEntryInfo));
|
||||
success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo));
|
||||
}
|
||||
|
||||
mNumEntries = mHeaderEntryQueue.size() ;
|
||||
|
|
@ -560,7 +562,7 @@ void LLVOCache::writeCacheHeader()
|
|||
for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++)
|
||||
{
|
||||
//fill the cache with the default entry.
|
||||
success = check_write(apr_file, entry, sizeof(HeaderEntryInfo)) ;
|
||||
success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ;
|
||||
|
||||
}
|
||||
delete entry ;
|
||||
|
|
@ -577,10 +579,10 @@ void LLVOCache::writeCacheHeader()
|
|||
|
||||
BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
|
||||
{
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY);
|
||||
apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo));
|
||||
LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
|
||||
|
||||
return check_write(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
|
||||
return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
|
||||
}
|
||||
|
||||
void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)
|
||||
|
|
@ -603,10 +605,10 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
|
|||
{
|
||||
std::string filename;
|
||||
getObjectCacheFilename(handle, filename);
|
||||
LLAPRFile apr_file(filename, APR_READ|APR_BINARY);
|
||||
LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
LLUUID cache_id ;
|
||||
success = check_read(apr_file, cache_id.mData, UUID_BYTES) ;
|
||||
success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ;
|
||||
|
||||
if(success)
|
||||
{
|
||||
|
|
@ -619,11 +621,11 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
|
|||
if(success)
|
||||
{
|
||||
S32 num_entries;
|
||||
success = check_read(apr_file, &num_entries, sizeof(S32)) ;
|
||||
success = check_read(&apr_file, &num_entries, sizeof(S32)) ;
|
||||
|
||||
for (S32 i = 0; success && i < num_entries; i++)
|
||||
{
|
||||
LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file);
|
||||
LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file);
|
||||
if (!entry->getLocalID())
|
||||
{
|
||||
llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
|
||||
|
|
@ -722,19 +724,19 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
|
|||
{
|
||||
std::string filename;
|
||||
getObjectCacheFilename(handle, filename);
|
||||
LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY);
|
||||
LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
|
||||
|
||||
success = check_write(apr_file, (void*)id.mData, UUID_BYTES) ;
|
||||
success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ;
|
||||
|
||||
|
||||
if(success)
|
||||
{
|
||||
S32 num_entries = cache_entry_map.size() ;
|
||||
success = check_write(apr_file, &num_entries, sizeof(S32));
|
||||
success = check_write(&apr_file, &num_entries, sizeof(S32));
|
||||
|
||||
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
|
||||
{
|
||||
success = iter->second->writeToFile(apr_file) ;
|
||||
success = iter->second->writeToFile(&apr_file) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class LLVOCacheEntry
|
|||
{
|
||||
public:
|
||||
LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);
|
||||
LLVOCacheEntry(LLAPRFile& apr_file);
|
||||
LLVOCacheEntry(LLAPRFile* apr_file);
|
||||
LLVOCacheEntry();
|
||||
~LLVOCacheEntry();
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ public:
|
|||
S32 getCRCChangeCount() const { return mCRCChangeCount; }
|
||||
|
||||
void dump() const;
|
||||
BOOL writeToFile(LLAPRFile& apr_file) const;
|
||||
BOOL writeToFile(LLAPRFile* apr_file) const;
|
||||
void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp);
|
||||
LLDataPackerBinaryBuffer *getDP(U32 crc);
|
||||
void recordHit();
|
||||
|
|
@ -142,6 +142,7 @@ private:
|
|||
U32 mNumEntries;
|
||||
std::string mHeaderFileName ;
|
||||
std::string mObjectCacheDirName;
|
||||
LLVolatileAPRPool* mLocalAPRFilePoolp ;
|
||||
header_entry_queue_t mHeaderEntryQueue;
|
||||
handle_entry_map_t mHandleEntryMap;
|
||||
|
||||
|
|
|
|||
|
|
@ -961,7 +961,7 @@ void LLVivoxVoiceClient::stateMachine()
|
|||
|
||||
if(!mSocket)
|
||||
{
|
||||
mSocket = LLSocket::create(LLSocket::STREAM_TCP);
|
||||
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
|
||||
}
|
||||
|
||||
mConnected = mSocket->blockingConnect(mDaemonHost);
|
||||
|
|
|
|||
|
|
@ -178,8 +178,8 @@ void LLWatchdog::init(killer_event_callback func)
|
|||
mKillerCallback = func;
|
||||
if(!mSuspectsAccessMutex && !mTimer)
|
||||
{
|
||||
mSuspectsAccessMutex = new LLMutex;
|
||||
mTimer = new LLWatchdogTimerThread;
|
||||
mSuspectsAccessMutex = new LLMutex(NULL);
|
||||
mTimer = new LLWatchdogTimerThread();
|
||||
mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000);
|
||||
mLastClockCount = LLTimer::getTotalTime();
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
// Dependencies
|
||||
#include "linden_common.h"
|
||||
#include "llapr.h"
|
||||
#include "llsingleton.h"
|
||||
#include "lltrans.h"
|
||||
#include "lluistring.h"
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "linden_common.h"
|
||||
#include "lltut.h"
|
||||
|
||||
#include "llapr.h"
|
||||
#include "llmessagetemplate.h"
|
||||
#include "llquaternion.h"
|
||||
#include "lltemplatemessagebuilder.h"
|
||||
|
|
@ -52,6 +53,7 @@ namespace tut
|
|||
static bool init = false;
|
||||
if(! init)
|
||||
{
|
||||
ll_init_apr();
|
||||
const F32 circuit_heartbeat_interval=5;
|
||||
const F32 circuit_timeout=100;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "linden_common.h"
|
||||
#include "lltut.h"
|
||||
|
||||
#include "llapr.h"
|
||||
#include "llmessageconfig.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llversionserver.h"
|
||||
|
|
@ -61,6 +62,7 @@ namespace tut
|
|||
static bool init = false;
|
||||
if(!init)
|
||||
{
|
||||
ll_init_apr();
|
||||
//init_prehash_data();
|
||||
init = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@
|
|||
#include "linden_common.h"
|
||||
#include "llerrorcontrol.h"
|
||||
#include "lltut.h"
|
||||
#include "llaprpool.h"
|
||||
|
||||
#include "apr_pools.h"
|
||||
#include "apr_getopt.h"
|
||||
|
||||
// the CTYPE_WORKAROUND is needed for linux dev stations that don't
|
||||
|
|
@ -349,12 +349,17 @@ int main(int argc, char **argv)
|
|||
ctype_workaround();
|
||||
#endif
|
||||
|
||||
LLAPRPool pool;
|
||||
pool.create();
|
||||
apr_getopt_t* os = NULL;
|
||||
if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv))
|
||||
apr_initialize();
|
||||
apr_pool_t* pool = NULL;
|
||||
if(APR_SUCCESS != apr_pool_create(&pool, NULL))
|
||||
{
|
||||
std::cerr << "Unable to initialize the arguments for parsing by apr_getopt()." << std::endl;
|
||||
std::cerr << "Unable to initialize pool" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
apr_getopt_t* os = NULL;
|
||||
if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv))
|
||||
{
|
||||
std::cerr << "Unable to pool" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -472,6 +477,8 @@ int main(int argc, char **argv)
|
|||
s.close();
|
||||
}
|
||||
|
||||
apr_terminate();
|
||||
|
||||
int retval = (success ? 0 : 1);
|
||||
return retval;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "linden_common.h"
|
||||
#include "indra_constants.h"
|
||||
|
||||
#include "llapr.h"
|
||||
#include "llerrorcontrol.h"
|
||||
|
||||
#include <math.h>
|
||||
|
|
@ -185,6 +186,9 @@ LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int wind
|
|||
std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl;
|
||||
};
|
||||
|
||||
// initialize linden lab APR module
|
||||
ll_init_apr();
|
||||
|
||||
// Set up llerror logging
|
||||
{
|
||||
LLError::initForApplication(".");
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "linden_common.h"
|
||||
#include <apr_file_io.h>
|
||||
#include "llapr.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
#include "llprocesslauncher.h"
|
||||
#include "llupdateinstaller.h"
|
||||
#include "lldir.h"
|
||||
|
|
@ -46,8 +45,7 @@ namespace {
|
|||
{
|
||||
std::string scriptFile = gDirUtilp->getBaseFileName(path);
|
||||
std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile);
|
||||
LLScopedVolatileAPRPool pool;
|
||||
apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, pool);
|
||||
apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp);
|
||||
if(status != APR_SUCCESS) throw RelocateError();
|
||||
|
||||
return newPath;
|
||||
|
|
|
|||
Loading…
Reference in New Issue