diff options
-rw-r--r-- | cpp/include/IceUtil/RWRecMutex.h | 2 | ||||
-rw-r--r-- | cpp/include/IceUtil/Thread.h | 70 | ||||
-rw-r--r-- | cpp/src/IceUtil/RWRecMutex.cpp | 18 | ||||
-rw-r--r-- | cpp/src/IceUtil/Thread.cpp | 328 |
4 files changed, 133 insertions, 285 deletions
diff --git a/cpp/include/IceUtil/RWRecMutex.h b/cpp/include/IceUtil/RWRecMutex.h index 84895e55aef..9bdff167b95 100644 --- a/cpp/include/IceUtil/RWRecMutex.h +++ b/cpp/include/IceUtil/RWRecMutex.h @@ -368,7 +368,7 @@ private: // // If there is an active writer this is the ID of the writer thread. // - mutable ThreadId _writerId; + mutable ThreadControl _writerId; // // Number of waiting writers (including any upgrader). diff --git a/cpp/include/IceUtil/Thread.h b/cpp/include/IceUtil/Thread.h index 03f0304aba5..bd7fbcfee7d 100644 --- a/cpp/include/IceUtil/Thread.h +++ b/cpp/include/IceUtil/Thread.h @@ -19,37 +19,6 @@ namespace IceUtil class Time; -#ifdef _WIN32 -struct HandleWrapper : public Shared -{ - // Inline for performance reasons. - HandleWrapper(HANDLE h, bool r = true) : - handle(h), release(r) - { - } - - // Inline for performance reasons. - virtual ~HandleWrapper() - { - if(handle && release) - { - CloseHandle(handle); - } - } - - HANDLE handle; - bool release; -}; - -typedef Handle<HandleWrapper> HandleWrapperPtr; -#endif - -#ifdef _WIN32 - typedef unsigned int ThreadId; -#else - typedef pthread_t ThreadId; -#endif - class ICE_UTIL_API ThreadControl { public: @@ -57,22 +26,19 @@ public: ThreadControl(); #ifdef _WIN32 - ThreadControl(const HandleWrapperPtr&, ThreadId); + ThreadControl(HANDLE, DWORD); #else - ThreadControl(ThreadId); + ThreadControl(pthread_t); #endif ThreadControl(const ThreadControl&); + + ~ThreadControl(); + ThreadControl& operator=(const ThreadControl&); bool operator==(const ThreadControl&) const; bool operator!=(const ThreadControl&) const; - bool operator<(const ThreadControl&) const; - - // - // Return the ID of the thread underlying this ThreadControl. - // - ThreadId id() const; // // Wait until the controlled thread terminates. The call has POSIX @@ -107,11 +73,12 @@ public: private: - Mutex _stateMutex; #ifdef _WIN32 - HandleWrapperPtr _handle; + HANDLE _handle; + DWORD _id; +#else + pthread_t _thread; #endif - ThreadId _id; }; class ICE_UTIL_API Thread : virtual public IceUtil::Shared @@ -121,8 +88,6 @@ public: Thread(); virtual ~Thread(); - ThreadId id() const; - virtual void run() = 0; ThreadControl start(size_t = 0); @@ -133,17 +98,20 @@ public: bool operator!=(const Thread&) const; bool operator<(const Thread&) const; - Thread(const Thread&); // Copying is forbidden - void operator=(const Thread&); // Assignment is forbidden - -private: - +protected: Mutex _stateMutex; + bool _started; #ifdef _WIN32 - HandleWrapperPtr _handle; + HANDLE _handle; + DWORD _id; +#else + pthread_t _thread; #endif - ThreadId _id; + +private: + Thread(const Thread&); // Copying is forbidden + void operator=(const Thread&); // Assignment is forbidden }; typedef Handle<Thread> ThreadPtr; diff --git a/cpp/src/IceUtil/RWRecMutex.cpp b/cpp/src/IceUtil/RWRecMutex.cpp index bb817eb646d..1cf27f35348 100644 --- a/cpp/src/IceUtil/RWRecMutex.cpp +++ b/cpp/src/IceUtil/RWRecMutex.cpp @@ -38,7 +38,6 @@ IceUtil::DeadlockException::ice_throw() const IceUtil::RWRecMutex::RWRecMutex() : _count(0), - _writerId(0), _waitingWriters(0), _upgrading(false) { @@ -120,7 +119,7 @@ IceUtil::RWRecMutex::writeLock() const // If the mutex is already write locked by this writer then // decrement _count, and return. // - if(_count < 0 && _writerId == ThreadControl().id()) + if(_count < 0 && _writerId == ThreadControl()) { --_count; return; @@ -149,7 +148,7 @@ IceUtil::RWRecMutex::writeLock() const // Got the lock, indicate it's held by a writer. // _count = -1; - _writerId = ThreadControl().id(); + _writerId = ThreadControl(); } bool @@ -161,7 +160,7 @@ IceUtil::RWRecMutex::tryWriteLock() const // If the mutex is already write locked by this writer then // decrement _count, and return. // - if(_count < 0 && _writerId == ThreadControl().id()) + if(_count < 0 && _writerId == ThreadControl()) { --_count; return true; @@ -179,7 +178,7 @@ IceUtil::RWRecMutex::tryWriteLock() const // Got the lock, indicate it's held by a writer. // _count = -1; - _writerId = ThreadControl().id(); + _writerId = ThreadControl(); return true; } @@ -191,7 +190,7 @@ IceUtil::RWRecMutex::timedWriteLock(const Time& timeout) const // // If the mutex is already write locked by this writer then // decrement _count, and return. - if(_count < 0 && _writerId == ThreadControl().id()) + if(_count < 0 && _writerId == ThreadControl()) { --_count; return true; @@ -233,7 +232,7 @@ IceUtil::RWRecMutex::timedWriteLock(const Time& timeout) const // Got the lock, indicate it's held by a writer. // _count = -1; - _writerId = ThreadControl().id(); + _writerId = ThreadControl(); return true; } @@ -308,7 +307,6 @@ IceUtil::RWRecMutex::unlock() const } else if(wr) { - _writerId = 0; // // Wake readers // @@ -357,7 +355,7 @@ IceUtil::RWRecMutex::upgrade() const // Got the lock, indicate it's held by a writer. // _count = -1; - _writerId = ThreadControl().id(); + _writerId = ThreadControl(); _upgrading = false; } @@ -425,7 +423,7 @@ IceUtil::RWRecMutex::timedUpgrade(const Time& timeout) const // Got the lock, indicate it's held by a writer. // _count = -1; - _writerId = ThreadControl().id(); + _writerId = ThreadControl(); _upgrading = false; return true; } diff --git a/cpp/src/IceUtil/Thread.cpp b/cpp/src/IceUtil/Thread.cpp index 65e1886a7b8..8c10fbe8475 100644 --- a/cpp/src/IceUtil/Thread.cpp +++ b/cpp/src/IceUtil/Thread.cpp @@ -15,32 +15,53 @@ using namespace std; #ifdef _WIN32 -IceUtil::ThreadControl::ThreadControl() -{ - IceUtil::Mutex::Lock lock(_stateMutex); - _handle = new HandleWrapper(GetCurrentThread(), false); - _id = GetCurrentThreadId(); +IceUtil::ThreadControl::ThreadControl() : + _handle(0), + _id(GetCurrentThreadId()) +{ + HANDLE currentThread = GetCurrentThread(); + HANDLE currentProcess = GetCurrentProcess(); + + if(DuplicateHandle(currentProcess, + currentThread, + currentProcess, + &_handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS) == 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } } -IceUtil::ThreadControl::ThreadControl(const HandleWrapperPtr& handle, ThreadId id) +IceUtil::ThreadControl::ThreadControl(HANDLE handle, DWORD id) : + _id(id) { - IceUtil::Mutex::Lock lock(_stateMutex); - _handle = handle; - _id = id; -} + HANDLE currentProcess = GetCurrentProcess(); -IceUtil::ThreadControl::ThreadControl(const ThreadControl& tc) -{ - ThreadId id; - HandleWrapperPtr handle; + if(DuplicateHandle(currentProcess, + handle, + currentProcess, + &_handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS) == 0) { - IceUtil::Mutex::Lock lock(tc._stateMutex); - id = tc._id; - handle = tc._handle; + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); } - IceUtil::Mutex::Lock lock(_stateMutex); - _handle = handle; - _id = id; +} + +IceUtil::ThreadControl::ThreadControl(const ThreadControl& tc) : + _handle(0) +{ + operator=(tc); +} + +IceUtil::ThreadControl::~ThreadControl() +{ + assert(_handle != 0); + bool ok = CloseHandle(_handle); + assert(ok); } IceUtil::ThreadControl& @@ -48,16 +69,23 @@ IceUtil::ThreadControl::operator=(const ThreadControl& rhs) { if(&rhs != this) { - ThreadId id; - HandleWrapperPtr handle; + if(_handle != 0 && CloseHandle(_handle) == 0) { - IceUtil::Mutex::Lock lock(rhs._stateMutex); - handle = rhs._handle; - id = rhs._id; + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } + _id = rhs._id; + + HANDLE currentProcess = GetCurrentProcess(); + if(DuplicateHandle(currentProcess, + rhs._handle, + currentProcess, + &_handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS) == 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); } - IceUtil::Mutex::Lock lock(_stateMutex); - _handle = handle; - _id = id; } return *this; } @@ -65,41 +93,20 @@ IceUtil::ThreadControl::operator=(const ThreadControl& rhs) bool IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const { - ThreadId id = rhs.id(); - IceUtil::Mutex::Lock lock(_stateMutex); - return _id == id; + return _id == rhs._id; } bool IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const { - return !operator==(rhs); -} - -bool -IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const -{ - ThreadId id = rhs.id(); - IceUtil::Mutex::Lock lock(_stateMutex); - return _id < id; + return _id != rhs._id; } -IceUtil::ThreadId -IceUtil::ThreadControl::id() const -{ - IceUtil::Mutex::Lock lock(_stateMutex); - return _id; -} void IceUtil::ThreadControl::join() { - HandleWrapperPtr handle; - { - IceUtil::Mutex::Lock lock(_stateMutex); - handle = _handle; - } - int rc = WaitForSingleObject(handle->handle, INFINITE); + int rc = WaitForSingleObject(_handle, INFINITE); if(rc != WAIT_OBJECT_0) { throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); @@ -109,19 +116,15 @@ IceUtil::ThreadControl::join() void IceUtil::ThreadControl::detach() { - // No-op: Windows doesn't have the concept of detaching a thread. + // On Windows, a thread is cleaned up when the last handle to this thread + // is closed. } bool IceUtil::ThreadControl::isAlive() const { - HandleWrapperPtr handle; - { - IceUtil::Mutex::Lock lock(_stateMutex); - handle = _handle; - } DWORD rc; - if(GetExitCodeThread(handle->handle, &rc) == 0) + if(GetExitCodeThread(_handle, &rc) == 0) { return false; } @@ -145,27 +148,20 @@ IceUtil::ThreadControl::yield() Sleep(0); } -IceUtil::Thread::Thread() +IceUtil::Thread::Thread() : + _started(false), + _handle(0), + _id(0) { - IceUtil::Mutex::Lock lock(_stateMutex); - _started = false; - _id = 0; - _handle = new HandleWrapper(0); } IceUtil::Thread::~Thread() { -} - -IceUtil::ThreadId -IceUtil::Thread::id() const -{ - IceUtil::Mutex::Lock lock(_stateMutex); - if(!_started) + if(_handle != 0) { - throw ThreadNotStartedException(__FILE__, __LINE__); + bool ok = CloseHandle(_handle); + assert(ok); } - return _id; } static unsigned int @@ -229,13 +225,16 @@ IceUtil::Thread::start(size_t stackSize) // __incRef(); - _handle->handle = + unsigned int id; + + _handle = reinterpret_cast<HANDLE>( _beginthreadex(0, static_cast<unsigned int>(stackSize), - startHook, this, 0, &_id)); + startHook, this, 0, &id)); + _id = id; - if(_handle->handle == 0) + if(_handle == 0) { __decRef(); throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); @@ -260,76 +259,40 @@ IceUtil::Thread::getThreadControl() const bool IceUtil::Thread::operator==(const Thread& rhs) const { - // - // Get rhs ID. - // - ThreadId id = rhs.id(); - - // - // Check that this thread was started. - // - IceUtil::Mutex::Lock lock(_stateMutex); - if(!_started) - { - throw ThreadNotStartedException(__FILE__, __LINE__); - } - - // - // We perform the comparison within the scope of the lock, otherwise the hardware has no - // way of knowing that it might have to flush a cache line. - // - return _id == id; + return this == &rhs; } bool IceUtil::Thread::operator!=(const Thread& rhs) const { - return !operator==(rhs); + return this != &rhs; } bool IceUtil::Thread::operator<(const Thread& rhs) const { - // - // Get rhs ID. - // - ThreadId id = rhs.id(); - - // - // Check that this thread was started. - // - IceUtil::Mutex::Lock lock(_stateMutex); - if(!_started) - { - throw ThreadNotStartedException(__FILE__, __LINE__); - } - - // - // We perform the comparison within the scope of the lock, otherwise the hardware has no - // way of knowing that it might have to flush a cache line. - // - return _id < id; + return this < &rhs; } #else -IceUtil::ThreadControl::ThreadControl(ThreadId id) +IceUtil::ThreadControl::ThreadControl(pthread_t thread) : + _thread(thread) { - IceUtil::Mutex::Lock lock(_stateMutex); - _id = id; } -IceUtil::ThreadControl::ThreadControl() +IceUtil::ThreadControl::ThreadControl() : + _thread(pthread_self()) { - IceUtil::Mutex::Lock lock(_stateMutex); - _id = pthread_self(); } -IceUtil::ThreadControl::ThreadControl(const ThreadControl& tc) +IceUtil::ThreadControl::ThreadControl(const ThreadControl& tc) : + _thread(tc._thread) +{ +} + +IceUtil::ThreadControl::~ThreadControl() { - ThreadId id = tc.id(); - IceUtil::Mutex::Lock lock(_stateMutex); - _id = id; } IceUtil::ThreadControl& @@ -337,9 +300,7 @@ IceUtil::ThreadControl::operator=(const ThreadControl& rhs) { if(&rhs != this) { - ThreadId id = rhs.id(); - IceUtil::Mutex::Lock lock(_stateMutex); - _id = id; + _thread = rhs._thread; } return *this; } @@ -347,9 +308,7 @@ IceUtil::ThreadControl::operator=(const ThreadControl& rhs) bool IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const { - ThreadId id = rhs.id(); - IceUtil::Mutex::Lock lock(_stateMutex); - return pthread_equal(_id, id); + return pthread_equal(_thread, rhs._thread) != 0; } bool @@ -358,32 +317,11 @@ IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const return !operator==(rhs); } -bool -IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const -{ - ThreadId id = rhs.id(); - IceUtil::Mutex::Lock lock(_stateMutex); - // NOTE: Linux specific - return _id < id; -} - -IceUtil::ThreadId -IceUtil::ThreadControl::id() const -{ - IceUtil::Mutex::Lock lock(_stateMutex); - return _id; -} - void IceUtil::ThreadControl::join() { - ThreadId id; - { - IceUtil::Mutex::Lock lock(_stateMutex); - id = _id; - } void* ignore = 0; - int rc = pthread_join(id, &ignore); + int rc = pthread_join(_thread, &ignore); if(rc != 0) { throw ThreadSyscallException(__FILE__, __LINE__, rc); @@ -393,12 +331,7 @@ IceUtil::ThreadControl::join() void IceUtil::ThreadControl::detach() { - ThreadId id; - { - IceUtil::Mutex::Lock lock(_stateMutex); - id = _id; - } - int rc = pthread_detach(id); + int rc = pthread_detach(_thread); if(rc != 0) { throw ThreadSyscallException(__FILE__, __LINE__, rc); @@ -411,13 +344,11 @@ IceUtil::ThreadControl::isAlive() const int policy; int ret; struct sched_param param; - IceUtil::Mutex::Lock lock(_stateMutex); - - ret = pthread_getschedparam(_id, &policy, ¶m); + ret = pthread_getschedparam(_thread, &policy, ¶m); #ifdef __APPLE__ if (ret == 0) { - ret = pthread_setschedparam(_id, policy, ¶m); + ret = pthread_setschedparam(_thread, policy, ¶m); } #endif return (ret == 0); @@ -439,29 +370,18 @@ IceUtil::ThreadControl::yield() sched_yield(); } -IceUtil::Thread::Thread() +IceUtil::Thread::Thread() : + _started(false) { - IceUtil::Mutex::Lock lock(_stateMutex); - _started = false; - _id = 0; } IceUtil::Thread::~Thread() { } -IceUtil::ThreadId -IceUtil::Thread::id() const -{ - IceUtil::Mutex::Lock lock(_stateMutex); - if(!_started) - { - throw ThreadNotStartedException(__FILE__, __LINE__); - } - return _id; -} -extern "C" { +extern "C" +{ static void* startHook(void* arg) { @@ -535,7 +455,7 @@ IceUtil::Thread::start(size_t stackSize) __decRef(); throw ThreadSyscallException(__FILE__, __LINE__, rc); } - rc = pthread_create(&_id, &attr, startHook, this); + rc = pthread_create(&_thread, &attr, startHook, this); if(rc != 0) { __decRef(); @@ -544,7 +464,7 @@ IceUtil::Thread::start(size_t stackSize) } else { - int rc = pthread_create(&_id, 0, startHook, this); + int rc = pthread_create(&_thread, 0, startHook, this); if(rc != 0) { __decRef(); @@ -554,7 +474,7 @@ IceUtil::Thread::start(size_t stackSize) _started = true; - return ThreadControl(_id); + return ThreadControl(_thread); } IceUtil::ThreadControl @@ -565,63 +485,25 @@ IceUtil::Thread::getThreadControl() const { throw ThreadNotStartedException(__FILE__, __LINE__); } - return ThreadControl(_id); + return ThreadControl(_thread); } bool IceUtil::Thread::operator==(const Thread& rhs) const { - // - // Get rhs ID. - // - ThreadId id = rhs.id(); - - // - // Check that this thread was started. - // - IceUtil::Mutex::Lock lock(_stateMutex); - if(!_started) - { - throw ThreadNotStartedException(__FILE__, __LINE__); - } - - // - // We perform the comparison within the scope of the lock, otherwise the hardware has no - // way of knowing that it might have to flush a cache line. - // - return pthread_equal(_id, id); + return this == &rhs; } bool IceUtil::Thread::operator!=(const Thread& rhs) const { - return !operator==(rhs); + return this != &rhs; } bool IceUtil::Thread::operator<(const Thread& rhs) const { - // - // Get rhs ID. - // - ThreadId id = rhs.id(); - - // - // Check that this thread was started. - // - IceUtil::Mutex::Lock lock(_stateMutex); - if(!_started) - { - throw ThreadNotStartedException(__FILE__, __LINE__); - } - - // - // We perform the comparison within the scope of the lock, otherwise the hardware has no - // way of knowing that it might have to flush a cache line. - // - // NOTE: Linux specific - // - return _id < id; + return this < &rhs; } #endif |