summaryrefslogtreecommitdiff
path: root/indra/llcommon/llapr.cpp
diff options
context:
space:
mode:
authorBrad Kittenbrink <brad@lindenlab.com>2009-02-18 21:10:16 +0000
committerBrad Kittenbrink <brad@lindenlab.com>2009-02-18 21:10:16 +0000
commitabdc99f21b542c4fea67030ddbd7166c9d1c6c63 (patch)
tree3e984e405adfdec189ca8a047daca5250737ffbf /indra/llcommon/llapr.cpp
parent34412f0530cf6a411b4de906a8e9da59cbcb3a85 (diff)
Merge of QAR-1267 to trunk. This was a combo merge of QAR-1175 (maint-render-9) and QAR-1236 (dll-msvcrt-2)
svn merge -r 109838:112264 svn+ssh://svn.lindenlab.com/svn/linden/branches/maint-render/maint-render-9-merge-r109833
Diffstat (limited to 'indra/llcommon/llapr.cpp')
-rw-r--r--indra/llcommon/llapr.cpp502
1 files changed, 389 insertions, 113 deletions
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index 74d821c721..82530b1489 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -36,8 +36,10 @@
#include "llapr.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;
+const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
void ll_init_apr()
{
@@ -46,10 +48,15 @@ void ll_init_apr()
// 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);
}
+
+ if(!LLAPRFile::sAPRFilePoolp)
+ {
+ LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool() ;
+ }
}
@@ -70,31 +77,127 @@ void ll_cleanup_apr()
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)
+LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
{
- mStatus = apr_pool_create(&mPool, parent);
+ mParent = parent ;
+ mReleasePoolFlag = releasePoolFlag ;
+ mMaxSize = size ;
+ mPool = NULL ;
+
+ createAPRPool() ;
+}
+
+LLAPRPool::~LLAPRPool()
+{
+ releaseAPRPool() ;
+}
- if(size > 0) //size is the number of blocks (which is usually 4K), NOT bytes.
+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, size) ;
+ apr_allocator_max_free_set(allocator, mMaxSize) ;
}
}
}
-LLAPRPool::~LLAPRPool()
+void LLAPRPool::releaseAPRPool()
+{
+ if(!mPool)
+ {
+ return ;
+ }
+
+ if(!mParent || mReleasePoolFlag)
+ {
+ apr_pool_destroy(mPool) ;
+ mPool = NULL ;
+ }
+}
+
+apr_pool_t* LLAPRPool::getAPRPool()
{
- apr_pool_destroy(mPool) ;
+ if(!mPool)
+ {
+ createAPRPool() ;
+ }
+
+ return mPool ;
+}
+LLVolatileAPRPool::LLVolatileAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
+ : LLAPRPool(parent, size, releasePoolFlag)
+{
+ mNumActiveRef = 0 ;
+ mNumTotalRef = 0 ;
}
+apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
+{
+ mNumTotalRef++ ;
+ mNumActiveRef++ ;
+ return getAPRPool() ;
+}
+
+void LLVolatileAPRPool::clearVolatileAPRPool()
+{
+ 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
//
@@ -133,9 +236,8 @@ void LLScopedLock::unlock()
}
}
-//
-// Misc functions
-//
+//---------------------------------------------------------------------
+
bool ll_apr_warn_status(apr_status_t status)
{
if(APR_SUCCESS == status) return false;
@@ -151,55 +253,110 @@ void ll_apr_assert_status(apr_status_t status)
llassert(ll_apr_warn_status(status) == false);
}
-// File I/O
-apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool)
+//---------------------------------------------------------------------
+//
+// LLAPRFile functions
+//
+LLAPRFile::LLAPRFile()
+{
+ mFile = NULL ;
+ mCurrentFilePoolp = NULL ;
+}
+LLAPRFile::~LLAPRFile()
+{
+ close() ;
+}
+
+apr_status_t LLAPRFile::close()
+{
+ apr_status_t ret = APR_SUCCESS ;
+ if(mFile)
+ {
+ ret = apr_file_close(mFile);
+ mFile = NULL ;
+ }
+
+ if(mCurrentFilePoolp)
+ {
+ mCurrentFilePoolp->clearVolatileAPRPool() ;
+ mCurrentFilePoolp = NULL ;
+ }
+
+ return ret ;
+}
+
+apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep)
+{
+ apr_status_t s ;
+ s = open(filename, flags, pool ? pool->getVolatileAPRPool() : NULL, sizep) ;
+
+ if(!mCurrentFilePoolp)
+ {
+ mCurrentFilePoolp = pool ;
+
+ if(!mFile)
+ {
+ close() ;
+ }
+ }
+
+ return s ;
+}
+apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool, S32* sizep)
{
- apr_file_t* apr_file;
apr_status_t s;
- if (pool == NULL) pool = gAPRPoolp;
- s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool);
- if (s != APR_SUCCESS)
+
+ //check if already open some file
+ llassert_always(!mFile) ;
+ llassert_always(!mCurrentFilePoolp) ;
+
+ s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(pool));
+ if (s != APR_SUCCESS || !mFile)
{
+ mFile = NULL ;
+ close() ;
if (sizep)
{
*sizep = 0;
}
- return NULL;
+ return s;
}
if (sizep)
{
S32 file_size = 0;
apr_off_t offset = 0;
- if (apr_file_seek(apr_file, APR_END, &offset) == APR_SUCCESS)
+ if (apr_file_seek(mFile, APR_END, &offset) == APR_SUCCESS)
{
llassert_always(offset <= 0x7fffffff);
file_size = (S32)offset;
offset = 0;
- apr_file_seek(apr_file, APR_SET, &offset);
+ apr_file_seek(mFile, APR_SET, &offset);
}
*sizep = file_size;
}
- return apr_file;
+ return s;
}
-apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep)
-{
- return ll_apr_file_open(filename, flags, sizep, NULL);
-}
-apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool)
-{
- return ll_apr_file_open(filename, flags, NULL, pool);
-}
-apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags)
-{
- return ll_apr_file_open(filename, flags, NULL, NULL);
+
+apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool)
+{
+ if(!pool)
+ {
+ mCurrentFilePoolp = sAPRFilePoolp ;
+ return mCurrentFilePoolp->getVolatileAPRPool() ;
+ }
+
+ return pool ;
}
-S32 ll_apr_file_read(apr_file_t* apr_file, void *buf, S32 nbytes)
+// File I/O
+S32 LLAPRFile::read(void *buf, S32 nbytes)
{
+ llassert_always(mFile) ;
+
apr_size_t sz = nbytes;
- apr_status_t s = apr_file_read(apr_file, buf, &sz);
+ apr_status_t s = apr_file_read(mFile, buf, &sz);
if (s != APR_SUCCESS)
{
return 0;
@@ -211,165 +368,273 @@ S32 ll_apr_file_read(apr_file_t* apr_file, void *buf, S32 nbytes)
}
}
-S32 ll_apr_file_read_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes)
+S32 LLAPRFile::write(const void *buf, S32 nbytes)
{
- if (pool == NULL) pool = gAPRPoolp;
- apr_file_t* filep = ll_apr_file_open(filename, APR_READ|APR_BINARY, pool);
- if (!filep)
+ llassert_always(mFile) ;
+
+ apr_size_t sz = nbytes;
+ apr_status_t s = apr_file_write(mFile, buf, &sz);
+ if (s != APR_SUCCESS)
{
return 0;
}
- S32 off;
- if (offset < 0)
- off = ll_apr_file_seek(filep, APR_END, 0);
else
- off = ll_apr_file_seek(filep, APR_SET, offset);
- S32 bytes_read;
- if (off < 0)
{
- bytes_read = 0;
+ llassert_always(sz <= 0x7fffffff);
+ return (S32)sz;
}
- else
+}
+
+S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset)
+{
+ return LLAPRFile::seek(mFile, where, 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)
{
- bytes_read = ll_apr_file_read(filep, buf, nbytes );
+ ret = apr_file_close(file_handle);
+ file_handle = NULL ;
}
- apr_file_close(filep);
- return bytes_read;
+ if(pool)
+ {
+ pool->clearVolatileAPRPool() ;
+ }
+
+ return ret ;
}
-S32 ll_apr_file_write(apr_file_t* apr_file, const void *buf, S32 nbytes)
+//static
+apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
{
- apr_size_t sz = nbytes;
- apr_status_t s = apr_file_write(apr_file, buf, &sz);
+ 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)
+ {
+ 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)
+{
+ if(!file_handle)
+ {
+ return -1 ;
+ }
+
+ apr_status_t s;
+ apr_off_t apr_offset;
+ if (offset >= 0)
+ {
+ apr_offset = (apr_off_t)offset;
+ s = apr_file_seek(file_handle, where, &apr_offset);
+ }
+ else
+ {
+ apr_offset = 0;
+ s = apr_file_seek(file_handle, APR_END, &apr_offset);
+ }
if (s != APR_SUCCESS)
{
+ return -1;
+ }
+ else
+ {
+ llassert_always(apr_offset <= 0x7fffffff);
+ return (S32)apr_offset;
+ }
+}
+
+//static
+S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
+{
+ //*****************************************
+ apr_file_t* file_handle = open(filename, pool, APR_READ|APR_BINARY);
+ //*****************************************
+ if (!file_handle)
+ {
return 0;
}
+
+ S32 off;
+ if (offset < 0)
+ off = LLAPRFile::seek(file_handle, APR_END, 0);
else
+ off = LLAPRFile::seek(file_handle, APR_SET, offset);
+
+ apr_size_t bytes_read;
+ if (off < 0)
{
- llassert_always(sz <= 0x7fffffff);
- return (S32)sz;
+ bytes_read = 0;
}
+ else
+ {
+ bytes_read = nbytes ;
+ apr_status_t s = apr_file_read(file_handle, buf, &bytes_read);
+ if (s != APR_SUCCESS)
+ {
+ bytes_read = 0;
+ }
+ else
+ {
+ llassert_always(bytes_read <= 0x7fffffff);
+ }
+ }
+
+ //*****************************************
+ close(file_handle, pool) ;
+ //*****************************************
+ return (S32)bytes_read;
}
-S32 ll_apr_file_write_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes)
+//static
+S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
{
- if (pool == NULL) pool = gAPRPoolp;
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
if (offset < 0)
{
flags |= APR_APPEND;
offset = 0;
}
- apr_file_t* filep = ll_apr_file_open(filename, flags, pool);
- if (!filep)
+
+ //*****************************************
+ apr_file_t* file_handle = open(filename, pool, flags);
+ //*****************************************
+ if (!file_handle)
{
return 0;
}
+
if (offset > 0)
{
- offset = ll_apr_file_seek(filep, APR_SET, offset);
+ offset = LLAPRFile::seek(file_handle, APR_SET, offset);
}
- S32 bytes_written;
+
+ apr_size_t bytes_written;
if (offset < 0)
{
bytes_written = 0;
}
else
{
- bytes_written = ll_apr_file_write(filep, buf, nbytes );
+ bytes_written = nbytes ;
+ apr_status_t s = apr_file_write(file_handle, buf, &bytes_written);
+ if (s != APR_SUCCESS)
+ {
+ bytes_written = 0;
+ }
+ else
+ {
+ llassert_always(bytes_written <= 0x7fffffff);
+ }
}
- apr_file_close(filep);
- return bytes_written;
-}
+ //*****************************************
+ LLAPRFile::close(file_handle, pool);
+ //*****************************************
-S32 ll_apr_file_seek(apr_file_t* apr_file, apr_seek_where_t where, S32 offset)
-{
- apr_status_t s;
- apr_off_t apr_offset;
- if (offset >= 0)
- {
- apr_offset = (apr_off_t)offset;
- s = apr_file_seek(apr_file, where, &apr_offset);
- }
- else
- {
- apr_offset = 0;
- s = apr_file_seek(apr_file, APR_END, &apr_offset);
- }
- if (s != APR_SUCCESS)
- {
- return -1;
- }
- else
- {
- llassert_always(apr_offset <= 0x7fffffff);
- return (S32)apr_offset;
- }
+ return (S32)bytes_written;
}
-bool ll_apr_file_remove(const std::string& filename, apr_pool_t* pool)
+//static
+bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
{
apr_status_t s;
- if (pool == NULL) pool = gAPRPoolp;
- 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)
{
- LL_DEBUGS("APR") << "ll_apr_file_remove failed on file: " << filename << LL_ENDL;
+ LL_DEBUGS("APR") << "LLAPRFile::remove failed on file: " << filename << LL_ENDL;
ll_apr_warn_status(s);
return false;
}
return true;
}
-bool ll_apr_file_rename(const std::string& filename, const std::string& newname, apr_pool_t* pool)
+//static
+bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool)
{
apr_status_t s;
- if (pool == NULL) pool = gAPRPoolp;
- 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)
{
- LL_DEBUGS("APR") << "ll_apr_file_rename failed on file: " << filename << LL_ENDL;
+ LL_DEBUGS("APR") << "LLAPRFile::rename failed on file: " << filename << LL_ENDL;
ll_apr_warn_status(s);
return false;
}
return true;
}
-bool ll_apr_file_exists(const std::string& filename, apr_pool_t* pool)
+//static
+bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags)
{
apr_file_t* apr_file;
apr_status_t s;
- if (pool == NULL) pool = gAPRPoolp;
- s = apr_file_open(&apr_file, filename.c_str(), APR_READ, 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 || !apr_file)
{
+ pool->clearVolatileAPRPool() ;
return false;
}
else
{
- apr_file_close(apr_file);
+ apr_file_close(apr_file) ;
+ pool->clearVolatileAPRPool() ;
return true;
}
}
-S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool)
+//static
+S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool)
{
apr_file_t* apr_file;
apr_finfo_t info;
apr_status_t s;
- if (pool == NULL) pool = gAPRPoolp;
- s = apr_file_open(&apr_file, 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 || !apr_file)
- {
+ {
+ pool->clearVolatileAPRPool() ;
+
return 0;
}
else
{
- apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
- apr_file_close(apr_file);
+ apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
+
+ apr_file_close(apr_file) ;
+ pool->clearVolatileAPRPool() ;
+
if (s == APR_SUCCESS)
{
return (S32)info.size;
@@ -381,31 +646,42 @@ S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool)
}
}
-bool ll_apr_dir_make(const std::string& dirname, apr_pool_t* pool)
+//static
+bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)
{
apr_status_t s;
- if (pool == NULL) pool = gAPRPoolp;
- 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_DEBUGS("APR") << "ll_apr_dir_make failed on file: " << dirname << LL_ENDL;
+ LL_DEBUGS("APR") << "LLAPRFile::makeDir failed on file: " << dirname << LL_ENDL;
ll_apr_warn_status(s);
return false;
}
return true;
}
-bool ll_apr_dir_remove(const std::string& dirname, apr_pool_t* pool)
+//static
+bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)
{
apr_status_t s;
- if (pool == NULL) pool = gAPRPoolp;
- 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)
{
- LL_DEBUGS("APR") << "ll_apr_dir_remove failed on file: " << dirname << LL_ENDL;
+ LL_DEBUGS("APR") << "LLAPRFile::removeDir failed on file: " << dirname << LL_ENDL;
ll_apr_warn_status(s);
return false;
}
return true;
}
-
+//
+//end of static components of LLAPRFile
+//*******************************************************************************************************************************
+//