diff --git a/indra/cwdebug/debug.h b/indra/cwdebug/debug.h
index 4161e18f7..b704c811d 100644
--- a/indra/cwdebug/debug.h
+++ b/indra/cwdebug/debug.h
@@ -49,6 +49,7 @@
#else // LL_COMMON_LINK_SHARED
#error LL_COMMON_LINK_SHARED not defined
#endif // LL_COMMON_LINK_SHARED
+#include "aithreadid.h"
// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
// some of the cwd macro's with something that generates viewer
@@ -104,23 +105,23 @@ struct fake_channel {
void on() const { }
void off() const { }
};
-extern CWD_API fake_channel const warning;
-extern CWD_API fake_channel const curl;
-extern CWD_API fake_channel const curlio;
-extern CWD_API fake_channel const statemachine;
-extern CWD_API fake_channel const notice;
+extern LL_COMMON_API fake_channel const warning;
+extern LL_COMMON_API fake_channel const curl;
+extern LL_COMMON_API fake_channel const curlio;
+extern LL_COMMON_API fake_channel const statemachine;
+extern LL_COMMON_API fake_channel const notice;
} // namespace dc
} // namespace debug
#define Debug(x) do { using namespace debug; x; } while(0)
-#define Dout(a, b) do { using namespace debug; if ((a).mOn) { llinfos_nf << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
+#define Dout(a, b) do { using namespace debug; if ((a).mOn) { llinfos_nf << AIThreadID::DoutPrint << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
#define DoutEntering(a, b) \
int __slviewer_debug_indentation = 2; \
{ \
using namespace debug; \
if ((a).mOn) \
- llinfos_nf << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
+ llinfos_nf << AIThreadID::DoutPrint << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
else \
__slviewer_debug_indentation = 0; \
} \
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 4be690734..cf1e564ae 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -15,8 +15,9 @@ include_directories(
)
set(llcommon_SOURCE_FILES
- aiframetimer.cpp
- imageids.cpp
+ aiframetimer.cpp
+ aithreadid.cpp
+ imageids.cpp
indra_constants.cpp
llallocator.cpp
llallocator_heap_profile.cpp
@@ -24,7 +25,7 @@ set(llcommon_SOURCE_FILES
llapr.cpp
llaprpool.cpp
llassettype.cpp
- llavatarname.cpp
+ llavatarname.cpp
llbase32.cpp
llbase64.cpp
llcommon.cpp
@@ -103,6 +104,7 @@ set(llcommon_HEADER_FILES
CMakeLists.txt
aiframetimer.h
+ aithreadid.h
aithreadsafe.h
bitpack.h
ctype_workaround.h
diff --git a/indra/llcommon/aithreadid.cpp b/indra/llcommon/aithreadid.cpp
new file mode 100644
index 000000000..dfb4a2660
--- /dev/null
+++ b/indra/llcommon/aithreadid.cpp
@@ -0,0 +1,70 @@
+/**
+ * @file aithreadid.cpp
+ *
+ * Copyright (c) 2012, Aleric Inglewood.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * 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.
+ *
+ * CHANGELOG
+ * and additional copyright holders.
+ *
+ * 08/08/2012
+ * - Initial version, written by Aleric Inglewood @ SL
+ */
+
+#include "sys.h"
+#include
+#include
+#include "aithreadid.h"
+
+AIThreadID const AIThreadID::sNone(AIThreadID::none);
+apr_os_thread_t AIThreadID::sMainThreadID;
+#ifndef LL_DARWIN
+apr_os_thread_t ll_thread_local AIThreadID::lCurrentThread = AIThreadID::undefinedID;
+#endif
+
+void AIThreadID::set_main_thread_id(void)
+{
+ sMainThreadID = apr_os_thread_current();
+}
+
+void AIThreadID::set_current_thread_id(void)
+{
+#ifndef LL_DARWIN
+ lCurrentThread = apr_os_thread_current();
+#endif
+}
+
+std::ostream& operator<<(std::ostream& os, AIThreadID const& id)
+{
+ return os << id.mID;
+}
+
+std::ostream& operator<<(std::ostream& os, AIThreadID::dout_print_t)
+{
+ if (!AIThreadID::in_main_thread())
+ {
+#ifdef LL_DARWIN
+ os << std::hex << (size_t)apr_os_thread_current() << std::dec << ' ';
+#else
+ os << std::hex << (size_t)AIThreadID::lCurrentThread << std::dec << ' ';
+#endif
+ }
+ return os;
+}
+
diff --git a/indra/llcommon/aithreadid.h b/indra/llcommon/aithreadid.h
new file mode 100644
index 000000000..c565b5913
--- /dev/null
+++ b/indra/llcommon/aithreadid.h
@@ -0,0 +1,91 @@
+/**
+ * @file aithreadid.h
+ * @brief Declaration of AIThreadID.
+ *
+ * Copyright (c) 2012, Aleric Inglewood.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * 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.
+ *
+ * CHANGELOG
+ * and additional copyright holders.
+ *
+ * 08/08/2012
+ * Initial version, written by Aleric Inglewood @ SL
+ */
+
+#ifndef AI_THREAD_ID
+#define AI_THREAD_ID
+
+#include // apr_os_thread_t, apr_os_thread_current(), apr_os_thread_equal().
+#include // std::ostream.
+#include "llpreprocessor.h" // LL_COMMON_API
+#include "llerror.h"
+
+#if LL_WINDOWS
+#define ll_thread_local __declspec(thread)
+#else
+#define ll_thread_local __thread
+#endif
+
+// Lightweight wrapper around apr_os_thread_t.
+// This class introduces no extra assembly code after optimization; it's only intend is to provide type-safety.
+class LL_COMMON_API AIThreadID
+{
+private:
+ apr_os_thread_t mID;
+ static apr_os_thread_t sMainThreadID;
+ static apr_os_thread_t const undefinedID = (apr_os_thread_t)-1;
+#ifndef LL_DARWIN
+ static ll_thread_local apr_os_thread_t lCurrentThread;
+#endif
+public:
+ static AIThreadID const sNone;
+ enum undefined_thread_t { none };
+ enum dout_print_t { DoutPrint };
+
+public:
+ AIThreadID(void) : mID(apr_os_thread_current()) { }
+ explicit AIThreadID(undefined_thread_t) : mID(undefinedID) { } // Used for sNone.
+ AIThreadID(AIThreadID const& id) : mID(id.mID) { }
+ AIThreadID& operator=(AIThreadID const& id) { mID = id.mID; return *this; }
+ bool is_main_thread(void) const { return apr_os_thread_equal(mID, sMainThreadID); }
+ bool is_no_thread(void) const { return apr_os_thread_equal(mID, sNone.mID); }
+ friend LL_COMMON_API bool operator==(AIThreadID const& id1, AIThreadID const& id2) { return apr_os_thread_equal(id1.mID, id2.mID); }
+ friend LL_COMMON_API bool operator!=(AIThreadID const& id1, AIThreadID const& id2) { return !apr_os_thread_equal(id1.mID, id2.mID); }
+ friend LL_COMMON_API std::ostream& operator<<(std::ostream& os, AIThreadID const& id);
+ friend LL_COMMON_API std::ostream& operator<<(std::ostream& os, dout_print_t);
+ static void set_main_thread_id(void); // Called once to set sMainThreadID.
+ static void set_current_thread_id(void); // Called once for every thread to set lCurrentThread.
+#ifdef LL_DARWIN
+ void reset(void) { mID = apr_os_thread_current(); }
+ bool equals_current_thread(void) const { return apr_os_thread_equal(mID, apr_os_thread_current()); }
+ static bool in_main_thread(void) { return apr_os_thread_equal(apr_os_thread_current(), sMainThreadID); }
+#else
+ void reset(void) { mID = lCurrentThread; }
+ bool equals_current_thread(void) const { return apr_os_thread_equal(mID, lCurrentThread); }
+ static bool in_main_thread(void) { return apr_os_thread_equal(lCurrentThread, sMainThreadID); }
+#endif
+};
+
+// Legacy function.
+inline bool is_main_thread(void)
+{
+ return AIThreadID::in_main_thread();
+}
+
+#endif // AI_THREAD_ID
diff --git a/indra/llcommon/aithreadsafe.h b/indra/llcommon/aithreadsafe.h
index b7d0045cb..02bfa8cd7 100644
--- a/indra/llcommon/aithreadsafe.h
+++ b/indra/llcommon/aithreadsafe.h
@@ -673,18 +673,18 @@ protected:
#ifdef LL_DEBUG
mutable bool mAccessed;
- mutable apr_os_thread_t mTheadID;
+ mutable AIThreadID mTheadID;
void accessed(void) const
{
if (!mAccessed)
{
mAccessed = true;
- mTheadID = apr_os_thread_current();
+ mTheadID.reset();
}
else
{
- llassert_always(apr_os_thread_equal(mTheadID, apr_os_thread_current()));
+ llassert_always(mTheadID.equals_current_thread());
}
}
#endif
diff --git a/indra/llcommon/llaprpool.cpp b/indra/llcommon/llaprpool.cpp
index 3559ff430..de5761157 100644
--- a/indra/llcommon/llaprpool.cpp
+++ b/indra/llcommon/llaprpool.cpp
@@ -60,10 +60,10 @@ void LLAPRPool::create(LLAPRPool& parent)
//
// 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();
+ mOwner.reset();
#else
mOwner = mParent->mOwner;
- llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ llassert(mOwner.equals_current_thread());
#endif
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
llassert_always(apr_pool_create_status == APR_SUCCESS);
@@ -83,7 +83,7 @@ void LLAPRPool::destroy(void)
// 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()));
+ llassert(!mParent || mParent->mOwner.equals_current_thread());
#endif
apr_pool_t* pool = mPool;
mPool = NULL; // Mark that we are BEING destructed.
diff --git a/indra/llcommon/llaprpool.h b/indra/llcommon/llaprpool.h
index dc123e942..4c9f36893 100644
--- a/indra/llcommon/llaprpool.h
+++ b/indra/llcommon/llaprpool.h
@@ -62,22 +62,22 @@ class LL_COMMON_API LLAPRPool
protected:
apr_pool_t* mPool; //!< Pointer to the underlaying pool. NULL if not initialized.
LLAPRPool* mParent; //!< Pointer to the parent pool, if any. Only valid when mPool is non-zero.
- apr_os_thread_t mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero.
+ AIThreadID mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero.
public:
//! Construct an uninitialized (destructed) pool.
- LLAPRPool(void) : mPool(NULL) { }
+ LLAPRPool(void) : mPool(NULL), mOwner(AIThreadID::none) { }
//! 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); }
+ LLAPRPool(LLAPRPool& parent) : mPool(NULL), mOwner(AIThreadID::none) { create(parent); }
//! Destruct the memory pool (free all of it's 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())
+ LLAPRPool(int) : mPool(NULL), mParent(NULL)
{
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL);
llassert_always(apr_pool_create_status == APR_SUCCESS);
@@ -104,7 +104,7 @@ public:
apr_pool_t* operator()(void) const
{
llassert(mPool);
- llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ llassert(mOwner.equals_current_thread());
return mPool;
}
@@ -112,7 +112,7 @@ public:
void clear(void)
{
llassert(mPool);
- llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ llassert(mOwner.equals_current_thread());
apr_pool_clear(mPool);
}
@@ -124,13 +124,13 @@ public:
void* palloc(size_t size)
{
llassert(mPool);
- llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ llassert(mOwner.equals_current_thread());
return apr_palloc(mPool, size);
}
void* pcalloc(size_t size)
{
llassert(mPool);
- llassert(apr_os_thread_equal(mOwner, apr_os_thread_current()));
+ llassert(mOwner.equals_current_thread());
return apr_pcalloc(mPool, size);
}
#endif
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index d0279f866..c4865e947 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -308,8 +308,4 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
Such computation is done iff the message will be logged.
*/
-#ifdef SHOW_ASSERT
-extern LL_COMMON_API bool is_main_thread();
-#endif
-
#endif // LL_LLERROR_H
diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h
index bae3e5615..2bb1943c8 100644
--- a/indra/llcommon/llframetimer.h
+++ b/indra/llcommon/llframetimer.h
@@ -44,6 +44,9 @@
#include "lltimer.h"
#include "timing.h"
#include
+#ifdef SHOW_ASSERT
+#include "aithreadid.h" // is_main_thread()
+#endif
class LL_COMMON_API LLFrameTimer
{
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index dd0efb422..c8d0be2f4 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -67,18 +67,12 @@
//
//----------------------------------------------------------------------------
-#if !LL_DARWIN
-U32 ll_thread_local local_thread_ID = 0;
-#endif
-
-U32 LLThread::sIDIter = 0;
LLAtomicS32 LLThread::sCount = 0;
LLAtomicS32 LLThread::sRunning = 0;
LL_COMMON_API void assert_main_thread()
{
- static U32 s_thread_id = LLThread::currentID();
- if (LLThread::currentID() != s_thread_id)
+ if (!AIThreadID::in_main_thread())
{
llerrs << "Illegal execution outside main thread." << llendl;
}
@@ -95,9 +89,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
LLThread *threadp = (LLThread *)datap;
-#if !LL_DARWIN
- local_thread_ID = threadp->mID;
-#endif
+ // Initialize thread-local cache of current thread ID (if supported).
+ AIThreadID::set_current_thread_id();
// Create a thread local data.
LLThreadLocalData::create(threadp);
@@ -137,7 +130,6 @@ LLThread::LLThread(std::string const& name) :
mStatus(STOPPED),
mThreadLocalData(NULL)
{
- mID = ++sIDIter;
sCount++;
llassert(sCount <= 50);
mRunCondition = new LLCondition;
@@ -281,12 +273,6 @@ void LLThread::setQuitting()
wake();
}
-// static
-U32 LLThread::currentID()
-{
- return (U32)apr_os_thread_current();
-}
-
// static
void LLThread::yield()
{
@@ -315,14 +301,6 @@ void LLThread::wakeLocked()
}
}
-//static
-apr_os_thread_t LLThread::sMainThreadID;
-
-void LLThread::set_main_thread_id(void)
-{
- sMainThreadID = apr_os_thread_current();
-}
-
// The thread private handle to access the LLThreadLocalData instance.
apr_threadkey_t* LLThreadLocalData::sThreadLocalDataKey;
@@ -345,6 +323,10 @@ void LLThreadLocalData::init(void)
return;
}
+ // This function is called by the main thread (these values are also needed in the next line).
+ AIThreadID::set_main_thread_id();
+ AIThreadID::set_current_thread_id();
+
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}
@@ -352,9 +334,6 @@ void LLThreadLocalData::init(void)
// Create the thread-local data for the main thread (this function is called by the main thread).
LLThreadLocalData::create(NULL);
-
- // This function is called by the main thread.
- LLThread::set_main_thread_id();
}
// This is called once for every thread when the thread is destructed.
@@ -421,27 +400,19 @@ void LLCondition::broadcast()
//============================================================================
LLMutexBase::LLMutexBase() :
- mLockingThread(NO_THREAD),
+ mLockingThread(AIThreadID::sNone),
mCount(0)
{
}
bool LLMutexBase::isSelfLocked() const
{
-#if LL_DARWIN
- return mLockingThread == LLThread::currentID();
-#else
- return mLockingThread == local_thread_ID;
-#endif
+ return mLockingThread.equals_current_thread();
}
void LLMutexBase::lock()
{
-#if LL_DARWIN
- if (mLockingThread == LLThread::currentID())
-#else
- if (mLockingThread == local_thread_ID)
-#endif
+ if (mLockingThread.equals_current_thread())
{ //redundant lock
mCount++;
return;
@@ -449,11 +420,33 @@ void LLMutexBase::lock()
apr_thread_mutex_lock(mAPRMutexp);
-#if LL_DARWIN
- mLockingThread = LLThread::currentID();
-#else
- mLockingThread = local_thread_ID;
-#endif
+ mLockingThread.reset();
+}
+
+bool LLMutexBase::tryLock()
+{
+ if (mLockingThread.equals_current_thread())
+ { //redundant lock
+ mCount++;
+ return true;
+ }
+ bool success = !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp));
+ if (success)
+ {
+ mLockingThread.reset();
+ }
+ return success;
+}
+
+// non-blocking, but does do a lock/unlock so not free
+bool LLMutexBase::isLocked() const
+{
+ if (mLockingThread.equals_current_thread())
+ return false; // A call to lock() won't block.
+ if (APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)))
+ return true;
+ apr_thread_mutex_unlock(mAPRMutexp);
+ return false;
}
void LLMutexBase::unlock()
@@ -463,7 +456,7 @@ void LLMutexBase::unlock()
mCount--;
return;
}
- mLockingThread = NO_THREAD;
+ mLockingThread = AIThreadID::sNone;
apr_thread_mutex_unlock(mAPRMutexp);
}
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index ef4303a02..549a090ec 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -45,17 +45,12 @@
#include "apr_thread_cond.h"
#include "llaprpool.h"
#include "llatomic.h"
+#include "aithreadid.h"
class LLThread;
class LLMutex;
class LLCondition;
-#if LL_WINDOWS
-#define ll_thread_local __declspec(thread)
-#else
-#define ll_thread_local __thread
-#endif
-
class LL_COMMON_API LLThreadLocalDataMember
{
public:
@@ -85,10 +80,12 @@ private:
~LLThreadLocalData();
};
+// Print to llerrs if the current thread is not the main thread.
+LL_COMMON_API void assert_main_thread();
+
class LL_COMMON_API LLThread
{
private:
- static apr_os_thread_t sMainThreadID;
static U32 sIDIter;
static LLAtomicS32 sCount;
static LLAtomicS32 sRunning;
@@ -108,11 +105,9 @@ public:
bool isQuitting() const { return (QUITTING == mStatus); }
bool isStopped() const { return (STOPPED == mStatus); }
- static U32 currentID(); // Return ID of current thread
static S32 getCount() { return sCount; }
static S32 getRunning() { return sRunning; }
static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure.
- static bool is_main_thread(void) { return apr_os_thread_equal(LLThread::sMainThreadID, apr_os_thread_current()); }
public:
// PAUSE / RESUME functionality. See source code for important usage notes.
@@ -136,11 +131,6 @@ public:
// Return thread-local data for the current thread.
static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); }
- // Called once, from LLThreadLocalData::init().
- static void set_main_thread_id(void);
-
- U32 getID() const { return mID; }
-
private:
bool mPaused;
@@ -153,7 +143,6 @@ protected:
apr_thread_t *mAPRThreadp;
volatile EThreadStatus mStatus;
- U32 mID;
friend void LLThreadLocalData::create(LLThread* threadp);
LLThreadLocalData* mThreadLocalData;
@@ -183,8 +172,7 @@ protected:
};
#ifdef SHOW_ASSERT
-LL_COMMON_API inline bool is_main_thread(void) { return LLThread::is_main_thread(); }
-#define ASSERT_SINGLE_THREAD do { static apr_os_thread_t first_thread_id = apr_os_thread_current(); llassert(apr_os_thread_equal(first_thread_id, apr_os_thread_current())); } while(0)
+#define ASSERT_SINGLE_THREAD do { static AIThreadID first_thread_id; llassert(first_thread_id.equals_current_thread()); } while(0)
#else
#define ASSERT_SINGLE_THREAD do { } while(0)
#endif
@@ -204,32 +192,24 @@ LL_COMMON_API inline bool is_main_thread(void) { return LLThread::is_main_thread
class LL_COMMON_API LLMutexBase
{
public:
- typedef enum
- {
- NO_THREAD = 0xFFFFFFFF
- } e_locking_thread;
-
LLMutexBase() ;
void lock(); // blocks
void unlock();
// Returns true if lock was obtained successfully.
- bool tryLock() { return !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)); }
+ bool tryLock();
- // 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; }
+ // Returns true if a call to lock() would block (returns false if self-locked()).
+ bool isLocked() const;
// Returns true if locked by this thread.
bool isSelfLocked() const;
- // get ID of locking thread
- U32 lockingThread() const { return mLockingThread; }
-
protected:
// mAPRMutexp is initialized and uninitialized in the derived class.
apr_thread_mutex_t* mAPRMutexp;
mutable U32 mCount;
- mutable U32 mLockingThread;
+ mutable AIThreadID mLockingThread;
private:
// Disallow copy construction and assignment.
diff --git a/indra/newview/statemachine/aistatemachine.cpp b/indra/newview/statemachine/aistatemachine.cpp
index 675317cb1..f008a4873 100644
--- a/indra/newview/statemachine/aistatemachine.cpp
+++ b/indra/newview/statemachine/aistatemachine.cpp
@@ -206,7 +206,7 @@ void AIStateMachine::locked_cont(void)
// Atomic test mActive and change mIdle.
mIdleActive.lock();
#ifdef SHOW_ASSERT
- mContThread = apr_os_thread_current();
+ mContThread.reset();
#endif
mIdle = false;
bool not_active = mActive == as_idle;
@@ -253,7 +253,7 @@ void AIStateMachine::set_state(state_type state)
mSetStateLock.lock();
// Do not call set_state() unless running.
- llassert(mState == bs_run || !LLThread::is_main_thread());
+ llassert(mState == bs_run || !is_main_thread());
// If this function is called from another thread than the main thread, then we have to ignore
// it if we're not idle and the state is less than the current state. The main thread must
@@ -279,12 +279,12 @@ void AIStateMachine::set_state(state_type state)
// state is less than the current state, ignore it.
// Also, if abort() or finish() was called, then we should just ignore it.
if (mState != bs_run ||
- (!mIdle && state <= mRunState && !LLThread::is_main_thread()))
+ (!mIdle && state <= mRunState && !AIThreadID::in_main_thread()))
{
#ifdef SHOW_ASSERT
// It's a bit weird if the same thread does two calls on a row where the second call
// has a smaller value: warn about that.
- if (mState == bs_run && mContThread == apr_os_thread_current())
+ if (mState == bs_run && mContThread.equals_current_thread())
{
llwarns << "Ignoring call to set_state(" << state_str(state) <<
") by non-main thread before main-thread could react on previous call, "
@@ -296,7 +296,7 @@ void AIStateMachine::set_state(state_type state)
}
// Do not call idle() when set_state is called from another thread; use idle(state_type) instead.
- llassert(!mCalledThreadUnsafeIdle || LLThread::is_main_thread());
+ llassert(!mCalledThreadUnsafeIdle || is_main_thread());
// Change mRunState to the requested value.
if (mRunState != state)
diff --git a/indra/newview/statemachine/aistatemachine.h b/indra/newview/statemachine/aistatemachine.h
index 13da6fd3d..55028232b 100644
--- a/indra/newview/statemachine/aistatemachine.h
+++ b/indra/newview/statemachine/aistatemachine.h
@@ -208,7 +208,7 @@ class AIStateMachine {
S64 mSleep; //!< Non-zero while the state machine is sleeping.
LLMutex mIdleActive; //!< Used for atomic operations on the pair mIdle / mActive.
#ifdef SHOW_ASSERT
- apr_os_thread_t mContThread; //!< Thread that last called locked_cont().
+ AIThreadID mContThread; //!< Thread that last called locked_cont().
bool mCalledThreadUnsafeIdle; //!< Set to true when idle() is called.
#endif
@@ -242,7 +242,7 @@ class AIStateMachine {
//! Create a non-running state machine.
AIStateMachine(void) : mState(bs_initialize), mIdle(true), mAborted(true), mActive(as_idle), mSleep(0), mParent(NULL), mCallback(NULL)
#ifdef SHOW_ASSERT
- , mContThread(0), mCalledThreadUnsafeIdle(false)
+ , mContThread(AIThreadID::none), mCalledThreadUnsafeIdle(false)
#endif
{ updateSettings(); }
@@ -269,7 +269,7 @@ class AIStateMachine {
mSetStateLock.lock();
// Ignore calls to cont() if the statemachine isn't idle. See comments in set_state().
// Calling cont() twice or after calling set_state(), without first calling idle(), is an error.
- if (mState != bs_run || !mIdle) { llassert(mState != bs_run || mContThread != apr_os_thread_current()); mSetStateLock.unlock(); return; }
+ if (mState != bs_run || !mIdle) { llassert(mState != bs_run || !mContThread.equals_current_thread()); mSetStateLock.unlock(); return; }
locked_cont();
}
private: