diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 034546c3f39f669e10566b80231cbb83a5596f68..8042fe25022fee6865f10d83e03405d501ec3ac2 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -164,14 +164,20 @@ template <typename Type> class LLAtomic32
 	~LLAtomic32<Type>() {};
 
 	operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
+	
+	Type	CurrentValue() const { apr_uint32_t data = apr_atomic_read32(const_cast< volatile apr_uint32_t* >(&mData)); return Type(data); }
+
 	Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }
 	void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }
 	void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }
 	Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++
 	Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
+
+	Type operator ++() { return apr_atomic_inc32(&mData); } // Type++
+	Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
 	
 private:
-	apr_uint32_t mData;
+	volatile apr_uint32_t mData;
 };
 
 typedef LLAtomic32<U32> LLAtomicU32;
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 1d56a52c32ee4c1dbaccc8fbcd603e9ef43ae2a7..6c117f7daf57fac7f6d4cc75ca2a2805b9fa1e9c 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -495,15 +495,7 @@ LLThreadSafeRefCount::LLThreadSafeRefCount() :
 
 LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src)
 {
-	if (sMutex)
-	{
-		sMutex->lock();
-	}
 	mRef = 0;
-	if (sMutex)
-	{
-		sMutex->unlock();
-	}
 }
 
 LLThreadSafeRefCount::~LLThreadSafeRefCount()
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 5c8bbca2cadb651862a9fcac74c595b1108d1404..c2f4184a8ad138568a298f1f6ac34d4f6f53d072 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -241,47 +241,43 @@ class LL_COMMON_API LLThreadSafeRefCount
 	LLThreadSafeRefCount(const LLThreadSafeRefCount&);
 	LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref) 
 	{
-		if (sMutex)
-		{
-			sMutex->lock();
-		}
 		mRef = 0;
-		if (sMutex)
-		{
-			sMutex->unlock();
-		}
 		return *this;
 	}
 
-
-	
 	void ref()
 	{
-		if (sMutex) sMutex->lock();
 		mRef++; 
-		if (sMutex) sMutex->unlock();
 	} 
 
 	S32 unref()
 	{
-		llassert(mRef >= 1);
-		if (sMutex) sMutex->lock();
-		S32 res = --mRef;
-		if (sMutex) sMutex->unlock();
-		if (0 == res) 
+		llassert(mRef >= 1);		
+		bool time_to_die = (mRef == 1);		
+		if (time_to_die)
 		{
-			delete this; 
+			if (sMutex) sMutex->lock();
+			// Looks redundant, but is very much not
+			// We need to check again once we've acquired the lock
+			// so that two threads who get into the if in parallel
+			// don't both attempt to the delete.
+			//
+			if (mRef == 1)
+				delete this; 
+			mRef--;
+			if (sMutex) sMutex->unlock();
 			return 0;
 		}
-		return res;
-	}	
+		return --mRef;		
+	}
 	S32 getNumRefs() const
 	{
-		return mRef;
+		const S32 currentVal = mRef.CurrentValue();
+		return currentVal;
 	}
 
 private: 
-	S32	mRef; 
+	LLAtomic32< S32	> mRef; 
 };
 
 //============================================================================