summaryrefslogtreecommitdiff
path: root/cppe/src/IceE/Thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cppe/src/IceE/Thread.cpp')
-rw-r--r--cppe/src/IceE/Thread.cpp356
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, &param);
-#ifdef __APPLE__
- if (ret == 0)
- {
- ret = pthread_setschedparam(_id, policy, &param);
- }
-#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