From e7aeb3feafb28a5353691bfdb0abd7dea8c58b77 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 4 Feb 2013 22:56:40 +0100 Subject: [PATCH] Add AINRLock for debugging purposes. This class can be used as RWLOCK parameter to AIThreadSafe to check that data is only accessed by a single thread (like AIThreadSafeSingleThreaded) AND is never write locked when a read or write lock was already obtained (by the same thread). It doesn't actually lock anything, it just keeps track if the "lock" was obtained before. The use case is to check if STL containers aren't being used (read or write locked) by a calling function when additional write access is necessary, as write access might invalidate iterator that point to the container (where the previous lock was taken). --- indra/llcommon/llthread.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 08d6e2110..f64200c95 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -397,6 +397,43 @@ public: #endif }; +#if LL_DEBUG +class LL_COMMON_API AINRLock +{ +private: + int read_locked; + int write_locked; + + mutable bool mAccessed; + mutable AIThreadID mTheadID; + + void accessed(void) const + { + if (!mAccessed) + { + mAccessed = true; + mTheadID.reset(); + } + else + { + llassert_always(mTheadID.equals_current_thread()); + } + } + +public: + AINRLock(void) : read_locked(false), write_locked(false), mAccessed(false) { } + + bool isLocked() const { return read_locked || write_locked; } + + void rdlock(bool high_priority = false) { accessed(); ++read_locked; } + void rdunlock() { --read_locked; } + void wrlock() { llassert(!isLocked()); accessed(); ++write_locked; } + void wrunlock() { --write_locked; } + void wr2rdlock() { llassert(false); } + void rd2wrlock() { llassert(false); } +}; +#endif + //============================================================================ void LLThread::lockData()