summaryrefslogtreecommitdiff
path: root/cpp/src/IceUtil/StaticMutex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceUtil/StaticMutex.cpp')
-rw-r--r--cpp/src/IceUtil/StaticMutex.cpp135
1 files changed, 134 insertions, 1 deletions
diff --git a/cpp/src/IceUtil/StaticMutex.cpp b/cpp/src/IceUtil/StaticMutex.cpp
index 9c5b4d15a3f..f5f307d9d24 100644
--- a/cpp/src/IceUtil/StaticMutex.cpp
+++ b/cpp/src/IceUtil/StaticMutex.cpp
@@ -7,6 +7,14 @@
//
// **********************************************************************
+//
+// We disable deprecation warning here, to allow clean compilation of
+// of deprecated methods.
+//
+#ifdef _MSC_VER
+# pragma warning( disable : 4996 )
+#endif
+
#include <IceUtil/StaticMutex.h>
#include <IceUtil/ThreadException.h>
@@ -72,5 +80,130 @@ void IceUtil::StaticMutex::initialize() const
}
LeaveCriticalSection(&_criticalSection);
}
-#endif
+bool
+IceUtil::StaticMutex::initialized() const
+{
+ //
+ // Read mutex and then inserts a memory barrier to ensure we can't
+ // see tmp != 0 before we see the initialized object
+ //
+ void* tmp = _mutex;
+ return InterlockedCompareExchangePointer(reinterpret_cast<void**>(&tmp), 0, 0) != 0;
+}
+
+void
+IceUtil::StaticMutex::lock() const
+{
+ if(!initialized())
+ {
+ initialize();
+ }
+ EnterCriticalSection(_mutex);
+ assert(_mutex->RecursionCount == 1);
+}
+
+bool
+IceUtil::StaticMutex::tryLock() const
+{
+ if(!initialized())
+ {
+ initialize();
+ }
+ if(!TryEnterCriticalSection(_mutex))
+ {
+ return false;
+ }
+ if(_mutex->RecursionCount > 1)
+ {
+ LeaveCriticalSection(_mutex);
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ return true;
+}
+
+void
+IceUtil::StaticMutex::unlock() const
+{
+ assert(_mutex != 0);
+ assert(_mutex->RecursionCount == 1);
+ LeaveCriticalSection(_mutex);
+}
+
+void
+IceUtil::StaticMutex::unlock(LockState&) const
+{
+ assert(_mutex != 0);
+ assert(_mutex->RecursionCount == 1);
+ LeaveCriticalSection(_mutex);
+}
+
+void
+IceUtil::StaticMutex::lock(LockState&) const
+{
+ if(!initialized())
+ {
+ initialize();
+ }
+ EnterCriticalSection(_mutex);
+}
+
+#else
+
+void
+IceUtil::StaticMutex::lock() const
+{
+ int rc = pthread_mutex_lock(&_mutex);
+ if(rc != 0)
+ {
+ if(rc == EDEADLK)
+ {
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ else
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+ }
+}
+
+bool
+IceUtil::StaticMutex::tryLock() const
+{
+ int rc = pthread_mutex_trylock(&_mutex);
+ if(rc != 0 && rc != EBUSY)
+ {
+ if(rc == EDEADLK)
+ {
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ else
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+ }
+ return (rc == 0);
+}
+
+void
+IceUtil::StaticMutex::unlock() const
+{
+ int rc = pthread_mutex_unlock(&_mutex);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+}
+
+void
+IceUtil::StaticMutex::unlock(LockState& state) const
+{
+ state.mutex = &_mutex;
+}
+
+void
+IceUtil::StaticMutex::lock(LockState&) const
+{
+}
+
+#endif