diff options
author | Matthew Newhook <matthew@zeroc.com> | 2001-12-27 18:38:22 +0000 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2001-12-27 18:38:22 +0000 |
commit | ca2b7f71b4133faf486a677b3744904c0f759471 (patch) | |
tree | 2ea5e06f611c338f8160a0c3bd36d069118926fe /cpp/src/IceUtil/RecMutex.cpp | |
parent | file run.py was initially added on branch IceThread. (diff) | |
download | ice-ca2b7f71b4133faf486a677b3744904c0f759471.tar.bz2 ice-ca2b7f71b4133faf486a677b3744904c0f759471.tar.xz ice-ca2b7f71b4133faf486a677b3744904c0f759471.zip |
IceThread merge.
Diffstat (limited to 'cpp/src/IceUtil/RecMutex.cpp')
-rw-r--r-- | cpp/src/IceUtil/RecMutex.cpp | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/cpp/src/IceUtil/RecMutex.cpp b/cpp/src/IceUtil/RecMutex.cpp new file mode 100644 index 00000000000..91735b00c78 --- /dev/null +++ b/cpp/src/IceUtil/RecMutex.cpp @@ -0,0 +1,168 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <IceUtil/RecMutex.h> +#include <IceUtil/Exception.h> + +using namespace std; + +#ifdef WIN32 + +IceUtil::RecMutex::RecMutex() : + _count(0) +{ + InitializeCriticalSection(&_mutex); +} + +IceUtil::RecMutex::~RecMutex() +{ + assert(_count == 0); + DeleteCriticalSection(&_mutex); +} + +bool +IceUtil::RecMutex::lock() +{ + EnterCriticalSection(&_mutex); + if (++_count > 1) + { + LeaveCriticalSection(&_mutex); + return false; + } + return true; +} + +bool +IceUtil::RecMutex::trylock() +{ + if (!TryEnterCriticalSection(&_mutex)) + { + throw LockedException(__FILE__, __LINE__); + } + if (++_count > 1) + { + LeaveCriticalSection(&_mutex); + return false; + } + return true; +} + +bool +IceUtil::RecMutex::unlock() +{ + if (--_count == 0) + { + LeaveCriticalSection(&_mutex); + return true; + } + return false; +} + +void +IceUtil::RecMutex::unlock(LockState& state) +{ + state.count = _count; + _count = 0; + LeaveCriticalSection(&_mutex); +} + +void +IceUtil::RecMutex::lock(LockState& state) +{ + EnterCriticalSection(&_mutex); + _count = state.count; +} +#else + +IceUtil::RecMutex::RecMutex() : + _count(0) +{ + const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE_NP }; + int rc = pthread_mutex_init(&_mutex, &attr); + if (rc != 0) + { + throw SyscallException(strerror(rc), __FILE__, __LINE__); + } +} + +IceUtil::RecMutex::~RecMutex() +{ + assert(_count == 0); + int rc = 0; + rc = pthread_mutex_destroy(&_mutex); + assert(rc == 0); +} + +bool +IceUtil::RecMutex::lock() +{ + int rc = pthread_mutex_lock(&_mutex); + if (rc != 0) + { + throw SyscallException(strerror(rc), __FILE__, __LINE__); + } + if (++_count > 1) + { + rc = pthread_mutex_unlock(&_mutex); + assert(rc == 0); + return false; + } + return true; +} + +bool +IceUtil::RecMutex::trylock() +{ + int rc = pthread_mutex_trylock(&_mutex); + if (rc != 0) + { + if (rc == EBUSY) + { + throw LockedException(__FILE__, __LINE__); + } + throw SyscallException(strerror(rc), __FILE__, __LINE__); + } + if (++_count > 1) + { + rc = pthread_mutex_unlock(&_mutex); + assert(rc == 0); + return false; + } + return true; +} + +bool +IceUtil::RecMutex::unlock() +{ + if (--_count == 0) + { + int rc = 0; // Prevent warnings when NDEBUG is defined. + rc = pthread_mutex_unlock(&_mutex); + assert(rc == 0); + return true; + } + return false; +} + +void +IceUtil::RecMutex::unlock(LockState& state) +{ + state.mutex = &_mutex; + state.count = _count; + _count = 0; +} + +void +IceUtil::RecMutex::lock(LockState& state) +{ + _count = state.count; +} + +#endif |