diff options
Diffstat (limited to 'cppe')
-rw-r--r-- | cppe/include/IceE/RWRecMutex.h | 33 | ||||
-rw-r--r-- | cppe/include/IceE/Thread.h | 63 | ||||
-rwxr-xr-x | cppe/src/IceE/Connection.cpp | 2 | ||||
-rw-r--r-- | cppe/src/IceE/RWRecMutex.cpp | 127 | ||||
-rw-r--r-- | cppe/src/IceE/Thread.cpp | 356 | ||||
-rw-r--r-- | cppe/test/IceE/thread/AliveTest.cpp | 4 |
6 files changed, 278 insertions, 307 deletions
diff --git a/cppe/include/IceE/RWRecMutex.h b/cppe/include/IceE/RWRecMutex.h index c1cd0dc44a8..576639069f1 100644 --- a/cppe/include/IceE/RWRecMutex.h +++ b/cppe/include/IceE/RWRecMutex.h @@ -17,6 +17,20 @@ namespace IceUtil { +class ICE_API DeadlockException : public Exception +{ +public: + + DeadlockException(const char*, int); + virtual const std::string ice_name() const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; + +private: + + static const char* _name; +}; + template <typename T> class RLockT { @@ -96,6 +110,12 @@ public: return _mutex.timedUpgrade(timeout); } + void + downgrade() const + { + _mutex.downgrade(); + } + protected: // TryRLockT's constructors @@ -327,6 +347,11 @@ public: // bool timedUpgrade(const Time&) const; + // + // Downgrade a write lock to a read lock. + // + void downgrade() const; + private: // noncopyable @@ -343,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. @@ -351,6 +376,11 @@ private: mutable unsigned int _waitingWriters; // + // True if an upgrader wants the lock. + // + mutable bool _upgrading; + + // // Internal mutex. // Mutex _mutex; @@ -360,6 +390,7 @@ private: // mutable Cond _readers; mutable Cond _writers; + mutable Cond _upgrader; }; } // End namespace Ice diff --git a/cppe/include/IceE/Thread.h b/cppe/include/IceE/Thread.h index 38fbfa448a1..db2b2ed420f 100644 --- a/cppe/include/IceE/Thread.h +++ b/cppe/include/IceE/Thread.h @@ -19,7 +19,7 @@ namespace IceUtil class Time; -#ifdef _WIN32 +#ifdef _WIN32_WCE struct HandleWrapper : public Shared { // Inline for performance reasons. @@ -40,18 +40,9 @@ struct HandleWrapper : public Shared HANDLE handle; bool release; }; - typedef Handle<HandleWrapper> HandleWrapperPtr; #endif -#ifdef _WIN32_WCE - typedef unsigned long ThreadId; -#elif _WIN32 - typedef unsigned int ThreadId; -#else - typedef pthread_t ThreadId; -#endif - class ICE_API ThreadControl { public: @@ -59,9 +50,9 @@ public: ThreadControl(); #ifdef _WIN32 - ThreadControl(const HandleWrapperPtr&, ThreadId); + ThreadControl(const HandleWrapperPtr&, DWORD); #else - ThreadControl(ThreadId); + ThreadControl(pthread_t); #endif ThreadControl(const ThreadControl&); @@ -69,12 +60,6 @@ public: 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 @@ -99,21 +84,27 @@ public: void detach(); // - // Check whether a thread is still alive. This is useful to implement - // a non-blocking join(). + // id() returns the Thread ID on Windows and the underlying pthread_t + // on POSIX platforms. // - bool isAlive() const; +#ifdef _WIN32 + typedef DWORD ID; +#else + typedef pthread_t ID; +#endif + ID id() const; static void sleep(const Time&); static void yield(); private: - Mutex _stateMutex; #ifdef _WIN32 + DWORD _id; HandleWrapperPtr _handle; +#else + pthread_t _thread; #endif - ThreadId _id; }; class ICE_API Thread : virtual public IceUtil::Shared @@ -123,8 +114,6 @@ public: Thread(); virtual ~Thread(); - ThreadId id() const; - virtual void run() = 0; ThreadControl start(size_t = 0); @@ -135,17 +124,33 @@ public: bool operator!=(const Thread&) const; bool operator<(const Thread&) const; - Thread(const Thread&); // Copying is forbidden - void operator=(const Thread&); // Assignment is forbidden + // + // Check whether a thread is still alive. This is useful to implement + // a non-blocking join(). + // + bool isAlive() const; -private: + // + // This function is an implementation detail; + // do not call it. + // + void _done(); + +protected: Mutex _stateMutex; bool _started; + bool _running; + #ifdef _WIN32 HandleWrapperPtr _handle; + DWORD _id; +#else + pthread_t _thread; #endif - ThreadId _id; + + Thread(const Thread&); // Copying is forbidden + void operator=(const Thread&); // Assignment is forbidden }; typedef Handle<Thread> ThreadPtr; diff --git a/cppe/src/IceE/Connection.cpp b/cppe/src/IceE/Connection.cpp index f2878204a81..57058258ff9 100755 --- a/cppe/src/IceE/Connection.cpp +++ b/cppe/src/IceE/Connection.cpp @@ -178,7 +178,7 @@ Ice::Connection::isFinished() const if(_transceiver != 0 #ifndef ICEE_PURE_BLOCKING_CLIENT - || _dispatchCount != 0 || (_threadPerConnection && _threadPerConnection->getThreadControl().isAlive()) + || _dispatchCount != 0 || (_threadPerConnection && _threadPerConnection->isAlive()) #endif ) { diff --git a/cppe/src/IceE/RWRecMutex.cpp b/cppe/src/IceE/RWRecMutex.cpp index ed2caa767a4..52ef988db8e 100644 --- a/cppe/src/IceE/RWRecMutex.cpp +++ b/cppe/src/IceE/RWRecMutex.cpp @@ -11,11 +11,35 @@ #include <IceE/Exception.h> #include <IceE/Time.h> +IceUtil::DeadlockException::DeadlockException(const char* file, int line) : + Exception(file, line) +{ +} + +const char* IceUtil::DeadlockException::_name = "IceUtil::DeadlockException"; + +const ::std::string +IceUtil::DeadlockException::ice_name() const +{ + return _name; +} + +IceUtil::Exception* +IceUtil::DeadlockException::ice_clone() const +{ + return new DeadlockException(*this); +} + +void +IceUtil::DeadlockException::ice_throw() const +{ + throw *this; +} IceUtil::RWRecMutex::RWRecMutex() : _count(0), - _writerId(0), - _waitingWriters(0) + _waitingWriters(0), + _upgrading(false) { } @@ -95,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; @@ -107,7 +131,7 @@ IceUtil::RWRecMutex::writeLock() const // while(_count != 0) { - _waitingWriters++; + ++_waitingWriters; try { _writers.wait(lock); @@ -124,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 @@ -136,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; @@ -154,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; } @@ -166,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; @@ -182,7 +206,7 @@ IceUtil::RWRecMutex::timedWriteLock(const Time& timeout) const Time remainder = end - Time::now(); if(remainder > Time()) { - _waitingWriters++; + ++_waitingWriters; try { bool result = _writers.timedWait(lock, remainder); @@ -208,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; } @@ -258,7 +282,7 @@ IceUtil::RWRecMutex::unlock() const // ww = (_waitingWriters != 0 && _count == 0); wr = (_waitingWriters == 0); - } + } // Unlock mutex. // // Wake up a waiting writer if there is one. If not, wake up all @@ -266,14 +290,23 @@ IceUtil::RWRecMutex::unlock() const // if(ww) { - // - // Wake writer - // - _writers.signal(); + if(_upgrading) + { + // + // If there is an untimed upgrader, it runs. + // + _upgrader.signal(); + } + else + { + // + // Wake a normal writer. + // + _writers.signal(); + } } else if(wr) { - _writerId = 0; // // Wake readers // @@ -286,6 +319,11 @@ IceUtil::RWRecMutex::upgrade() const { Mutex::Lock lock(_mutex); + if(_upgrading) + { + throw DeadlockException(__FILE__, __LINE__); + } + // Reader owns at least one count // assert(_count > 0); @@ -294,27 +332,30 @@ IceUtil::RWRecMutex::upgrade() const // // Wait to acquire the write lock. // + _upgrading = true; while(_count != 0) { - _waitingWriters++; + ++_waitingWriters; try { - _writers.wait(lock); + _upgrader.wait(lock); } catch(...) { + _upgrading = false; --_waitingWriters; - _count++; + ++_count; throw; } - _waitingWriters--; + --_waitingWriters; } // // Got the lock, indicate it's held by a writer. // _count = -1; - _writerId = ThreadControl().id(); + _writerId = ThreadControl(); + _upgrading = false; } bool @@ -322,6 +363,15 @@ IceUtil::RWRecMutex::timedUpgrade(const Time& timeout) const { Mutex::Lock lock(_mutex); + // + // If another reader is already waiting for an upgrade, + // this upgrade cannot possibly succeed. + // + if(_upgrading) + { + return false; + } + // Reader owns at least one count // assert(_count > 0); @@ -330,35 +380,40 @@ IceUtil::RWRecMutex::timedUpgrade(const Time& timeout) const // // Wait to acquire the write lock. // + _upgrading = true; Time end = Time::now() + timeout; while(_count != 0) { Time remainder = end - Time::now(); if(remainder > Time()) { - _waitingWriters++; + ++_waitingWriters; try { - bool result = _writers.timedWait(lock, remainder); - _waitingWriters--; - if(result == false) + bool result = _upgrader.timedWait(lock, remainder); + --_waitingWriters; + if(!result) { - _count++; + _upgrading = false; + ++_count; return false; } } catch(...) { + _upgrading = false; --_waitingWriters; - _count++; + ++_count; throw; } } else { // - // If a timeout occurred then the lock wasn't acquired - _count++; + // The lock isn't acquired if a timeout occurred. + // + ++_count; + _upgrading = false; return false; } } @@ -367,6 +422,18 @@ 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; } + +void +IceUtil::RWRecMutex::downgrade() const +{ + Mutex::Lock lock(_mutex); + + if(++_count == 0) + { + _count = 1; + } +} diff --git a/cppe/src/IceE/Thread.cpp b/cppe/src/IceE/Thread.cpp index d5cc992bd65..7869ec1583a 100644 --- a/cppe/src/IceE/Thread.cpp +++ b/cppe/src/IceE/Thread.cpp @@ -17,32 +17,53 @@ using namespace std; #ifdef _WIN32 -IceUtil::ThreadControl::ThreadControl() +#ifndef _WIN32_WCE +# include <process.h> +#endif + +#ifdef _WIN32_WCE +// +// Under WCE it is not possible to call DuplicateHandle on a thread +// handle. Instead we use the handle wrapper. This constructor uses +// GetCurrentThreadId() to get the current thread object. This object +// can also be used as the thread handle. +// +IceUtil::ThreadControl::ThreadControl() : + _id(GetCurrentThreadId()), + _handle(new HandleWrapper(static_cast<HANDLE>(_id), false)) { - IceUtil::Mutex::Lock lock(_stateMutex); - _handle = new HandleWrapper(GetCurrentThread(), false); - _id = GetCurrentThreadId(); } +#else +IceUtil::ThreadControl::ThreadControl() : + _id(GetCurrentThreadId()), + _handle(new HandleWrapper(0)) +{ + HANDLE currentThread = GetCurrentThread(); + HANDLE currentProcess = GetCurrentProcess(); + + if(DuplicateHandle(currentProcess, + currentThread, + currentProcess, + &_handle->handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS) == 0) + { + throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); + } +} +#endif -IceUtil::ThreadControl::ThreadControl(const HandleWrapperPtr& handle, ThreadId id) +IceUtil::ThreadControl::ThreadControl(const HandleWrapperPtr& handle, IceUtil::ThreadControl::ID id) : + _id(id), + _handle(handle) { - IceUtil::Mutex::Lock lock(_stateMutex); - _handle = handle; - _id = id; } -IceUtil::ThreadControl::ThreadControl(const ThreadControl& tc) +IceUtil::ThreadControl::ThreadControl(const ThreadControl& tc) : + _id(tc.id), + _handle(tc.handle) { - ThreadId id; - HandleWrapperPtr handle; - { - IceUtil::Mutex::Lock lock(tc._stateMutex); - id = tc._id; - handle = tc._handle; - } - IceUtil::Mutex::Lock lock(_stateMutex); - _handle = handle; - _id = id; } IceUtil::ThreadControl& @@ -50,16 +71,8 @@ IceUtil::ThreadControl::operator=(const ThreadControl& rhs) { if(&rhs != this) { - ThreadId id; - HandleWrapperPtr handle; - { - IceUtil::Mutex::Lock lock(rhs._stateMutex); - handle = rhs._handle; - id = rhs._id; - } - IceUtil::Mutex::Lock lock(_stateMutex); - _handle = handle; - _id = id; + _id = rhs.id; + _handle = rhs.handle; } return *this; } @@ -67,41 +80,19 @@ 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; -} - -IceUtil::ThreadId -IceUtil::ThreadControl::id() const -{ - IceUtil::Mutex::Lock lock(_stateMutex); - return _id; + return _id != rhs._id; } void IceUtil::ThreadControl::join() { - HandleWrapperPtr handle; - { - IceUtil::Mutex::Lock lock(_stateMutex); - handle = _handle; - } - int rc = WaitForSingleObject(handle->handle, INFINITE); + int rc = WaitForSingleObject(_handle->handle, INFINITE); if(rc != WAIT_OBJECT_0) { throw ThreadSyscallException(__FILE__, __LINE__, GetLastError()); @@ -114,27 +105,16 @@ IceUtil::ThreadControl::detach() // No-op: Windows doesn't have the concept of detaching a thread. } -bool -IceUtil::ThreadControl::isAlive() const +IceUtil::ThreadControl::ID +IceUtil::ThreadControl::id() const { - HandleWrapperPtr handle; - { - IceUtil::Mutex::Lock lock(_stateMutex); - handle = _handle; - } - DWORD rc; - if(GetExitCodeThread(handle->handle, &rc) == 0) - { - return false; - } - return rc == STILL_ACTIVE; + return _id; } void IceUtil::ThreadControl::sleep(const Time& timeout) { - long msec = (long)timeout.toMilliSeconds(); - Sleep(msec); + Sleep(static_cast<long>(timeout.toMilliSeconds())); } void @@ -148,29 +128,18 @@ IceUtil::ThreadControl::yield() Sleep(0); } -IceUtil::Thread::Thread() +IceUtil::Thread::Thread() : + _started(false), + _running(false), + _handle(new HandleWrapper(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) - { - throw ThreadNotStartedException(__FILE__, __LINE__); - } - return _id; -} - static void* startHook(void* arg) { @@ -200,13 +169,11 @@ startHook(void* arg) { fprintf(stderr, "IceUtil::Thread::run(): uncaught exception: %s\n", e.toString()); } + thread->_done(); + return 0; } -#ifndef _WIN32_WCE -#include <process.h> -#endif - IceUtil::ThreadControl IceUtil::Thread::start(size_t stackSize) { @@ -247,6 +214,7 @@ IceUtil::Thread::start(size_t stackSize) } _started = true; + _running = true; return ThreadControl(_handle, _id); } @@ -265,25 +233,7 @@ 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 @@ -295,46 +245,38 @@ IceUtil::Thread::operator!=(const Thread& rhs) const bool IceUtil::Thread::operator<(const Thread& rhs) const { - // - // Get rhs ID. - // - ThreadId id = rhs.id(); + return this < &rhs; +} - // - // Check that this thread was started. - // +bool +IceUtil::Thread::isAlive() const +{ IceUtil::Mutex::Lock lock(_stateMutex); - if(!_started) - { - throw ThreadNotStartedException(__FILE__, __LINE__); - } + return _running; +} - // - // 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; +void +IceUtil::Thread::_done() +{ + IceUtil::Mutex::Lock lock(_stateMutex); + _running = false; } #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) { - ThreadId id = tc.id(); - IceUtil::Mutex::Lock lock(_stateMutex); - _id = id; } IceUtil::ThreadControl& @@ -342,9 +284,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; } @@ -352,9 +292,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 @@ -363,32 +301,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); @@ -398,34 +315,17 @@ 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); } } -bool -IceUtil::ThreadControl::isAlive() const +IceUtil::ThreadControl::ID +IceUtil::ThreadControl::id() const { - int policy; - int ret; - struct sched_param param; - IceUtil::Mutex::Lock lock(_stateMutex); - - ret = pthread_getschedparam(_id, &policy, ¶m); -#ifdef __APPLE__ - if (ret == 0) - { - ret = pthread_setschedparam(_id, policy, ¶m); - } -#endif - return (ret == 0); + return _thread; } void @@ -444,41 +344,30 @@ IceUtil::ThreadControl::yield() sched_yield(); } -IceUtil::Thread::Thread() +IceUtil::Thread::Thread() : + _started(false), + _running(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" { static void* startHook(void* arg) { + // + // Ensure that the thread doesn't go away until run() has + // completed. + // + IceUtil::ThreadPtr thread; try { IceUtil::Thread* rawThread = static_cast<IceUtil::Thread*>(arg); - // - // Ensure that the thread doesn't go away until run() has - // completed. - // - IceUtil::ThreadPtr thread = rawThread; + thread = rawThread; // // See the comment in IceUtil::Thread::start() for details. @@ -494,6 +383,8 @@ startHook(void* arg) { fprintf(stderr, "IceUtil::Thread::run(): uncaught exception\n"); } + thread->_done(); + return 0; } } @@ -539,7 +430,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(); @@ -548,7 +439,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(); @@ -557,8 +448,9 @@ IceUtil::Thread::start(size_t stackSize) } _started = true; + _running = true; - return ThreadControl(_id); + return ThreadControl(_thread); } IceUtil::ThreadControl @@ -569,31 +461,13 @@ 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 @@ -605,27 +479,21 @@ IceUtil::Thread::operator!=(const Thread& rhs) const bool IceUtil::Thread::operator<(const Thread& rhs) const { - // - // Get rhs ID. - // - ThreadId id = rhs.id(); + return this < &rhs; +} - // - // Check that this thread was started. - // +bool +IceUtil::Thread::isAlive() const +{ IceUtil::Mutex::Lock lock(_stateMutex); - if(!_started) - { - throw ThreadNotStartedException(__FILE__, __LINE__); - } + return _running; +} - // - // 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; +void +IceUtil::Thread::_done() +{ + IceUtil::Mutex::Lock lock(_stateMutex); + _running = false; } #endif diff --git a/cppe/test/IceE/thread/AliveTest.cpp b/cppe/test/IceE/thread/AliveTest.cpp index 4a7773b3847..0815c5fba04 100644 --- a/cppe/test/IceE/thread/AliveTest.cpp +++ b/cppe/test/IceE/thread/AliveTest.cpp @@ -92,8 +92,8 @@ AliveTest::run() AliveTestThreadPtr t = new AliveTestThread(childCreated, parentReady); IceUtil::ThreadControl c = t->start(); childCreated.waitForSignal(); - test(c.isAlive()); + test(t->isAlive()); parentReady.signal(); c.join(); - test(!c.isAlive()); + test(!t->isAlive()); } |