summaryrefslogtreecommitdiff
path: root/indra/llcommon/llerror.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llerror.cpp')
-rw-r--r--indra/llcommon/llerror.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index d671decccb..b135dafb3c 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -1223,9 +1223,62 @@ namespace LLError
char** LLCallStacks::sBuffer = NULL ;
S32 LLCallStacks::sIndex = 0 ;
+ class CallStacksLogLock
+ {
+ public:
+ CallStacksLogLock();
+ ~CallStacksLogLock();
+ bool ok() const { return mOK; }
+ private:
+ bool mLocked;
+ bool mOK;
+ };
+
+ CallStacksLogLock::CallStacksLogLock()
+ : mLocked(false), mOK(false)
+ {
+ if (!gCallStacksLogMutexp)
+ {
+ mOK = true;
+ return;
+ }
+
+ const int MAX_RETRIES = 5;
+ for (int attempts = 0; attempts < MAX_RETRIES; ++attempts)
+ {
+ apr_status_t s = apr_thread_mutex_trylock(gCallStacksLogMutexp);
+ if (!APR_STATUS_IS_EBUSY(s))
+ {
+ mLocked = true;
+ mOK = true;
+ return;
+ }
+
+ ms_sleep(1);
+ }
+
+ // We're hosed, we can't get the mutex. Blah.
+ std::cerr << "CallStacksLogLock::CallStacksLogLock: failed to get mutex for log"
+ << std::endl;
+ }
+
+ CallStacksLogLock::~CallStacksLogLock()
+ {
+ if (mLocked)
+ {
+ apr_thread_mutex_unlock(gCallStacksLogMutexp);
+ }
+ }
+
//static
void LLCallStacks::push(const char* function, const int line)
{
+ CallStacksLogLock lock;
+ if (!lock.ok())
+ {
+ return;
+ }
+
if(!sBuffer)
{
sBuffer = new char*[512] ;
@@ -1261,6 +1314,12 @@ namespace LLError
//static
void LLCallStacks::end(std::ostringstream* _out)
{
+ CallStacksLogLock lock;
+ if (!lock.ok())
+ {
+ return;
+ }
+
if(!sBuffer)
{
sBuffer = new char*[512] ;
@@ -1283,6 +1342,12 @@ namespace LLError
//static
void LLCallStacks::print()
{
+ CallStacksLogLock lock;
+ if (!lock.ok())
+ {
+ return;
+ }
+
if(sIndex > 0)
{
llinfos << " ************* PRINT OUT LL CALL STACKS ************* " << llendl ;