diff options
Diffstat (limited to 'cppe/src/IceE/Thread.cpp')
-rw-r--r-- | cppe/src/IceE/Thread.cpp | 356 |
1 files changed, 112 insertions, 244 deletions
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 |