Skip to content
Snippets Groups Projects
Commit abdc99f2 authored by Brad Kittenbrink's avatar Brad Kittenbrink
Browse files

Merge of QAR-1267 to trunk. This was a combo merge of QAR-1175...

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
parent 34412f05
No related branches found
No related tags found
No related merge requests found
Showing
with 730 additions and 171 deletions
...@@ -108,6 +108,9 @@ Carjay McGinnis ...@@ -108,6 +108,9 @@ Carjay McGinnis
Catherine Pfeffer Catherine Pfeffer
VWR-1282 VWR-1282
VWR-8624 VWR-8624
Celierra Darling
VWR-1274
VWR-6975
Dale Glass Dale Glass
VWR-120 VWR-120
VWR-560 VWR-560
...@@ -375,6 +378,7 @@ Renault Clio ...@@ -375,6 +378,7 @@ Renault Clio
VWR-1976 VWR-1976
Robin Cornelius Robin Cornelius
VWR-2488 VWR-2488
VWR-9557
Ryozu Kojima Ryozu Kojima
VWR-287 VWR-287
Sammy Frederix Sammy Frederix
......
...@@ -9,9 +9,9 @@ include(Variables) ...@@ -9,9 +9,9 @@ include(Variables)
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1") set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
set(CMAKE_CXX_FLAGS_RELEASE set(CMAKE_CXX_FLAGS_RELEASE
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG") "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"-DLL_RELEASE=1 -DLL_SEND_CRASH_REPORTS=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1") "-DLL_RELEASE=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
# Don't bother with a MinSizeRel build. # Don't bother with a MinSizeRel build.
...@@ -26,15 +26,18 @@ if (WINDOWS) ...@@ -26,15 +26,18 @@ if (WINDOWS)
# Don't build DLLs. # Don't build DLLs.
set(BUILD_SHARED_LIBS OFF) set(BUILD_SHARED_LIBS OFF)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MTd" set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd"
CACHE STRING "C++ compiler debug options" FORCE) CACHE STRING "C++ compiler debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MT" "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD"
CACHE STRING "C++ compiler release-with-debug options" FORCE) CACHE STRING "C++ compiler release-with-debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MT" "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD"
CACHE STRING "C++ compiler release options" FORCE) CACHE STRING "C++ compiler release options" FORCE)
set(CMAKE_CXX_STANDARD_LIBRARIES "")
set(CMAKE_C_STANDARD_LIBRARIES "")
add_definitions( add_definitions(
/DLL_WINDOWS=1 /DLL_WINDOWS=1
/DUNICODE /DUNICODE
......
# -*- cmake -*-
include(BerkeleyDB) include(BerkeleyDB)
include(Linking) include(Linking)
include(Prebuilt) include(Prebuilt)
...@@ -19,12 +17,14 @@ else (STANDALONE) ...@@ -19,12 +17,14 @@ else (STANDALONE)
debug ${ARCH_PREBUILT_DIRS_DEBUG}/apr-1.lib debug ${ARCH_PREBUILT_DIRS_DEBUG}/apr-1.lib
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/apr-1.lib optimized ${ARCH_PREBUILT_DIRS_RELEASE}/apr-1.lib
) )
set(APRICONV_LIBRARIES
debug ${ARCH_PREBUILT_DIRS_DEBUG}/apriconv-1.lib
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/apriconv-1.lib
)
set(APRUTIL_LIBRARIES set(APRUTIL_LIBRARIES
debug ${ARCH_PREBUILT_DIRS_DEBUG}/aprutil-1.lib debug ${ARCH_PREBUILT_DIRS_DEBUG}/aprutil-1.lib ${APRICONV_LIBRARIES}
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/aprutil-1.lib optimized ${ARCH_PREBUILT_DIRS_RELEASE}/aprutil-1.lib ${APRICONV_LIBRARIES}
) )
# Doesn't need to link with iconv.dll
set(APRICONV_LIBRARIES "")
elseif (DARWIN) elseif (DARWIN)
set(APR_LIBRARIES set(APR_LIBRARIES
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.a debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.a
......
...@@ -14,10 +14,18 @@ else (STANDALONE) ...@@ -14,10 +14,18 @@ else (STANDALONE)
set(VORBISFILE_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS}) set(VORBISFILE_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS})
if (WINDOWS) if (WINDOWS)
set(OGG_LIBRARIES ogg_static_mt) set(OGG_LIBRARIES
set(VORBIS_LIBRARIES vorbis_static_mt) optimized ogg_static
set(VORBISENC_LIBRARIES vorbisenc_static_mt) debug ogg_static_d)
set(VORBISFILE_LIBRARIES vorbisfile_static_mt) set(VORBIS_LIBRARIES
optimized vorbis_static
debug vorbis_static_d)
set(VORBISENC_LIBRARIES
optimized vorbisenc_static
debug vorbisenc_static_d)
set(VORBISFILE_LIBRARIES
optimized vorbisfile_static
debug vorbisfile_static_d)
else (WINDOWS) else (WINDOWS)
set(OGG_LIBRARIES ogg) set(OGG_LIBRARIES ogg)
set(VORBIS_LIBRARIES vorbis) set(VORBIS_LIBRARIES vorbis)
......
...@@ -28,14 +28,14 @@ else (STANDALONE) ...@@ -28,14 +28,14 @@ else (STANDALONE)
debug libboost_signals-vc71-mt-sgd-${BOOST_VERSION}) debug libboost_signals-vc71-mt-sgd-${BOOST_VERSION})
else (MSVC71) else (MSVC71)
set(BOOST_PROGRAM_OPTIONS_LIBRARY set(BOOST_PROGRAM_OPTIONS_LIBRARY
optimized libboost_program_options-vc80-mt-s-${BOOST_VERSION} optimized libboost_program_options-vc80-mt-${BOOST_VERSION}
debug libboost_program_options-vc80-mt-sgd-${BOOST_VERSION}) debug libboost_program_options-vc80-mt-gd-${BOOST_VERSION})
set(BOOST_REGEX_LIBRARY set(BOOST_REGEX_LIBRARY
optimized libboost_regex-vc80-mt-s-${BOOST_VERSION} optimized libboost_regex-vc80-mt-${BOOST_VERSION}
debug libboost_regex-vc80-mt-sgd-${BOOST_VERSION}) debug libboost_regex-vc80-mt-gd-${BOOST_VERSION})
set(BOOST_SIGNALS_LIBRARY set(BOOST_SIGNALS_LIBRARY
optimized libboost_signals-vc80-mt-s-${BOOST_VERSION} optimized libboost_signals-vc80-mt-${BOOST_VERSION}
debug libboost_signals-vc80-mt-sgd-${BOOST_VERSION}) debug libboost_signals-vc80-mt-gd-${BOOST_VERSION})
endif (MSVC71) endif (MSVC71)
elseif (DARWIN) elseif (DARWIN)
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
......
...@@ -5,6 +5,11 @@ if (STANDALONE) ...@@ -5,6 +5,11 @@ if (STANDALONE)
include(FindGooglePerfTools) include(FindGooglePerfTools)
else (STANDALONE) else (STANDALONE)
use_prebuilt_binary(google) use_prebuilt_binary(google)
if (WINDOWS)
set(TCMALLOC_LIBRARIES
debug libtcmalloc_minimal-debug
optimized libtcmalloc_minimal-debug)
endif (WINDOWS)
if (LINUX) if (LINUX)
set(TCMALLOC_LIBRARIES tcmalloc) set(TCMALLOC_LIBRARIES tcmalloc)
set(STACKTRACE_LIBRARIES stacktrace) set(STACKTRACE_LIBRARIES stacktrace)
......
...@@ -17,7 +17,7 @@ else (STANDALONE) ...@@ -17,7 +17,7 @@ else (STANDALONE)
debug ${ARCH_PREBUILT_DIRS_DEBUG}/liblljpeg.a debug ${ARCH_PREBUILT_DIRS_DEBUG}/liblljpeg.a
) )
elseif (WINDOWS) elseif (WINDOWS)
set(JPEG_LIBRARIES jpeglib_6b) set(JPEG_LIBRARIES jpeglib)
endif (LINUX) endif (LINUX)
set(JPEG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) set(JPEG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
endif (STANDALONE) endif (STANDALONE)
...@@ -18,8 +18,8 @@ endif (SERVER AND LINUX) ...@@ -18,8 +18,8 @@ endif (SERVER AND LINUX)
# mapserver requires certain files to be copied so LL_MESA_HEADLESS can be set # mapserver requires certain files to be copied so LL_MESA_HEADLESS can be set
# differently for different object files. # differently for different object files.
macro (copy_server_sources _copied_SOURCES) macro (copy_server_sources )
foreach (PREFIX ${_copied_SOURCES}) foreach (PREFIX ${ARGV})
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
......
...@@ -40,4 +40,9 @@ else (SERVER AND LINUX) ...@@ -40,4 +40,9 @@ else (SERVER AND LINUX)
set(LLWINDOW_LIBRARIES set(LLWINDOW_LIBRARIES
llwindow llwindow
) )
if (WINDOWS)
list(APPEND LLWINDOW_LIBRARIES
comdlg32
)
endif (WINDOWS)
endif (SERVER AND LINUX) endif (SERVER AND LINUX)
...@@ -32,11 +32,16 @@ endif (LINUX) ...@@ -32,11 +32,16 @@ endif (LINUX)
if (WINDOWS) if (WINDOWS)
set(WINDOWS_LIBRARIES set(WINDOWS_LIBRARIES
advapi32
shell32
ws2_32 ws2_32
mswsock mswsock
psapi psapi
winmm winmm
netapi32 netapi32
wldap32
gdi32
user32
) )
else (WINDOWS) else (WINDOWS)
set(WINDOWS_LIBRARIES "") set(WINDOWS_LIBRARIES "")
......
...@@ -8,6 +8,12 @@ if (STANDALONE) ...@@ -8,6 +8,12 @@ if (STANDALONE)
include(FindPNG) include(FindPNG)
else (STANDALONE) else (STANDALONE)
use_prebuilt_binary(libpng) use_prebuilt_binary(libpng)
set(PNG_LIBRARIES png12) if (WINDOWS)
set(PNG_LIBRARIES
debug libpngd
optimized libpng)
else (WINDOWS)
set(PNG_LIBRARIES png12)
endif (WINDOWS)
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
endif (STANDALONE) endif (STANDALONE)
...@@ -10,7 +10,9 @@ if (STANDALONE) ...@@ -10,7 +10,9 @@ if (STANDALONE)
else (STANDALONE) else (STANDALONE)
use_prebuilt_binary(zlib) use_prebuilt_binary(zlib)
if (WINDOWS) if (WINDOWS)
set(ZLIB_LIBRARIES zlib) set(ZLIB_LIBRARIES
debug zlibd
optimized zlib)
else (WINDOWS) else (WINDOWS)
set(ZLIB_LIBRARIES z) set(ZLIB_LIBRARIES z)
endif (WINDOWS) endif (WINDOWS)
......
...@@ -178,7 +178,9 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) ...@@ -178,7 +178,9 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName); std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName);
apr_file_t *fp = ll_apr_file_open(path, LL_APR_R); LLAPRFile infile ;
infile.open(path, LL_APR_R);
apr_file_t *fp = infile.getFileHandle();
if (!fp) if (!fp)
return ST_NO_XLT_FILE; return ST_NO_XLT_FILE;
...@@ -187,8 +189,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) ...@@ -187,8 +189,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// register file to be closed on function exit // register file to be closed on function exit
//-------------------------------------------------------------------- //--------------------------------------------------------------------
FileCloser fileCloser(fp);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// load header // load header
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -618,6 +619,8 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) ...@@ -618,6 +619,8 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
} }
} }
infile.close() ;
return ST_OK; return ST_OK;
} }
......
...@@ -354,7 +354,9 @@ BOOL LLKeyframeMotionParam::loadMotions() ...@@ -354,7 +354,9 @@ BOOL LLKeyframeMotionParam::loadMotions()
// open the file // open the file
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
S32 fileSize = 0; S32 fileSize = 0;
apr_file_t* fp = ll_apr_file_open(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) if (!fp || fileSize == 0)
{ {
llinfos << "ERROR: can't open: " << path << llendl; llinfos << "ERROR: can't open: " << path << llendl;
...@@ -366,7 +368,6 @@ BOOL LLKeyframeMotionParam::loadMotions() ...@@ -366,7 +368,6 @@ BOOL LLKeyframeMotionParam::loadMotions()
if ( !text ) if ( !text )
{ {
llinfos << "ERROR: can't allocated keyframe text buffer." << llendl; llinfos << "ERROR: can't allocated keyframe text buffer." << llendl;
apr_file_close(fp);
return FALSE; return FALSE;
} }
...@@ -393,7 +394,7 @@ BOOL LLKeyframeMotionParam::loadMotions() ...@@ -393,7 +394,7 @@ BOOL LLKeyframeMotionParam::loadMotions()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// close the file // close the file
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
apr_file_close( fp ); infile.close();
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// check for error // check for error
......
...@@ -209,7 +209,9 @@ LLFSMState* LLStateDiagram::getState(U32 state_id) ...@@ -209,7 +209,9 @@ LLFSMState* LLStateDiagram::getState(U32 state_id)
BOOL LLStateDiagram::saveDotFile(const std::string& filename) BOOL LLStateDiagram::saveDotFile(const std::string& filename)
{ {
apr_file_t* dot_file = ll_apr_file_open(filename, LL_APR_W); LLAPRFile outfile ;
outfile.open(filename, LL_APR_W);
apr_file_t* dot_file = outfile.getFileHandle() ;
if (!dot_file) if (!dot_file)
{ {
...@@ -258,8 +260,6 @@ BOOL LLStateDiagram::saveDotFile(const std::string& filename) ...@@ -258,8 +260,6 @@ BOOL LLStateDiagram::saveDotFile(const std::string& filename)
apr_file_printf(dot_file, "}\n"); apr_file_printf(dot_file, "}\n");
apr_file_close(dot_file);
return TRUE; return TRUE;
} }
......
...@@ -36,8 +36,10 @@ ...@@ -36,8 +36,10 @@
#include "llapr.h" #include "llapr.h"
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool 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 *gLogMutexp = NULL;
const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
void ll_init_apr() void ll_init_apr()
{ {
...@@ -46,10 +48,15 @@ void ll_init_apr() ...@@ -46,10 +48,15 @@ void ll_init_apr()
// Initialize APR and create the global pool // Initialize APR and create the global pool
apr_initialize(); apr_initialize();
apr_pool_create(&gAPRPoolp, NULL); apr_pool_create(&gAPRPoolp, NULL);
// Initialize the logging mutex // Initialize the logging mutex
apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); 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() ...@@ -70,31 +77,127 @@ void ll_cleanup_apr()
apr_pool_destroy(gAPRPoolp); apr_pool_destroy(gAPRPoolp);
gAPRPoolp = NULL; gAPRPoolp = NULL;
} }
if (LLAPRFile::sAPRFilePoolp)
{
delete LLAPRFile::sAPRFilePoolp ;
LLAPRFile::sAPRFilePoolp = NULL ;
}
apr_terminate(); apr_terminate();
} }
//
// //
//LLAPRPool //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); apr_allocator_t *allocator = apr_pool_allocator_get(mPool);
if (allocator) 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 // LLScopedLock
// //
...@@ -133,9 +236,8 @@ void LLScopedLock::unlock() ...@@ -133,9 +236,8 @@ void LLScopedLock::unlock()
} }
} }
// //---------------------------------------------------------------------
// Misc functions
//
bool ll_apr_warn_status(apr_status_t status) bool ll_apr_warn_status(apr_status_t status)
{ {
if(APR_SUCCESS == status) return false; if(APR_SUCCESS == status) return false;
...@@ -151,55 +253,110 @@ void ll_apr_assert_status(apr_status_t status) ...@@ -151,55 +253,110 @@ void ll_apr_assert_status(apr_status_t status)
llassert(ll_apr_warn_status(status) == false); 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; apr_status_t s;
if (pool == NULL) pool = gAPRPoolp;
s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool); //check if already open some file
if (s != APR_SUCCESS) 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) if (sizep)
{ {
*sizep = 0; *sizep = 0;
} }
return NULL; return s;
} }
if (sizep) if (sizep)
{ {
S32 file_size = 0; S32 file_size = 0;
apr_off_t offset = 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); llassert_always(offset <= 0x7fffffff);
file_size = (S32)offset; file_size = (S32)offset;
offset = 0; offset = 0;
apr_file_seek(apr_file, APR_SET, &offset); apr_file_seek(mFile, APR_SET, &offset);
} }
*sizep = file_size; *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)
{ apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool)
return ll_apr_file_open(filename, flags, sizep, NULL); {
} if(!pool)
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool) {
{ mCurrentFilePoolp = sAPRFilePoolp ;
return ll_apr_file_open(filename, flags, NULL, pool); return mCurrentFilePoolp->getVolatileAPRPool() ;
} }
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags)
{ return pool ;
return ll_apr_file_open(filename, flags, NULL, NULL);
} }
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_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) if (s != APR_SUCCESS)
{ {
return 0; return 0;
...@@ -211,165 +368,273 @@ S32 ll_apr_file_read(apr_file_t* apr_file, void *buf, S32 nbytes) ...@@ -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; llassert_always(mFile) ;
apr_file_t* filep = ll_apr_file_open(filename, APR_READ|APR_BINARY, pool);
if (!filep) apr_size_t sz = nbytes;
apr_status_t s = apr_file_write(mFile, buf, &sz);
if (s != APR_SUCCESS)
{ {
return 0; return 0;
} }
S32 off;
if (offset < 0)
off = ll_apr_file_seek(filep, APR_END, 0);
else 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_status_t s = apr_file_write(apr_file, buf, &sz); 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) 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; return 0;
} }
S32 off;
if (offset < 0)
off = LLAPRFile::seek(file_handle, APR_END, 0);
else else
off = LLAPRFile::seek(file_handle, APR_SET, offset);
apr_size_t bytes_read;
if (off < 0)
{ {
llassert_always(sz <= 0x7fffffff); bytes_read = 0;
return (S32)sz;
} }
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; apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
if (offset < 0) if (offset < 0)
{ {
flags |= APR_APPEND; flags |= APR_APPEND;
offset = 0; 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; return 0;
} }
if (offset > 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) if (offset < 0)
{ {
bytes_written = 0; bytes_written = 0;
} }
else 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) return (S32)bytes_written;
{
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;
}
} }
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; 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) 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); ll_apr_warn_status(s);
return false; return false;
} }
return true; 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; 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) 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); ll_apr_warn_status(s);
return false; return false;
} }
return true; 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_file_t* apr_file;
apr_status_t s; 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) if (s != APR_SUCCESS || !apr_file)
{ {
pool->clearVolatileAPRPool() ;
return false; return false;
} }
else else
{ {
apr_file_close(apr_file); apr_file_close(apr_file) ;
pool->clearVolatileAPRPool() ;
return true; 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_file_t* apr_file;
apr_finfo_t info; apr_finfo_t info;
apr_status_t s; 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) if (s != APR_SUCCESS || !apr_file)
{ {
pool->clearVolatileAPRPool() ;
return 0; return 0;
} }
else else
{ {
apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file); apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file);
apr_file_close(apr_file);
apr_file_close(apr_file) ;
pool->clearVolatileAPRPool() ;
if (s == APR_SUCCESS) if (s == APR_SUCCESS)
{ {
return (S32)info.size; return (S32)info.size;
...@@ -381,31 +646,42 @@ S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool) ...@@ -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; 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) 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); ll_apr_warn_status(s);
return false; return false;
} }
return true; 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; 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) 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); ll_apr_warn_status(s);
return false; return false;
} }
return true; return true;
} }
//
//end of static components of LLAPRFile
//*******************************************************************************************************************************
//
...@@ -61,18 +61,51 @@ void ll_init_apr(); ...@@ -61,18 +61,51 @@ void ll_init_apr();
*/ */
void ll_cleanup_apr(); void ll_cleanup_apr();
//
//LL apr_pool
//manage apr_pool_t, destroy allocated apr_pool in the destruction function.
//
class LLAPRPool class LLAPRPool
{ {
public: public:
LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0) ; LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ;
~LLAPRPool() ; ~LLAPRPool() ;
apr_pool_t* getAPRPool() {return mPool ; } apr_pool_t* getAPRPool() ;
apr_status_t getStatus() {return mStatus ; } 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 LLVolatileAPRPool : public LLAPRPool
{
public:
LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
~LLVolatileAPRPool(){}
apr_pool_t* getVolatileAPRPool() ;
void clearVolatileAPRPool() ;
BOOL isFull() ;
BOOL isEmpty() {return !mNumActiveRef ;}
private: private:
apr_pool_t* mPool ; S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
apr_status_t mStatus ; S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating.
} ; } ;
/** /**
...@@ -145,24 +178,71 @@ typedef LLAtomic32<S32> LLAtomicS32; ...@@ -145,24 +178,71 @@ typedef LLAtomic32<S32> LLAtomicS32;
#define LL_APR_WB (APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY) // "wb" #define LL_APR_WB (APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY) // "wb"
#define LL_APR_RPB (APR_READ|APR_WRITE|APR_BINARY) // "r+b" #define LL_APR_RPB (APR_READ|APR_WRITE|APR_BINARY) // "r+b"
#define LL_APR_WPB (APR_CREATE|APR_TRUNCATE|APR_READ|APR_WRITE|APR_BINARY) // "w+b" #define LL_APR_WPB (APR_CREATE|APR_TRUNCATE|APR_READ|APR_WRITE|APR_BINARY) // "w+b"
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep, apr_pool_t* pool);
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, S32* sizep); //
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool); //apr_file manager
apr_file_t* ll_apr_file_open(const std::string& filename, apr_int32_t flags); //which: 1)only keeps one file open;
// Returns actual offset, -1 if seek fails // 2)closes the open file in the destruction function
S32 ll_apr_file_seek(apr_file_t* apr_file, apr_seek_where_t where, S32 offset); // 3)informs the apr_pool to clean the memory when the file is closed.
// Returns bytes read/written, 0 if read/write fails: //Note: please close an open file at the earliest convenience.
S32 ll_apr_file_read(apr_file_t* apr_file, void* buf, S32 nbytes); // especially do not put some time-costly operations between open() and close().
S32 ll_apr_file_read_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes); // otherwise it might lock the APRFilePool.
S32 ll_apr_file_write(apr_file_t* apr_file, const void* buf, S32 nbytes); //there are two different apr_pools the APRFile can use:
S32 ll_apr_file_write_ex(const std::string& filename, apr_pool_t* pool, void *buf, S32 offset, S32 nbytes); // 1, a temperary pool passed to an APRFile function, which is used within this function and only once.
// returns false if failure: // 2, a global pool.
bool ll_apr_file_remove(const std::string& filename, apr_pool_t* pool = NULL); //
bool ll_apr_file_rename(const std::string& filename, const std::string& newname, apr_pool_t* pool = NULL); class LLAPRFile
bool ll_apr_file_exists(const std::string& filename, apr_pool_t* pool = NULL); {
S32 ll_apr_file_size(const std::string& filename, apr_pool_t* pool = NULL); private:
bool ll_apr_dir_make(const std::string& dirname, apr_pool_t* pool = NULL); apr_file_t* mFile ;
bool ll_apr_dir_remove(const std::string& dirname, apr_pool_t* pool = NULL); LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool.
public:
LLAPRFile() ;
~LLAPRFile() ;
apr_status_t open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep = NULL);
apr_status_t open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool = NULL, S32* sizep = NULL);
apr_status_t close() ;
// Returns actual offset, -1 if seek fails
S32 seek(apr_seek_where_t where, S32 offset);
apr_status_t eof() { return apr_file_eof(mFile);}
// Returns bytes read/written, 0 if read/write fails:
S32 read(void* buf, S32 nbytes);
S32 write(const void* buf, S32 nbytes);
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, 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, LLVolatileAPRPool* pool = NULL);
static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);
//*******************************************************************************************************************************
};
/** /**
* @brief Function which approprately logs error or remains quiet on * @brief Function which approprately logs error or remains quiet on
......
...@@ -197,6 +197,10 @@ void LLCRC::update(const std::string& filename) ...@@ -197,6 +197,10 @@ void LLCRC::update(const std::string& filename)
update(data, nread); update(data, nread);
delete[] data; delete[] data;
} }
else
{
fclose(fp);
}
} }
} }
......
...@@ -990,6 +990,38 @@ namespace LLError ...@@ -990,6 +990,38 @@ namespace LLError
return new std::ostringstream; return new std::ostringstream;
} }
void Log::flush(std::ostringstream* out, char* message)
{
LogLock lock;
if (!lock.ok())
{
return;
}
if(strlen(out->str().c_str()) < 128)
{
strcpy(message, out->str().c_str());
}
else
{
strncpy(message, out->str().c_str(), 127);
message[127] = '\0' ;
}
Globals& g = Globals::get();
if (out == &g.messageStream)
{
g.messageStream.clear();
g.messageStream.str("");
g.messageStreamInUse = false;
}
else
{
delete out;
}
return ;
}
void Log::flush(std::ostringstream* out, const CallSite& site) void Log::flush(std::ostringstream* out, const CallSite& site)
{ {
...@@ -1205,3 +1237,94 @@ namespace LLError ...@@ -1205,3 +1237,94 @@ namespace LLError
} }
} }
namespace LLError
{
char** LLCallStacks::sBuffer = NULL ;
S32 LLCallStacks::sIndex = 0 ;
//static
void LLCallStacks::push(const char* function, const int line)
{
if(!sBuffer)
{
sBuffer = new char*[512] ;
sBuffer[0] = new char[512 * 128] ;
for(S32 i = 1 ; i < 512 ; i++)
{
sBuffer[i] = sBuffer[i-1] + 128 ;
}
sIndex = 0 ;
}
if(sIndex > 511)
{
clear() ;
}
strcpy(sBuffer[sIndex], function) ;
sprintf(sBuffer[sIndex] + strlen(function), " line: %d ", line) ;
sIndex++ ;
return ;
}
//static
std::ostringstream* LLCallStacks::insert(const char* function, const int line)
{
std::ostringstream* _out = LLError::Log::out();
*_out << function << " line " << line << " " ;
return _out ;
}
//static
void LLCallStacks::end(std::ostringstream* _out)
{
if(!sBuffer)
{
sBuffer = new char*[512] ;
sBuffer[0] = new char[512 * 128] ;
for(S32 i = 1 ; i < 512 ; i++)
{
sBuffer[i] = sBuffer[i-1] + 128 ;
}
sIndex = 0 ;
}
if(sIndex > 511)
{
clear() ;
}
LLError::Log::flush(_out, sBuffer[sIndex++]) ;
}
//static
void LLCallStacks::print()
{
if(sIndex > 0)
{
llinfos << " ************* PRINT OUT LL CALL STACKS ************* " << llendl ;
while(sIndex > 0)
{
sIndex-- ;
llinfos << sBuffer[sIndex] << llendl ;
}
llinfos << " *************** END OF LL CALL STACKS *************** " << llendl ;
}
if(sBuffer)
{
delete[] sBuffer[0] ;
delete[] sBuffer ;
sBuffer = NULL ;
}
}
//static
void LLCallStacks::clear()
{
sIndex = 0 ;
}
}
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <typeinfo> #include <typeinfo>
#include "llerrorlegacy.h" #include "llerrorlegacy.h"
#include "stdtypes.h"
/* Error Logging Facility /* Error Logging Facility
...@@ -135,6 +136,7 @@ namespace LLError ...@@ -135,6 +136,7 @@ namespace LLError
public: public:
static bool shouldLog(CallSite&); static bool shouldLog(CallSite&);
static std::ostringstream* out(); static std::ostringstream* out();
static void flush(std::ostringstream* out, char* message) ;
static void flush(std::ostringstream*, const CallSite&); static void flush(std::ostringstream*, const CallSite&);
}; };
...@@ -179,9 +181,41 @@ namespace LLError ...@@ -179,9 +181,41 @@ namespace LLError
class NoClassInfo { }; class NoClassInfo { };
// used to indicate no class info known for logging // used to indicate no class info known for logging
}
//LLCallStacks keeps track of call stacks and output the call stacks to log file
//when LLAppViewer::handleViewerCrash() is triggered.
//
//Note: to be simple, efficient and necessary to keep track of correct call stacks,
//LLCallStacks is designed not to be thread-safe.
//so try not to use it in multiple parallel threads at same time.
//Used in a single thread at a time is fine.
class LLCallStacks
{
private:
static char** sBuffer ;
static S32 sIndex ;
public:
static void push(const char* function, const int line) ;
static std::ostringstream* insert(const char* function, const int line) ;
static void print() ;
static void clear() ;
static void end(std::ostringstream* _out) ;
};
}
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
#define llpushcallstacks LLError::LLCallStacks::push(__FUNCTION__, __LINE__)
#define llcallstacks \
{\
std::ostringstream* _out = LLError::LLCallStacks::insert(__FUNCTION__, __LINE__) ; \
(*_out)
#define llcallstacksendl \
LLError::End(); \
LLError::LLCallStacks::end(_out) ; \
}
#define llclearcallstacks LLError::LLCallStacks::clear()
#define llprintcallstacks LLError::LLCallStacks::print()
/* /*
Class type information for logging Class type information for logging
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment