summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpp/include/IceUtil/RWRecMutex.h2
-rw-r--r--cpp/include/IceUtil/Thread.h70
-rw-r--r--cpp/src/IceUtil/RWRecMutex.cpp18
-rw-r--r--cpp/src/IceUtil/Thread.cpp328
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, &param);
+ ret = pthread_getschedparam(_thread, &policy, &param);
#ifdef __APPLE__
if (ret == 0)
{
- ret = pthread_setschedparam(_id, policy, &param);
+ ret = pthread_setschedparam(_thread, policy, &param);
}
#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