diff options
Diffstat (limited to 'indra/llcommon/llapr.cpp')
-rw-r--r-- | indra/llcommon/llapr.cpp | 220 |
1 files changed, 142 insertions, 78 deletions
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 669afc5330..66ec5bad2c 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -4,31 +4,25 @@ * @date 2004-11-28 * @brief Helper functions for using the apache portable runtime library. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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$ */ @@ -57,7 +51,7 @@ void ll_init_apr() if(!LLAPRFile::sAPRFilePoolp) { - LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool() ; + LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; } } @@ -99,13 +93,12 @@ void ll_cleanup_apr() // //LLAPRPool // -LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) -{ - mParent = parent ; - mReleasePoolFlag = releasePoolFlag ; - mMaxSize = size ; - mPool = NULL ; - +LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) + : mParent(parent), + mReleasePoolFlag(releasePoolFlag), + mMaxSize(size), + mPool(NULL) +{ createAPRPool() ; } @@ -148,31 +141,65 @@ void LLAPRPool::releaseAPRPool() } } +//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) { - if(!mPool) + //create mutex + if(!is_local) //not a local apr_pool, that is: shared by multiple threads. { - createAPRPool() ; + apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex + apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool); } - - return mPool ; } -LLVolatileAPRPool::LLVolatileAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) - : LLAPRPool(parent, size, releasePoolFlag) + +LLVolatileAPRPool::~LLVolatileAPRPool() { - mNumActiveRef = 0 ; - mNumTotalRef = 0 ; + //delete mutex + if(mMutexp) + { + apr_thread_mutex_destroy(mMutexp); + apr_pool_destroy(mMutexPool); + } } -apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() +// +//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++ ; - return getAPRPool() ; + + if(!mPool) + { + createAPRPool() ; + } + + return mPool ; } void LLVolatileAPRPool::clearVolatileAPRPool() { + LLScopedLock lock(mMutexp) ; + if(mNumActiveRef > 0) { mNumActiveRef--; @@ -251,10 +278,9 @@ void LLScopedLock::unlock() bool ll_apr_warn_status(apr_status_t status) { if(APR_SUCCESS == status) return false; -#ifndef LL_WINDOWS char buf[MAX_STRING]; /* Flawfinder: ignore */ - LL_WARNS_ONCE("APR") << "APR: " << apr_strerror(status, buf, MAX_STRING) << LL_ENDL; -#endif + apr_strerror(status, buf, MAX_STRING); + LL_WARNS("APR") << "APR: " << buf << LL_ENDL; return true; } @@ -268,10 +294,18 @@ void ll_apr_assert_status(apr_status_t status) // LLAPRFile functions // LLAPRFile::LLAPRFile() + : mFile(NULL), + mCurrentFilePoolp(NULL) +{ +} + +LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool) + : mFile(NULL), + mCurrentFilePoolp(NULL) { - mFile = NULL ; - mCurrentFilePoolp = NULL ; + open(filename, flags, pool); } + LLAPRFile::~LLAPRFile() { close() ; @@ -295,11 +329,40 @@ apr_status_t LLAPRFile::close() return ret ; } -apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep) +apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool, S32* sizep) { apr_status_t s ; - s = open(filename, flags, pool ? pool->getVolatileAPRPool() : NULL, sizep) ; + + //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 ; + + if (sizep) + { + *sizep = 0; + } + } + else if (sizep) + { + S32 file_size = 0; + apr_off_t offset = 0; + if (apr_file_seek(mFile, APR_END, &offset) == APR_SUCCESS) + { + llassert_always(offset <= 0x7fffffff); + file_size = (S32)offset; + offset = 0; + apr_file_seek(mFile, APR_SET, &offset); + } + *sizep = file_size; + } + if(!mCurrentFilePoolp) { mCurrentFilePoolp = pool ; @@ -312,40 +375,25 @@ apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filenam return s ; } -apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool, S32* sizep) + +//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, getAPRFilePool(pool)); + s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, gAPRPoolp); if (s != APR_SUCCESS || !mFile) { mFile = NULL ; close() ; - if (sizep) - { - *sizep = 0; - } return s; } - if (sizep) - { - S32 file_size = 0; - apr_off_t offset = 0; - if (apr_file_seek(mFile, APR_END, &offset) == APR_SUCCESS) - { - llassert_always(offset <= 0x7fffffff); - file_size = (S32)offset; - offset = 0; - apr_file_seek(mFile, APR_SET, &offset); - } - *sizep = file_size; - } - return s; } @@ -363,12 +411,17 @@ apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool) // File I/O S32 LLAPRFile::read(void *buf, S32 nbytes) { - llassert_always(mFile) ; + if(!mFile) + { + llwarns << "apr mFile is removed by somebody else. Can not read." << llendl ; + return 0; + } apr_size_t sz = nbytes; apr_status_t s = apr_file_read(mFile, buf, &sz); if (s != APR_SUCCESS) { + ll_apr_warn_status(s); return 0; } else @@ -380,12 +433,17 @@ S32 LLAPRFile::read(void *buf, S32 nbytes) S32 LLAPRFile::write(const void *buf, S32 nbytes) { - llassert_always(mFile) ; + if(!mFile) + { + llwarns << "apr mFile is removed by somebody else. Can not write." << llendl ; + return 0; + } apr_size_t sz = nbytes; apr_status_t s = apr_file_write(mFile, buf, &sz); if (s != APR_SUCCESS) { + ll_apr_warn_status(s); return 0; } else @@ -434,6 +492,8 @@ apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool 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; @@ -464,6 +524,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) } if (s != APR_SUCCESS) { + ll_apr_warn_status(s); return -1; } else @@ -484,14 +545,13 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb return 0; } - S32 off; - if (offset < 0) - off = LLAPRFile::seek(file_handle, APR_END, 0); - else - off = LLAPRFile::seek(file_handle, APR_SET, offset); + llassert(offset >= 0); + + if (offset > 0) + offset = LLAPRFile::seek(file_handle, APR_SET, offset); apr_size_t bytes_read; - if (off < 0) + if (offset < 0) { bytes_read = 0; } @@ -501,6 +561,8 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb apr_status_t s = apr_file_read(file_handle, buf, &bytes_read); if (s != APR_SUCCESS) { + LL_WARNS("APR") << " Attempting to read filename: " << filename << LL_ENDL; + ll_apr_warn_status(s); bytes_read = 0; } else @@ -549,6 +611,8 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n apr_status_t s = apr_file_write(file_handle, buf, &bytes_written); if (s != APR_SUCCESS) { + LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL; + ll_apr_warn_status(s); bytes_written = 0; } else @@ -575,8 +639,8 @@ bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool) if (s != APR_SUCCESS) { - LL_DEBUGS("APR") << "LLAPRFile::remove failed on file: " << filename << LL_ENDL; ll_apr_warn_status(s); + LL_WARNS("APR") << " Attempting to remove filename: " << filename << LL_ENDL; return false; } return true; @@ -593,8 +657,8 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname, if (s != APR_SUCCESS) { - LL_DEBUGS("APR") << "LLAPRFile::rename failed on file: " << filename << LL_ENDL; ll_apr_warn_status(s); + LL_WARNS("APR") << " Attempting to rename filename: " << filename << LL_ENDL; return false; } return true; @@ -667,8 +731,8 @@ bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool) if (s != APR_SUCCESS) { - LL_DEBUGS("APR") << "LLAPRFile::makeDir failed on file: " << dirname << LL_ENDL; ll_apr_warn_status(s); + LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL; return false; } return true; @@ -685,8 +749,8 @@ bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool) if (s != APR_SUCCESS) { - LL_DEBUGS("APR") << "LLAPRFile::removeDir failed on file: " << dirname << LL_ENDL; ll_apr_warn_status(s); + LL_WARNS("APR") << " Attempting to remove directory: " << dirname << LL_ENDL; return false; } return true; |