diff --git a/doc/contributions.txt b/doc/contributions.txt
index 66323a38c621c49f9bd9b3a8ddff0e064a021c64..6146689fb0a6335094905d13924a67c6c3afe1a7 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1070,6 +1070,7 @@ Nicky Dasmijn
     STORM-2010
 	STORM-2082
 	MAINT-6665
+	SL-10291
 	SL-10293
 Nicky Perian
 	OPEN-1
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index d353d06de2ebef503d83334f454063b1152add6a..29f0c7da9a39ee1ac9d6906a51519cf621dc44a3 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -28,13 +28,12 @@
 
 #include "linden_common.h"
 #include "llapr.h"
+#include "llmutex.h"
 #include "apr_dso.h"
 #include "llthreadlocalstorage.h"
 
 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 *gCallStacksLogMutexp = NULL;
 
 const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
 
@@ -48,10 +47,6 @@ void ll_init_apr()
 	if (!gAPRPoolp)
 	{
 		apr_pool_create(&gAPRPoolp, NULL);
-		
-		// Initialize the logging mutex
-		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
-		apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
 	}
 
 	if(!LLAPRFile::sAPRFilePoolp)
@@ -75,23 +70,6 @@ void ll_cleanup_apr()
 
 	LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
 
-	if (gLogMutexp)
-	{
-		// Clean up the logging mutex
-
-		// All other threads NEED to be done before we clean up APR, so this is okay.
-		apr_thread_mutex_destroy(gLogMutexp);
-		gLogMutexp = NULL;
-	}
-	if (gCallStacksLogMutexp)
-	{
-		// Clean up the logging mutex
-
-		// All other threads NEED to be done before we clean up APR, so this is okay.
-		apr_thread_mutex_destroy(gCallStacksLogMutexp);
-		gCallStacksLogMutexp = NULL;
-	}
-
 	LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
 
 	if (gAPRPoolp)
@@ -168,26 +146,19 @@ apr_pool_t* LLAPRPool::getAPRPool()
 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)
+				  mNumTotalRef(0)
 {
 	//create mutex
 	if(!is_local) //not a local apr_pool, that is: shared by multiple threads.
 	{
-		apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex
-		apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool);
+		mMutexp.reset(new std::mutex());
 	}
 }
 
 LLVolatileAPRPool::~LLVolatileAPRPool()
 {
 	//delete mutex
-	if(mMutexp)
-	{
-		apr_thread_mutex_destroy(mMutexp);
-		apr_pool_destroy(mMutexPool);
-	}
+    mMutexp.reset();
 }
 
 //
@@ -201,7 +172,7 @@ apr_pool_t* LLVolatileAPRPool::getAPRPool()
 
 apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() 
 {	
-	LLScopedLock lock(mMutexp) ;
+	LLScopedLock lock(mMutexp.get()) ;
 
 	mNumTotalRef++ ;
 	mNumActiveRef++ ;
@@ -216,7 +187,7 @@ apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
 
 void LLVolatileAPRPool::clearVolatileAPRPool() 
 {
-	LLScopedLock lock(mMutexp) ;
+    LLScopedLock lock(mMutexp.get());
 
 	if(mNumActiveRef > 0)
 	{
@@ -250,44 +221,6 @@ BOOL LLVolatileAPRPool::isFull()
 {
 	return mNumTotalRef > FULL_VOLATILE_APR_POOL ;
 }
-//---------------------------------------------------------------------
-//
-// LLScopedLock
-//
-LLScopedLock::LLScopedLock(apr_thread_mutex_t* mutex) : mMutex(mutex)
-{
-	if(mutex)
-	{
-		if(ll_apr_warn_status(apr_thread_mutex_lock(mMutex)))
-		{
-			mLocked = false;
-		}
-		else
-		{
-			mLocked = true;
-		}
-	}
-	else
-	{
-		mLocked = false;
-	}
-}
-
-LLScopedLock::~LLScopedLock()
-{
-	unlock();
-}
-
-void LLScopedLock::unlock()
-{
-	if(mLocked)
-	{
-		if(!ll_apr_warn_status(apr_thread_mutex_unlock(mMutex)))
-		{
-			mLocked = false;
-		}
-	}
-}
 
 //---------------------------------------------------------------------
 
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 1ac5c4e9b2b9ed2309b819dcca3e2341689ed16a..73d1d180efe9b78da0dd864a5235b0af62fdd054 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -36,15 +36,23 @@
 #include <boost/noncopyable.hpp>
 #include "llwin32headerslean.h"
 #include "apr_thread_proc.h"
-#include "apr_thread_mutex.h"
 #include "apr_getopt.h"
 #include "apr_signal.h"
 #include "apr_atomic.h"
 
 #include "llstring.h"
 
-extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
-extern apr_thread_mutex_t* gCallStacksLogMutexp;
+#if LL_WINDOWS
+#pragma warning (push)
+#pragma warning (disable:4265)
+#endif
+// warning C4265: 'std::_Pad' : class has virtual functions, but destructor is not virtual
+
+#include <mutex>
+
+#if LL_WINDOWS
+#pragma warning (pop)
+#endif
 
 struct apr_dso_handle_t;
 /**
@@ -120,50 +128,9 @@ private:
 	S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
 	S32 mNumTotalRef ;  //number of total pointers pointing to the apr_pool since last creating.  
 
-	apr_thread_mutex_t *mMutexp;
-	apr_pool_t         *mMutexPool;
+	std::unique_ptr<std::mutex> mMutexp;
 } ;
 
-/** 
- * @class LLScopedLock
- * @brief Small class to help lock and unlock mutexes.
- *
- * This class is used to have a stack level lock once you already have
- * an apr mutex handy. The constructor handles the lock, and the
- * destructor handles the unlock. Instances of this class are
- * <b>not</b> thread safe.
- */
-class LL_COMMON_API LLScopedLock : private boost::noncopyable
-{
-public:
-	/**
-	 * @brief Constructor which accepts a mutex, and locks it.
-	 *
-	 * @param mutex An allocated APR mutex. If you pass in NULL,
-	 * this wrapper will not lock.
-	 */
-	LLScopedLock(apr_thread_mutex_t* mutex);
-
-	/**
-	 * @brief Destructor which unlocks the mutex if still locked.
-	 */
-	~LLScopedLock();
-
-	/** 
-	 * @brief Check lock.
-	 */
-	bool isLocked() const { return mLocked; }
-
-	/** 
-	 * @brief This method unlocks the mutex.
-	 */
-	void unlock();
-
-protected:
-	bool mLocked;
-	apr_thread_mutex_t* mMutex;
-};
-
 template <typename Type> class LLAtomic32
 {
 public:
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 17d8164289511ce3569081cb1eca91c5f924ef4c..3db67059854a9243d901b188f57b76548b028dce 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -1096,6 +1096,9 @@ namespace
 }
 
 namespace {
+	LLMutex gLogMutex;
+	LLMutex gCallStacksLogMutex;
+
 	bool checkLevelMap(const LevelMap& map, const std::string& key,
 						LLError::ELevel& level)
 	{
@@ -1135,56 +1138,6 @@ namespace {
 		}
 		return found_level;
 	}
-	
-	class LogLock
-	{
-	public:
-		LogLock();
-		~LogLock();
-		bool ok() const { return mOK; }
-	private:
-		bool mLocked;
-		bool mOK;
-	};
-	
-	LogLock::LogLock()
-		: mLocked(false), mOK(false)
-	{
-		if (!gLogMutexp)
-		{
-			mOK = true;
-			return;
-		}
-		
-		const int MAX_RETRIES = 5;
-		for (int attempts = 0; attempts < MAX_RETRIES; ++attempts)
-		{
-			apr_status_t s = apr_thread_mutex_trylock(gLogMutexp);
-			if (!APR_STATUS_IS_EBUSY(s))
-			{
-				mLocked = true;
-				mOK = true;
-				return;
-			}
-
-			ms_sleep(1);
-			//apr_thread_yield();
-				// Just yielding won't necessarily work, I had problems with
-				// this on Linux - doug 12/02/04
-		}
-
-		// We're hosed, we can't get the mutex.  Blah.
-		std::cerr << "LogLock::LogLock: failed to get mutex for log"
-					<< std::endl;
-	}
-	
-	LogLock::~LogLock()
-	{
-		if (mLocked)
-		{
-			apr_thread_mutex_unlock(gLogMutexp);
-		}
-	}
 }
 
 namespace LLError
@@ -1192,8 +1145,8 @@ namespace LLError
 
 	bool Log::shouldLog(CallSite& site)
 	{
-		LogLock lock;
-		if (!lock.ok())
+		LLMutexTrylock lock(&gLogMutex, 5);
+		if (!lock.isLocked())
 		{
 			return false;
 		}
@@ -1243,11 +1196,11 @@ namespace LLError
 
 	std::ostringstream* Log::out()
 	{
-		LogLock lock;
+		LLMutexTrylock lock(&gLogMutex,5);
 		// If we hit a logging request very late during shutdown processing,
 		// when either of the relevant LLSingletons has already been deleted,
 		// DO NOT resurrect them.
-		if (lock.ok() && ! (Settings::wasDeleted() || Globals::wasDeleted()))
+		if (lock.isLocked() && ! (Settings::wasDeleted() || Globals::wasDeleted()))
 		{
 			Globals* g = Globals::getInstance();
 
@@ -1263,8 +1216,8 @@ namespace LLError
 
 	void Log::flush(std::ostringstream* out, char* message)
 	{
-		LogLock lock;
-		if (!lock.ok())
+		LLMutexTrylock lock(&gLogMutex,5);
+		if (!lock.isLocked())
 		{
 			return;
 		}
@@ -1303,8 +1256,8 @@ namespace LLError
 
 	void Log::flush(std::ostringstream* out, const CallSite& site)
 	{
-		LogLock lock;
-		if (!lock.ok())
+		LLMutexTrylock lock(&gLogMutex,5);
+		if (!lock.isLocked())
 		{
 			return;
 		}
@@ -1469,69 +1422,6 @@ namespace LLError
 	char** LLCallStacks::sBuffer = NULL ;
 	S32    LLCallStacks::sIndex  = 0 ;
 
-#define SINGLE_THREADED 1
-
-	class CallStacksLogLock
-	{
-	public:
-		CallStacksLogLock();
-		~CallStacksLogLock();
-
-#if SINGLE_THREADED
-		bool ok() const { return true; }
-#else
-		bool ok() const { return mOK; }
-	private:
-		bool mLocked;
-		bool mOK;
-#endif
-	};
-	
-#if SINGLE_THREADED
-	CallStacksLogLock::CallStacksLogLock()
-	{
-	}
-	CallStacksLogLock::~CallStacksLogLock()
-	{
-	}
-#else
-	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);
-		}
-	}
-#endif
-
 	//static
    void LLCallStacks::allocateStackBuffer()
    {
@@ -1560,8 +1450,8 @@ namespace LLError
    //static
    void LLCallStacks::push(const char* function, const int line)
    {
-	   CallStacksLogLock lock;
-       if (!lock.ok())
+       LLMutexTrylock lock(&gCallStacksLogMutex, 5);
+       if (!lock.isLocked())
        {
            return;
        }
@@ -1595,8 +1485,8 @@ namespace LLError
    //static
    void LLCallStacks::end(std::ostringstream* _out)
    {
-	   CallStacksLogLock lock;
-       if (!lock.ok())
+       LLMutexTrylock lock(&gCallStacksLogMutex, 5);
+       if (!lock.isLocked())
        {
            return;
        }
@@ -1617,8 +1507,8 @@ namespace LLError
    //static
    void LLCallStacks::print()
    {
-	   CallStacksLogLock lock;
-       if (!lock.ok())
+       LLMutexTrylock lock(&gCallStacksLogMutex, 5);
+       if (!lock.isLocked())
        {
            return;
        }
@@ -1655,8 +1545,8 @@ namespace LLError
 
 bool debugLoggingEnabled(const std::string& tag)
 {
-    LogLock lock;
-    if (!lock.ok())
+    LLMutexTrylock lock(&gLogMutex, 5);
+    if (!lock.isLocked())
     {
         return false;
     }
diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp
index d394f179fb52fd674854f724c9fd2721f00ec567..bd4db8be845528e0524ba15f4333f949c8419361 100644
--- a/indra/llcommon/llfixedbuffer.cpp
+++ b/indra/llcommon/llfixedbuffer.cpp
@@ -31,7 +31,7 @@
 LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
 	: LLLineBuffer(),
 	  mMaxLines(max_lines),
-	  mMutex(NULL)
+	  mMutex()
 {
 	mTimer.reset();
 }
diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp
index 9c13ef9e309a94dda09dfa19929c69297a0cfc05..cf84e50953caaa91e06bf4369f1a1a043ad207c4 100644
--- a/indra/llcommon/llmutex.cpp
+++ b/indra/llcommon/llmutex.cpp
@@ -30,41 +30,19 @@
 
 #include "llmutex.h"
 #include "llthread.h"
+#include "lltimer.h"
 
 //============================================================================
 
-LLMutex::LLMutex(apr_pool_t *poolp) :
-	mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD)
+LLMutex::LLMutex() :
+ mCount(0),
+ mLockingThread(NO_THREAD)
 {
-	//if (poolp)
-	//{
-	//	mIsLocalPool = FALSE;
-	//	mAPRPoolp = poolp;
-	//}
-	//else
-	{
-		mIsLocalPool = TRUE;
-		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
-	}
-	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
 }
 
 
 LLMutex::~LLMutex()
 {
-#if MUTEX_DEBUG
-	//bad assertion, the subclass LLSignal might be "locked", and that's OK
-	//llassert_always(!isLocked()); // better not be locked!
-#endif
-	if (ll_apr_is_initialized())
-	{
-		apr_thread_mutex_destroy(mAPRMutexp);
-		if (mIsLocalPool)
-		{
-			apr_pool_destroy(mAPRPoolp);
-		}
-	}
-	mAPRMutexp = NULL;
 }
 
 
@@ -76,7 +54,7 @@ void LLMutex::lock()
 		return;
 	}
 	
-	apr_thread_mutex_lock(mAPRMutexp);
+	mMutex.lock();
 	
 #if MUTEX_DEBUG
 	// Have to have the lock before we can access the debug info
@@ -106,19 +84,18 @@ void LLMutex::unlock()
 #endif
 
 	mLockingThread = NO_THREAD;
-	apr_thread_mutex_unlock(mAPRMutexp);
+	mMutex.unlock();
 }
 
 bool LLMutex::isLocked()
 {
-	apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
-	if (APR_STATUS_IS_EBUSY(status))
+	if (!mMutex.try_lock())
 	{
 		return true;
 	}
 	else
 	{
-		apr_thread_mutex_unlock(mAPRMutexp);
+		mMutex.unlock();
 		return false;
 	}
 }
@@ -141,8 +118,7 @@ bool LLMutex::trylock()
 		return true;
 	}
 	
-	apr_status_t status(apr_thread_mutex_trylock(mAPRMutexp));
-	if (APR_STATUS_IS_EBUSY(status))
+	if (!mMutex.try_lock())
 	{
 		return false;
 	}
@@ -161,45 +137,95 @@ bool LLMutex::trylock()
 
 //============================================================================
 
-LLCondition::LLCondition(apr_pool_t *poolp) :
-	LLMutex(poolp)
+LLCondition::LLCondition() :
+	LLMutex()
 {
-	// base class (LLMutex) has already ensured that mAPRPoolp is set up.
-
-	apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
 }
 
 
 LLCondition::~LLCondition()
 {
-	apr_thread_cond_destroy(mAPRCondp);
-	mAPRCondp = NULL;
 }
 
 
 void LLCondition::wait()
 {
-	if (!isLocked())
-	{ //mAPRMutexp MUST be locked before calling apr_thread_cond_wait
-		apr_thread_mutex_lock(mAPRMutexp);
-#if MUTEX_DEBUG
-		// avoid asserts on destruction in non-release builds
-		U32 id = LLThread::currentID();
-		mIsLocked[id] = TRUE;
-#endif
-	}
-	apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
+	std::unique_lock< std::mutex > lock(mMutex);
+	mCond.wait(lock);
 }
 
 void LLCondition::signal()
 {
-	apr_thread_cond_signal(mAPRCondp);
+	mCond.notify_one();
 }
 
 void LLCondition::broadcast()
 {
-	apr_thread_cond_broadcast(mAPRCondp);
+	mCond.notify_all();
 }
 
 
+
+LLMutexTrylock::LLMutexTrylock(LLMutex* mutex)
+    : mMutex(mutex),
+    mLocked(false)
+{
+    if (mMutex)
+        mLocked = mMutex->trylock();
+}
+
+LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms)
+    : mMutex(mutex),
+    mLocked(false)
+{
+    if (!mMutex)
+        return;
+
+    for (U32 i = 0; i < aTries; ++i)
+    {
+        mLocked = mMutex->trylock();
+        if (mLocked)
+            break;
+        ms_sleep(delay_ms);
+    }
+}
+
+LLMutexTrylock::~LLMutexTrylock()
+{
+    if (mMutex && mLocked)
+        mMutex->unlock();
+}
+
+
+//---------------------------------------------------------------------
+//
+// LLScopedLock
+//
+LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex)
+{
+	if(mutex)
+	{
+		mutex->lock();
+		mLocked = true;
+	}
+	else
+	{
+		mLocked = false;
+	}
+}
+
+LLScopedLock::~LLScopedLock()
+{
+	unlock();
+}
+
+void LLScopedLock::unlock()
+{
+	if(mLocked)
+	{
+		mMutex->unlock();
+		mLocked = false;
+	}
+}
+
 //============================================================================
diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h
index ea535cee86d1783be719df606b9dea747694e7cd..f841d7f9503bd3e02c3e14b634e91557706a8123 100644
--- a/indra/llcommon/llmutex.h
+++ b/indra/llcommon/llmutex.h
@@ -28,6 +28,19 @@
 #define LL_LLMUTEX_H
 
 #include "stdtypes.h"
+#include <boost/noncopyable.hpp>
+
+#if LL_WINDOWS
+#pragma warning (push)
+#pragma warning (disable:4265)
+#endif
+// 'std::_Pad' : class has virtual functions, but destructor is not virtual
+#include <mutex>
+#include <condition_variable>
+
+#if LL_WINDOWS
+#pragma warning (pop)
+#endif
 
 //============================================================================
 
@@ -37,10 +50,6 @@
 #include <map>
 #endif
 
-struct apr_thread_mutex_t;
-struct apr_pool_t;
-struct apr_thread_cond_t;
-
 class LL_COMMON_API LLMutex
 {
 public:
@@ -49,7 +58,7 @@ public:
 		NO_THREAD = 0xFFFFFFFF
 	} e_locking_thread;
 
-	LLMutex(apr_pool_t *apr_poolp = NULL); // NULL pool constructs a new pool for the mutex
+	LLMutex();
 	virtual ~LLMutex();
 	
 	void lock();		// blocks
@@ -60,13 +69,10 @@ public:
 	U32 lockingThread() const; //get ID of locking thread
 	
 protected:
-	apr_thread_mutex_t *mAPRMutexp;
+	std::mutex			mMutex;
 	mutable U32			mCount;
 	mutable U32			mLockingThread;
 	
-	apr_pool_t			*mAPRPoolp;
-	BOOL				mIsLocalPool;
-	
 #if MUTEX_DEBUG
 	std::map<U32, BOOL> mIsLocked;
 #endif
@@ -76,7 +82,7 @@ protected:
 class LL_COMMON_API LLCondition : public LLMutex
 {
 public:
-	LLCondition(apr_pool_t* apr_poolp); // Defaults to global pool, could use the thread pool as well.
+	LLCondition();
 	~LLCondition();
 	
 	void wait();		// blocks
@@ -84,7 +90,7 @@ public:
 	void broadcast();
 	
 protected:
-	apr_thread_cond_t* mAPRCondp;
+	std::condition_variable mCond;
 };
 
 class LLMutexLock
@@ -119,19 +125,9 @@ private:
 class LLMutexTrylock
 {
 public:
-	LLMutexTrylock(LLMutex* mutex)
-		: mMutex(mutex),
-		  mLocked(false)
-	{
-		if (mMutex)
-			mLocked = mMutex->trylock();
-	}
-
-	~LLMutexTrylock()
-	{
-		if (mMutex && mLocked)
-			mMutex->unlock();
-	}
+	LLMutexTrylock(LLMutex* mutex);
+	LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms = 10);
+	~LLMutexTrylock();
 
 	bool isLocked() const
 	{
@@ -142,4 +138,43 @@ private:
 	LLMutex*	mMutex;
 	bool		mLocked;
 };
-#endif // LL_LLTHREAD_H
+
+/**
+* @class LLScopedLock
+* @brief Small class to help lock and unlock mutexes.
+*
+* The constructor handles the lock, and the destructor handles
+* the unlock. Instances of this class are <b>not</b> thread safe.
+*/
+class LL_COMMON_API LLScopedLock : private boost::noncopyable
+{
+public:
+    /**
+    * @brief Constructor which accepts a mutex, and locks it.
+    *
+    * @param mutex An allocated mutex. If you pass in NULL,
+    * this wrapper will not lock.
+    */
+    LLScopedLock(std::mutex* mutex);
+
+    /**
+    * @brief Destructor which unlocks the mutex if still locked.
+    */
+    ~LLScopedLock();
+
+    /**
+    * @brief Check lock.
+    */
+    bool isLocked() const { return mLocked; }
+
+    /**
+    * @brief This method unlocks the mutex.
+    */
+    void unlock();
+
+protected:
+    bool mLocked;
+    std::mutex* mMutex;
+};
+
+#endif // LL_LLMUTEX_H
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index f066e9a4cdd43006a531453e6bae33a19b8fa586..860415bb2213e9b36db6eb189f9b298daa15a0e9 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -186,8 +186,8 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
         mIsLocalPool = TRUE;
         apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
     }
-    mRunCondition = new LLCondition(mAPRPoolp);
-    mDataLock = new LLMutex(mAPRPoolp);
+    mRunCondition = new LLCondition();
+    mDataLock = new LLMutex();
     mLocalAPRFilePoolp = NULL ;
 }
 
@@ -413,7 +413,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount()
 {
     if (!sMutex)
     {
-        sMutex = new LLMutex(0);
+        sMutex = new LLMutex();
     }
 }
 
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index d4af2c6b011f2cf261247a5a798ef051060c988c..8f33d789ebde25871f9c480d229029507556fbd6 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -738,7 +738,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)
       getSystemTime(&time_last);
       uuids_this_tick = uuids_per_tick;
       init = TRUE;
-	  mMutex = new LLMutex(NULL);
+	  mMutex = new LLMutex();
    }
 
    uuid_time_t time_now = {0,0};
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 4c197dc1d6362b193fd3fe29f9f2a73880022da6..4b91b2cacaf4007ab467ff4a7c505a7e32ff8826 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -37,7 +37,7 @@
 LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded, bool should_pause) :
 	LLQueuedThread(name, threaded, should_pause)
 {
-	mDeleteMutex = new LLMutex(NULL);
+	mDeleteMutex = new LLMutex();
 
 	if(!mLocalAPRFilePoolp)
 	{
@@ -204,7 +204,7 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
 	  mWorkerClassName(name),
 	  mRequestHandle(LLWorkerThread::nullHandle()),
 	  mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
-	  mMutex(NULL),
+	  mMutex(),
 	  mWorkFlags(0)
 {
 	if (!mWorkerThread)
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index 1829062af6426b1137323214aec283a8ecb9a475..7c93c54cdfc3fba724eddeae0cd6ec2b41773580 100644
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -333,7 +333,7 @@ LLMutex *getCurlMutex()
 
     if (!sHandleMutexp)
     {
-        sHandleMutexp = new LLMutex(NULL);
+        sHandleMutexp = new LLMutex();
     }
 
     return sHandleMutexp;
@@ -389,7 +389,7 @@ void initialize()
     S32 mutex_count = CRYPTO_num_locks();
     for (S32 i = 0; i < mutex_count; i++)
     {
-        sSSLMutex.push_back(LLMutex_ptr(new LLMutex(NULL)));
+        sSSLMutex.push_back(LLMutex_ptr(new LLMutex()));
     }
     CRYPTO_set_id_callback(&ssl_thread_id);
     CRYPTO_set_locking_callback(&ssl_locking_callback);
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 1a4dd2ca9943c67b2383580972cd3883147b75dd..680fbf548f7ffd80ac819cda04957e027592088b 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -594,7 +594,7 @@ void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_
 {
 	sUseNewByteRange = use_new_byte_range;
     sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
-	sMutex = new LLMutex(NULL);
+	sMutex = new LLMutex();
 }
 
 //static
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 4875fe700198edc91015228311de23a01b03bc65..5f42fba86602ecf4df3b609ebae06b4ff947495a 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -35,7 +35,7 @@
 LLImageDecodeThread::LLImageDecodeThread(bool threaded)
 	: LLQueuedThread("imagedecode", threaded)
 {
-	mCreationMutex = new LLMutex(getAPRPool());
+	mCreationMutex = new LLMutex();
 }
 
 //virtual 
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index 3b8f08e0c6cc125557849211e76a4118951dafec..89cdb1c6b9176cb4c42e5774c0632d69bd217147 100644
--- a/indra/llmath/llvolumemgr.cpp
+++ b/indra/llmath/llvolumemgr.cpp
@@ -48,7 +48,7 @@ LLVolumeMgr::LLVolumeMgr()
 {
 	// the LLMutex magic interferes with easy unit testing,
 	// so you now must manually call useMutex() to use it
-	//mDataMutex = new LLMutex(gAPRPoolp);
+	//mDataMutex = new LLMutex();
 }
 
 LLVolumeMgr::~LLVolumeMgr()
@@ -214,7 +214,7 @@ void LLVolumeMgr::useMutex()
 { 
 	if (!mDataMutex)
 	{
-		mDataMutex = new LLMutex(gAPRPoolp);
+		mDataMutex = new LLMutex();
 	}
 }
 
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index d07d9980c38bd662190a55dea03b41a6eaa3ed4f..1a0eceba0f824144a5fa073f903e68cbbc25c71d 100644
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -265,7 +265,7 @@ void LLBufferArray::setThreaded(bool threaded)
 	{
 		if(!mMutexp)
 		{
-			mMutexp = new LLMutex(NULL);
+			mMutexp = new LLMutex();
 		}
 	}
 	else
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 537efa69d88bb1bdaf33b31fb0f0a814f7a18ca3..5730a362670366098a7285132a673c5840f83b46 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -48,7 +48,7 @@ static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP
 
 LLProxy::LLProxy():
 		mHTTPProxyEnabled(false),
-		mProxyMutex(NULL),
+		mProxyMutex(),
 		mUDPProxy(),
 		mTCPProxy(),
 		mHTTPProxy(),
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 9468696507b31e98be7b947a4badad5024ee9c56..9766e1bfede5f8f130153bc1f8b44d3c232ea6f6 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -92,8 +92,8 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
 }
 
 LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
-	mInputMutex(gAPRPoolp),
-	mOutputMutex(gAPRPoolp),
+	mInputMutex(),
+	mOutputMutex(),
 	mOutputStartIndex(0),
 	mOwner(owner),
 	mSocket(socket)
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 0a8e58ac90cf60d7fda67900b565ce0e6ec9f426..eb6cb1b503a00778e37bbb22853aa5ecf0659b39 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -80,11 +80,11 @@ protected:
 };
 
 LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
-	mIncomingQueueMutex(gAPRPoolp)
+	mIncomingQueueMutex()
 {
 	if(!sInstancesMutex)
 	{
-		sInstancesMutex = new LLMutex(gAPRPoolp);
+		sInstancesMutex = new LLMutex();
 	}
 	
 	mOwner = owner;
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index d5bd1834c2da0d5ceb194f3178f0a67b5dbaa2d0..617056d94d224eeea3d89b26b45063fe469811e4 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -234,7 +234,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
 	mDataFP(NULL),
 	mIndexFP(NULL)
 {
-	mDataMutex = new LLMutex(0);
+	mDataMutex = new LLMutex();
 
 	S32 i;
 	for (i = 0; i < VFSLOCK_COUNT; i++)
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7c79cc7ddf83131bd93b55e271c40fdb44576295..f8fa06b527d177ad765ef5cf0f37620b48757a12 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2148,7 +2148,7 @@ bool LLAppViewer::initThreads()
 
 	if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
 	{
-		LLTrace::BlockTimer::setLogLock(new LLMutex(NULL));
+		LLTrace::BlockTimer::setLogLock(new LLMutex());
 		mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName);
 		mFastTimerLogThread->start();
 	}
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index 5443afe60c1c5418e8ec0fa295c5a726591b8eba..b8e6e81ee6695c92f5239d0d1d3f1c118226e652 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -315,7 +315,7 @@ void LLDirPickerThread::run()
 //static
 void LLDirPickerThread::initClass()
 {
-	sMutex = new LLMutex(NULL);
+	sMutex = new LLMutex();
 }
 
 //static
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index b48ecc8f31a11aa81b925ee6abb783cbe1835567..66198b3bf68475fa989e448645d0b761b1afea69 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -46,7 +46,7 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i
 	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")),
 	mAccountName(session_id[LL_FCP_ACCOUNT_NAME]),
 	mCompleteName(session_id[LL_FCP_COMPLETE_NAME]),
-	mMutex(NULL),
+	mMutex(),
 	mShowHistory(false),
 	mMessages(NULL),
 	mHistoryThreadsBusy(false),
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 2cc42460a54c7ede74135d2c2d1eba4eee5c6fd8..616bee84fdc2c619eb5fffade8b44f0373340719 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -266,7 +266,7 @@ mCalculateBtn(NULL)
 	sInstance = this;
 	mLastMouseX = 0;
 	mLastMouseY = 0;
-	mStatusLock = new LLMutex(NULL);
+	mStatusLock = new LLMutex();
 	mModelPreview = NULL;
 
 	mLODMode[LLModel::LOD_HIGH] = 0;
@@ -1265,7 +1265,7 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl
 //-----------------------------------------------------------------------------
 
 LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
-: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL)
+: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex()
 , mLodsQuery()
 , mLodsWithParsingError()
 , mPelvisZOffset( 0.0f )
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index c535fc1cdf49bdd49ae253dec8d17d85784f761f..c9889667b47416fc675baa7ce328831ac40bc406 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -516,7 +516,7 @@ LLMutex* LLLogChat::historyThreadsMutex()
 {
 	if (sHistoryThreadsMutex == NULL)
 	{
-		sHistoryThreadsMutex = new LLMutex(NULL);
+		sHistoryThreadsMutex = new LLMutex();
 	}
 	return sHistoryThreadsMutex;
 }
@@ -1012,8 +1012,8 @@ void LLDeleteHistoryThread::run()
 
 LLActionThread::LLActionThread(const std::string& name)
 	: LLThread(name),
-	mMutex(NULL),
-	mRunCondition(NULL),
+	mMutex(),
+	mRunCondition(),
 	mFinished(false)
 {
 }
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index f32dad7f559bdf615ee74cae55150ef96f47cbed..a6002bd57f120e74c34dc730ff4262af6f4c3cd1 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -830,9 +830,9 @@ LLMeshRepoThread::LLMeshRepoThread()
 {
 	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
 
-	mMutex = new LLMutex(NULL);
-	mHeaderMutex = new LLMutex(NULL);
-	mSignal = new LLCondition(NULL);
+	mMutex = new LLMutex();
+	mHeaderMutex = new LLMutex();
+	mSignal = new LLCondition();
 	mHttpRequest = new LLCore::HttpRequest;
 	mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
 	mHttpOptions->setTransferTimeout(SMALL_MESH_XFER_TIMEOUT);
@@ -2039,7 +2039,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
 	mUploadSkin = upload_skin;
 	mUploadJoints = upload_joints;
     mLockScaleIfJointPosition = lock_scale_if_joint_position;
-	mMutex = new LLMutex(NULL);
+	mMutex = new LLMutex();
 	mPendingUploads = 0;
 	mFinished = false;
 	mOrigin = gAgent.getPositionAgent();
@@ -3446,7 +3446,7 @@ LLMeshRepository::LLMeshRepository()
 
 void LLMeshRepository::init()
 {
-	mMeshMutex = new LLMutex(NULL);
+	mMeshMutex = new LLMutex();
 	
 	LLConvexDecomposition::getInstance()->initSystem();
 
@@ -4588,8 +4588,8 @@ LLPhysicsDecomp::LLPhysicsDecomp()
 	mQuitting = false;
 	mDone = false;
 
-	mSignal = new LLCondition(NULL);
-	mMutex = new LLMutex(NULL);
+	mSignal = new LLCondition();
+	mMutex = new LLMutex();
 }
 
 LLPhysicsDecomp::~LLPhysicsDecomp()
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index eb4b914e183f386c43a9a7fc4446f88c3583cb11..e5af47ab6cb69111f161585c53e9700b2bd1bed7 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -825,10 +825,10 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted)
 
 LLTextureCache::LLTextureCache(bool threaded)
 	: LLWorkerThread("TextureCache", threaded),
-	  mWorkersMutex(NULL),
-	  mHeaderMutex(NULL),
-	  mListMutex(NULL),
-	  mFastCacheMutex(NULL),
+	  mWorkersMutex(),
+	  mHeaderMutex(),
+	  mListMutex(),
+	  mFastCacheMutex(),
 	  mHeaderAPRFile(NULL),
 	  mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called.
 	  mTexturesSizeTotal(0),
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 1f69939c4644fa41232a1be7db6a59e23607fc1b..ca401f5c177e8ccb9891dab8c24017a21b0af9da 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -925,7 +925,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mCanUseHTTP(true),
 	  mRetryAttempt(0),
 	  mActiveCount(0),
-	  mWorkMutex(NULL),
+	  mWorkMutex(),
 	  mFirstPacket(0),
 	  mLastPacket(-1),
 	  mTotalPackets(0),
@@ -2543,8 +2543,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
 	  mDebugPause(FALSE),
 	  mPacketCount(0),
 	  mBadPacketCount(0),
-	  mQueueMutex(getAPRPool()),
-	  mNetworkQueueMutex(getAPRPool()),
+	  mQueueMutex(),
+	  mNetworkQueueMutex(),
 	  mTextureCache(cache),
 	  mImageDecodeThread(imagedecodethread),
 	  mTextureBandwidth(0),
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index d2a55785684d2890a12c5fdca055610926fc53c7..a9a91b158b1b5b3aa98e431950ea42884957c3a4 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -175,7 +175,7 @@ void LLFilePickerThread::run()
 //static
 void LLFilePickerThread::initClass()
 {
-	sMutex = new LLMutex(NULL);
+	sMutex = new LLMutex();
 }
 
 //static
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 2782cd954572471e0448512e7aba9f6d64033b82..dd6c77ca7d1ace427a03bb199197812f1fd293e7 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -155,7 +155,7 @@ void LLWatchdogTimeout::ping(const std::string& state)
 
 // LLWatchdog
 LLWatchdog::LLWatchdog() :
-	mSuspectsAccessMutex(NULL),
+	mSuspectsAccessMutex(),
 	mTimer(NULL),
 	mLastClockCount(0),
 	mKillerCallback(&default_killer_callback)
@@ -185,7 +185,7 @@ void LLWatchdog::init(killer_event_callback func)
 	mKillerCallback = func;
 	if(!mSuspectsAccessMutex && !mTimer)
 	{
-		mSuspectsAccessMutex = new LLMutex(NULL);
+		mSuspectsAccessMutex = new LLMutex();
 		mTimer = new LLWatchdogTimerThread();
 		mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000);
 		mLastClockCount = LLTimer::getTotalTime();