aboutsummaryrefslogtreecommitdiff
path: root/dep/src/zthread/win32
diff options
context:
space:
mode:
Diffstat (limited to 'dep/src/zthread/win32')
-rw-r--r--dep/src/zthread/win32/AtomicCount.cxx60
-rw-r--r--dep/src/zthread/win32/AtomicFastLock.h122
-rw-r--r--dep/src/zthread/win32/AtomicFastRecursiveLock.h158
-rw-r--r--dep/src/zthread/win32/FastLock.h146
-rw-r--r--dep/src/zthread/win32/FastRecursiveLock.h109
-rw-r--r--dep/src/zthread/win32/Monitor.cxx242
-rw-r--r--dep/src/zthread/win32/Monitor.h153
-rw-r--r--dep/src/zthread/win32/PerformanceCounterStrategy.h108
-rw-r--r--dep/src/zthread/win32/TSS.h108
-rw-r--r--dep/src/zthread/win32/ThreadOps.cxx197
-rw-r--r--dep/src/zthread/win32/ThreadOps.h152
11 files changed, 1555 insertions, 0 deletions
diff --git a/dep/src/zthread/win32/AtomicCount.cxx b/dep/src/zthread/win32/AtomicCount.cxx
new file mode 100644
index 00000000000..84cbf8c3ddc
--- /dev/null
+++ b/dep/src/zthread/win32/AtomicCount.cxx
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTATOMICCOUNTIMPL_H__
+#define __ZTATOMICCOUNTIMPL_H__
+
+#include <windows.h>
+#include <assert.h>
+
+namespace ZThread {
+
+
+AtomicCount::AtomicCount() {
+
+ _value = reinterpret_cast<void*>(new LONG(0));
+
+}
+
+AtomicCount::~AtomicCount() {
+
+ assert(*reinterpret_cast<LPLONG>(_value) == 0);
+ delete reinterpret_cast<LPLONG>(_value);
+
+}
+
+void AtomicCount::increment() {
+
+ ::InterlockedIncrement(reinterpret_cast<LPLONG>(_value));
+
+}
+
+bool AtomicCount::decrement() {
+
+ LONG v = ::InterlockedDecrement(reinterpret_cast<LPLONG>(_value));
+ return static_cast<unsigned long>(v) == 0;
+
+}
+
+};
+
+#endif // __ZTATOMICCOUNTIMPL_H__
diff --git a/dep/src/zthread/win32/AtomicFastLock.h b/dep/src/zthread/win32/AtomicFastLock.h
new file mode 100644
index 00000000000..a714c03789f
--- /dev/null
+++ b/dep/src/zthread/win32/AtomicFastLock.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTFASTLOCK_H__
+#define __ZTFASTLOCK_H__
+
+#include "zthread/NonCopyable.h"
+#include <windows.h>
+#include <assert.h>
+
+namespace ZThread {
+
+
+/**
+ * @class FastLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:32:20-0400>
+ * @version 2.1.6
+ *
+ * This is the smallest and fastest synchronization object in the library.
+ * It is an implementation of fast mutex, an all or nothing exclusive
+ * lock. It should be used only where you need speed and are willing
+ * to sacrifice all the state & safety checking provided by the framework
+ * for speed.
+ *
+ * The current Platform SDK defines:
+ *
+ * LONG InterlockedExchange(LPLONG, LONG)
+ * LONG InterlockedCompareExchange(LPLONG, LONG, LONG, LONG)
+ *
+ * If your compiler complains about LPLONG not being implicitly casted to
+ * a PVOID, then you should get the SDK update from microsoft or use the
+ * WIN9X implementation of this class.
+ *
+ * ----
+ * Because Windows 95 and earlier can run on processors prior to the 486, they
+ * don't all support the CMPXCHG function, and so Windows 95 an earlier dont support
+ * InterlockedCompareExchange. For this, you should use the win9x implementation
+ * of this class
+ */
+class FastLock : private NonCopyable {
+
+#pragma pack(push, 8)
+ LONG volatile _lock;
+#pragma pack(pop)
+
+ public:
+
+ /**
+ * Create a new FastLock
+ */
+ inline FastLock() : _lock(0) { }
+
+
+ /**
+ * Destroy FastLock
+ */
+ inline ~FastLock() { assert(_lock == 0); }
+
+ /**
+ * Lock the fast Lock, no error check.
+ *
+ * @exception None
+ */
+ inline void acquire() {
+
+ while (::InterlockedCompareExchange(const_cast<LPLONG>(&_lock), 1, 0) != 0)
+ ::Sleep(0);
+
+ }
+
+
+ /**
+ * Release the fast Lock, no error check.
+ *
+ * @exception None
+ */
+ inline void release() {
+
+ ::InterlockedExchange(const_cast<LPLONG>(&_lock), (LONG)0);
+
+ }
+
+ /**
+ * Try to acquire an exclusive lock. No safety or state checks are performed.
+ * This function returns immediately regardless of the value of the timeout
+ *
+ * @param timeout Unused
+ * @return bool
+ * @exception Synchronization_Exception - not thrown
+ */
+ inline bool tryAcquire(unsigned long timeout=0) {
+
+ return ::InterlockedCompareExchange(const_cast<LPLONG>(&_lock), 1, 0) == 0;
+
+ }
+
+}; /* FastLock */
+
+
+};
+#endif
diff --git a/dep/src/zthread/win32/AtomicFastRecursiveLock.h b/dep/src/zthread/win32/AtomicFastRecursiveLock.h
new file mode 100644
index 00000000000..c6a61b03b5d
--- /dev/null
+++ b/dep/src/zthread/win32/AtomicFastRecursiveLock.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTFASTRECURSIVELOCK_H__
+#define __ZTFASTRECURSIVELOCK_H__
+
+#include "zthread/NonCopyable.h"
+#include <windows.h>
+#include <assert.h>
+
+namespace ZThread {
+
+
+/**
+ * @class FastRecursiveLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:32:34-0400>
+ * @version 2.1.6
+ *
+ * This is the smaller and faster implementation of a RecursiveLock.
+ * A single thread can acquire the mutex any number of times, but it
+ * must perform a release for each acquire(). Other threads are blocked
+ * until a thread has released all of its locks on the mutex.
+ *
+ * This particular implementation performs fewer safety checks. Like
+ * the FastLock implementation, any waiting caused by an acquire() request
+ * is not interruptable. This is so that the mutex can have the fastest
+ * response time for a time critical application while still having a good
+ * degree of reliability.
+ *
+ * TryEnterCriticalSection() does not work at all on some systems, so its
+ * not used.
+ *
+ *
+ * The current Platform SDK defines:
+ *
+ * LONG InterlockedExchange(LPLONG, LONG)
+ * LONG InterlockedCompareExchange(LPLONG, LONG, LONG, LONG)
+ *
+ * If your compiler complains about LPLONG not being implicitly casted to
+ * a PVOID, then you should get the SDK update from microsoft or use the
+ * WIN9X implementation of this class.
+ *
+ * ----
+ * Because Windows 95 and earlier can run on processors prior to the 486, they
+ * don't all support the CMPXCHG function, and so Windows 95 an earlier dont support
+ * InterlockedCompareExchange. If you define ZT_WIN9X, you'll get a version of the
+ * FastLock that uses the XCHG instruction
+ */
+class FastRecursiveLock : private NonCopyable {
+
+// Add def for mingw32 or other non-ms compiler to align on 64-bit
+// boundary
+#pragma pack(push, 8)
+ LONG volatile _lock;
+#pragma pack(pop)
+ LONG _count;
+
+ public:
+
+ /**
+ * Create a new FastRecursiveLock
+ */
+ inline FastRecursiveLock() : _lock(0), _count(0) { }
+
+
+ /**
+ * Destroy FastLock
+ */
+ inline ~FastRecursiveLock() {
+ assert(_lock == 0);
+ }
+
+ /**
+ * Lock the fast Lock, no error check.
+ *
+ * @exception None
+ */
+ inline void acquire() {
+
+ DWORD id = ::GetCurrentThreadId();
+
+ // Take ownership if the lock is free or owned by the calling thread
+ do {
+
+ DWORD owner = (DWORD)::InterlockedCompareExchange(const_cast<LPLONG>(&_lock), id, 0);
+ if(owner == 0 || owner == id)
+ break;
+
+ ::Sleep(0);
+
+ } while(1);
+
+ _count++;
+
+ }
+
+
+ /**
+ * Release the fast Lock, no error check.
+ *
+ * @exception None
+ */
+ inline void release() {
+
+ if(--_count == 0)
+ ::InterlockedExchange(const_cast<LPLONG>(&_lock), 0);
+
+ }
+
+ /**
+ * Try to acquire an exclusive lock. No safety or state checks are performed.
+ * This function returns immediately regardless of the value of the timeout
+ *
+ * @param timeout Unused
+ * @return bool
+ * @exception Synchronization_Exception - not thrown
+ */
+ inline bool tryAcquire(unsigned long timeout=0) {
+
+ DWORD id = ::GetCurrentThreadId();
+ DWORD owner = (DWORD)::InterlockedCompareExchange(const_cast<LPLONG>(&_lock), id, 0);
+
+ if(owner == 0 || owner == id) {
+ _count++;
+ return true;
+ }
+
+ return false;
+
+ }
+
+
+}; /* FastRecursiveLock */
+
+
+};
+#endif
diff --git a/dep/src/zthread/win32/FastLock.h b/dep/src/zthread/win32/FastLock.h
new file mode 100644
index 00000000000..2e9fe829af6
--- /dev/null
+++ b/dep/src/zthread/win32/FastLock.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTFASTLOCK_H__
+#define __ZTFASTLOCK_H__
+
+#include "zthread/Exceptions.h"
+#include "zthread/NonCopyable.h"
+#include "../ThreadOps.h"
+#include <windows.h>
+#include <assert.h>
+
+namespace ZThread {
+
+ /**
+ * @class FastLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:32:44-0400>
+ * @version 2.2.11
+ *
+ * This FastLock implementation is based on a Win32 Mutex
+ * object. This will perform better under high contention,
+ * but will not be as fast as the spin lock under reasonable
+ * circumstances.
+ */
+ class FastLock : private NonCopyable {
+
+ HANDLE _hMutex;
+#ifndef NDEBUG
+ volatile bool _locked;
+#endif
+
+ public:
+
+ /**
+ * Create a new FastLock
+ */
+ FastLock() {
+
+#ifndef NDEBUG
+ _locked = false;
+#endif
+
+ _hMutex = ::CreateMutex(0, 0, 0);
+ assert(_hMutex != NULL);
+ if(_hMutex == NULL)
+ throw Initialization_Exception();
+
+ }
+
+
+ ~FastLock() {
+ ::CloseHandle(_hMutex);
+ }
+
+ void acquire() {
+
+ if(::WaitForSingleObject(_hMutex, INFINITE) != WAIT_OBJECT_0) {
+ assert(0);
+ throw Synchronization_Exception();
+ }
+
+#ifndef NDEBUG
+
+ // Simulate deadlock to provide consistent behavior. This
+ // will help avoid errors when porting. Avoiding situations
+ // where a FastMutex mistakenly behaves as a recursive lock.
+
+ while(_locked)
+ ThreadOps::yield();
+
+ _locked = true;
+
+#endif
+
+ }
+
+ void release() {
+
+#ifndef NDEBUG
+ _locked = false;
+#endif
+
+ if(::ReleaseMutex(_hMutex) == 0) {
+ assert(0);
+ throw Synchronization_Exception();
+ }
+
+ }
+
+
+ bool tryAcquire(unsigned long timeout = 0) {
+
+ switch(::WaitForSingleObject(_hMutex, timeout)) {
+ case WAIT_OBJECT_0:
+
+#ifndef NDEBUG
+
+ // Simulate deadlock to provide consistent behavior. This
+ // will help avoid errors when porting. Avoiding situations
+ // where a FastMutex mistakenly behaves as a recursive lock.
+
+ while(_locked)
+ ThreadOps::yield();
+
+ _locked = true;
+
+#endif
+
+ return true;
+ case WAIT_TIMEOUT:
+ return false;
+ default:
+ break;
+ }
+
+ assert(0);
+ throw Synchronization_Exception();
+
+ }
+
+ };
+
+} // namespace ZThread
+
+#endif
diff --git a/dep/src/zthread/win32/FastRecursiveLock.h b/dep/src/zthread/win32/FastRecursiveLock.h
new file mode 100644
index 00000000000..e1a6e7cd692
--- /dev/null
+++ b/dep/src/zthread/win32/FastRecursiveLock.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTFASTRECURSIVELOCK_H__
+#define __ZTFASTRECURSIVELOCK_H__
+
+#include "zthread/Exceptions.h"
+#include "zthread/NonCopyable.h"
+#include <windows.h>
+#include <assert.h>
+
+namespace ZThread {
+
+
+/**
+ * @class FastRecursiveLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:32:56-0400>
+ * @version 2.2.11
+ *
+ * This FastRecursiveLock implementation is based on a Win32 Mutex
+ * object. This will perform better under high contention,
+ * but will not be as fast as the spin lock under reasonable
+ * circumstances.
+ */
+class FastRecursiveLock : private NonCopyable {
+
+ HANDLE _hMutex;
+ volatile unsigned int _count;
+
+ public:
+
+ /**
+ * Create a new FastRecursiveLock
+ */
+ FastRecursiveLock() : _count(0) {
+
+ _hMutex = ::CreateMutex(0, 0, 0);
+ assert(_hMutex != NULL);
+ if(_hMutex == NULL)
+ throw Initialization_Exception();
+
+ }
+
+
+ ~FastRecursiveLock() {
+ ::CloseHandle(_hMutex);
+ }
+
+
+ void acquire() {
+
+ if(::WaitForSingleObject(_hMutex, INFINITE) != WAIT_OBJECT_0) {
+ assert(0);
+ throw Synchronization_Exception();
+ }
+
+ }
+
+ void release() {
+
+ if(::ReleaseMutex(_hMutex) == 0) {
+ assert(0);
+ throw Synchronization_Exception();
+ }
+
+ }
+
+ bool tryAcquire(unsigned long) {
+
+ switch(::WaitForSingleObject(_hMutex, 0)) {
+ case WAIT_OBJECT_0:
+ return true;
+ case WAIT_TIMEOUT:
+ return false;
+ default:
+ break;
+ }
+
+ assert(0);
+ throw Synchronization_Exception();
+
+ }
+
+}; /* FastRecursiveLock */
+
+} // namespace ZThread
+
+#endif
diff --git a/dep/src/zthread/win32/Monitor.cxx b/dep/src/zthread/win32/Monitor.cxx
new file mode 100644
index 00000000000..6e69487c054
--- /dev/null
+++ b/dep/src/zthread/win32/Monitor.cxx
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "Monitor.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+using namespace ZThread;
+
+Monitor::Monitor() : _owner(0), _waiting(false) {
+
+ _handle = ::CreateEvent(0, TRUE, FALSE, 0);
+ if(_handle == NULL) {
+ assert(0);
+ }
+
+}
+
+Monitor::~Monitor() {
+
+ assert(!_waiting);
+
+ ::CloseHandle(_handle);
+
+}
+
+Monitor::STATE Monitor::wait(unsigned long ms) {
+
+ // Update the owner on first use. The owner will not change, each
+ // thread waits only on a single Monitor and a Monitor is never
+ // shared
+ if(_owner == 0)
+ _owner = ::GetCurrentThreadId();
+
+ STATE state; //(INVALID);
+
+ // Serialize access to the state of the Monitor
+ // and test the state to determine if a wait is needed.
+ _waitLock.acquire();
+
+ if(pending(ANYTHING)) {
+
+ // Return without waiting when possible
+ state = next();
+
+ _waitLock.release();
+ return state;
+
+ }
+ // Unlock the external lock if a wait() is probably needed.
+ // Access to the state is still serial.
+ _lock.release();
+
+ // Wait for a transition in the state that is of interest, this
+ // allows waits to exclude certain flags (e.g. INTERRUPTED)
+ // for a single wait() w/o actually discarding those flags -
+ // they will remain set until a wait interested in those flags
+ // occurs.
+ // if(!currentState(interest)) {
+
+ // Wait, ignoring signals
+ _waiting = true;
+
+ // Block until the event is set.
+ _waitLock.release();
+
+ // The event is manual reset so this lack of atmoicity will not
+ // be an issue
+
+ DWORD dwResult =
+ ::WaitForSingleObject(_handle, ((ms == 0) ? INFINITE : (DWORD)ms));
+
+ // Reacquire serialized access to the state
+ _waitLock.acquire();
+
+ // Awaken only when the event is set or the timeout expired
+ assert(dwResult == WAIT_OBJECT_0 || dwResult == WAIT_TIMEOUT);
+
+ if(dwResult == WAIT_TIMEOUT)
+ push(TIMEDOUT);
+
+ // Get the next available STATE
+ state = next();
+ _waiting = false;
+
+ ::ResetEvent(_handle);
+
+ // Acquire the internal lock & release the external lock
+ _waitLock.release();
+
+ // Reaquire the external lock, keep from deadlocking threads calling
+ // notify(), interrupt(), etc.
+ _lock.acquire();
+
+ return state;
+
+}
+
+
+bool Monitor::interrupt() {
+
+ // Serialize access to the state
+ _waitLock.acquire();
+
+ bool wasInterruptable = !pending(INTERRUPTED);
+ bool hadWaiter = _waiting;
+
+ if(wasInterruptable) {
+
+ // Update the state & wake the waiter if there is one
+ push(INTERRUPTED);
+
+ wasInterruptable = false;
+
+ if(hadWaiter && !masked(Monitor::INTERRUPTED)) {
+
+ // Blocked on a synchronization object
+ if(::SetEvent(_handle) == FALSE) {
+ assert(0);
+ }
+
+ } else
+ wasInterruptable = !(_owner == ::GetCurrentThreadId());
+
+ }
+
+ _waitLock.release();
+
+ // Only returns true when an interrupted thread is not currently blocked
+ return wasInterruptable;
+
+}
+
+bool Monitor::isInterrupted() {
+
+ // Serialize access to the state
+ _waitLock.acquire();
+
+ bool wasInterrupted = pending(INTERRUPTED);
+ clear(INTERRUPTED);
+
+ _waitLock.release();
+
+ return wasInterrupted;
+
+}
+
+
+bool Monitor::notify() {
+
+ // Serialize access to the state
+ _waitLock.acquire();
+
+ bool wasNotifyable = !pending(INTERRUPTED);
+
+ if(wasNotifyable) {
+
+ // Set the flag and wake the waiter if there
+ // is one
+ push(SIGNALED);
+
+ // If there is a waiter then send the signal.
+ if(_waiting)
+ if(::SetEvent(_handle) == FALSE) {
+ assert(0);
+ }
+
+ }
+
+ _waitLock.release();
+
+ return wasNotifyable;
+
+}
+
+
+bool Monitor::cancel() {
+
+ // Serialize access to the state
+ _waitLock.acquire();
+
+ bool wasInterrupted = !pending(INTERRUPTED);
+ bool hadWaiter = _waiting;
+
+ push(CANCELED);
+
+ if(wasInterrupted) {
+
+ // Update the state & wake the waiter if there is one
+ push(INTERRUPTED);
+
+ // If there is a waiter then send the signal.
+ if(hadWaiter && !masked(Monitor::INTERRUPTED))
+ if(::SetEvent(_handle) == FALSE) {
+ assert(0);
+ }
+
+ }
+
+ _waitLock.release();
+
+ return wasInterrupted;
+
+}
+
+bool Monitor::isCanceled() {
+
+ // Serialize access to the state
+ _waitLock.acquire();
+
+ bool wasCanceled = examine(CANCELED);
+
+ if(_owner == ::GetCurrentThreadId())
+ clear(INTERRUPTED);
+
+ _waitLock.release();
+
+ return wasCanceled;
+
+}
+
diff --git a/dep/src/zthread/win32/Monitor.h b/dep/src/zthread/win32/Monitor.h
new file mode 100644
index 00000000000..7073343b7f8
--- /dev/null
+++ b/dep/src/zthread/win32/Monitor.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTMONITOR_H__
+#define __ZTMONITOR_H__
+
+#include "../Status.h"
+#include "../FastLock.h"
+
+namespace ZThread {
+
+/**
+ * @class Monitor
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:33:10-0400>
+ * @version 2.2.11
+ */
+class Monitor : public Status, private NonCopyable {
+
+ //! Serialize access to external objects
+ FastLock _lock;
+
+ //! Event used to block thread
+ HANDLE _handle;
+
+ //! Serialize access to the internal state of the monitor
+ FastLock _waitLock;
+
+ //! Owning thread
+ DWORD _owner;
+
+ //! Waiting flag, to avoid uneccessary signals
+ volatile bool _waiting;
+
+ //! State of the monitor
+ volatile int _state;
+
+ public:
+
+ //! Create a new monitor.
+ Monitor();
+
+ //! Destroy the monitor.
+ ~Monitor();
+
+ //! Acquire the external lock for this monitor.
+ inline void acquire() {
+ _lock.acquire();
+ }
+
+ //! Try to acquire the external lock for this monitor.
+ inline bool tryAcquire() {
+ return _lock.tryAcquire();
+ }
+
+ //! Release the external lock for this monitor.
+ inline void release() {
+ _lock.release();
+ }
+
+ /**
+ * Wait for a state change and atomically unlock the external lock.
+ * Blocks for an indefinent amount of time.
+ *
+ * @return INTERRUPTED if the wait was ended by a interrupt()
+ * or SIGNALED if the wait was ended by a notify()
+ *
+ * @post the external lock is always acquired before this function returns
+ */
+ inline STATE wait() {
+ return wait(0);
+ }
+
+ /**
+ * Wait for a state change and atomically unlock the external lock.
+ * May blocks for an indefinent amount of time.
+ *
+ * @param timeout - maximum time to block (milliseconds) or 0 to
+ * block indefinently
+ *
+ * @return INTERRUPTED if the wait was ended by a interrupt()
+ * or TIMEDOUT if the maximum wait time expired.
+ * or SIGNALED if the wait was ended by a notify()
+ *
+ * @post the external lock is always acquired before this function returns
+ */
+ STATE wait(unsigned long timeout);
+
+ /**
+ * Interrupt this monitor. If there is a thread blocked on this monitor object
+ * it will be signaled and released. If there is no waiter, a flag is set and
+ * the next attempt to wait() will return INTERRUPTED w/o blocking.
+ *
+ * @return false if the thread was previously INTERRUPTED.
+ */
+ bool interrupt();
+
+ /**
+ * Notify this monitor. If there is a thread blocked on this monitor object
+ * it will be signaled and released. If there is no waiter, a flag is set and
+ * the next attempt to wait() will return SIGNALED w/o blocking, if no other
+ * flag is set.
+ *
+ * @return false if the thread was previously INTERRUPTED.
+ */
+ bool notify();
+
+ /**
+ * Check the state of this monitor, clearing the INTERRUPTED status if set.
+ *
+ * @return bool true if the monitor was INTERRUPTED.
+ * @post INTERRUPTED flag cleared if the calling thread owns the monitor.
+ */
+ bool isInterrupted();
+
+ /**
+ * Mark the Status CANCELED, and INTERRUPT the montor.
+ *
+ * @see interrupt()
+ */
+ bool cancel();
+
+ /**
+ * Test the CANCELED Status, clearing the INTERRUPTED status if set.
+ *
+ * @return bool
+ */
+ bool isCanceled();
+
+};
+
+};
+
+#endif
diff --git a/dep/src/zthread/win32/PerformanceCounterStrategy.h b/dep/src/zthread/win32/PerformanceCounterStrategy.h
new file mode 100644
index 00000000000..95b526830b3
--- /dev/null
+++ b/dep/src/zthread/win32/PerformanceCounterStrategy.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTTIMESTRATEGY_H__
+#define __ZTTIMESTRATEGY_H__
+
+#include <assert.h>
+#include <windows.h>
+
+namespace ZThread {
+
+/**
+ * @class PerformanceCounterStrategy
+ *
+ * Implement a strategy for time operatons based on
+ * Windows QueryPerformanceXXX() functions.
+ * This only (erroneously) considers the lower 32 bits.
+ */
+class TimeStrategy {
+
+ unsigned long _secs;
+ unsigned long _millis;
+
+public:
+
+ TimeStrategy() {
+
+ // Keep track of the relative time the program started
+ static LARGE_INTEGER i;
+ static BOOL valid(::QueryPerformanceCounter(&i));
+
+ assert(valid == TRUE);
+
+ LARGE_INTEGER j;
+ ::QueryPerformanceCounter(&j);
+
+ j.LowPart -= i.LowPart;
+ j.LowPart /= frequency();
+
+ // Mask off the high bits
+ _millis = (unsigned long)j.LowPart / 1000;
+ _secs = (unsigned long)j.LowPart - _millis;
+
+ }
+
+ unsigned long seconds() const {
+ return _secs;
+ }
+
+ unsigned long milliseconds() const {
+ return _millis;
+ }
+
+ unsigned long seconds(unsigned long s) {
+
+ unsigned long z = seconds();
+
+ _secs = s;
+ return z;
+
+ }
+
+ unsigned long milliseconds(unsigned long ms) {
+
+ unsigned long z = milliseconds();
+
+ _millis = ms;
+ return z;
+
+ }
+
+private:
+
+ // Get the frequency
+ static DWORD frequency() {
+
+ static LARGE_INTEGER i;
+ static BOOL valid(::QueryPerformanceFrequency(&i));
+
+ assert(valid == TRUE);
+ return i.LowPart;
+
+ }
+
+};
+
+};
+
+#endif // __ZTTIMESTRATEGY_H__
diff --git a/dep/src/zthread/win32/TSS.h b/dep/src/zthread/win32/TSS.h
new file mode 100644
index 00000000000..2400830f06a
--- /dev/null
+++ b/dep/src/zthread/win32/TSS.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTTSS_H__
+#define __ZTTSS_H__
+
+#include <windows.h>
+
+namespace ZThread {
+
+ /**
+ * @class TSS
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-27T14:18:43-0400>
+ * @version 2.3.0
+ *
+ * An abstraction for dealing with WIN32 thread specific storage (tss).
+ * Provides get/set and creation/destruction.
+ */
+ template <typename T>
+ class TSS {
+
+ DWORD _key;
+ bool _valid;
+
+ public:
+
+ /**
+ * Create a new object for accessing tss. The def
+ */
+ TSS() {
+
+ _key = ::TlsAlloc();
+ _valid = (_key != 0xFFFFFFFF);
+
+ }
+
+ /**
+ * Destroy the underlying supoprt for accessing tss with this
+ * object.
+ */
+ virtual ~TSS() {
+
+ if(_valid)
+ ::TlsFree(_key);
+
+ }
+
+ /**
+ * Get the value stored in tss.
+ *
+ * @return T
+ *
+ * @exception InvalidOp_exception thrown when the tss is not properly initialized
+ */
+ inline T get() const {
+
+ if(!_valid)
+ throw InvalidOp_Exception();
+
+ return static_cast<T>(::TlsGetValue(_key));
+
+ }
+
+ /**
+ * Store a value in tss.
+ *
+ * @param value T
+ * @return T old value
+ *
+ * @exception InvalidOp_exception thrown when the tss is not properly initialized
+ */
+ inline T set(T value) const {
+
+ T oldValue = get();
+ ::TlsSetValue(_key, value);
+
+ return oldValue;
+
+ }
+
+
+ };
+
+}
+
+#endif
+
+
diff --git a/dep/src/zthread/win32/ThreadOps.cxx b/dep/src/zthread/win32/ThreadOps.cxx
new file mode 100644
index 00000000000..6e8fb8d3b71
--- /dev/null
+++ b/dep/src/zthread/win32/ThreadOps.cxx
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "ThreadOps.h"
+#include "zthread/Runnable.h"
+#include <process.h>
+
+namespace ZThread {
+
+const ThreadOps ThreadOps::INVALID(0);
+
+/**
+ * Detect OS at runtime and attempt to locate the SwitchToThread
+ * function, which will assist in making the spin lock implementation
+ * which use ThreadOps::yield() a bit fairer.
+ */
+class YieldOps {
+
+ typedef BOOL (*Yield)(void);
+ Yield _fnYield;
+
+public:
+
+ YieldOps() : _fnYield(NULL) {
+
+ OSVERSIONINFO v;
+ v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ if(::GetVersionEx(&v) && (v.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
+
+ // Uses GetModuleHandle() so the reference count on the dll is
+ // not affected. There is a warning about race conditions involving
+ // this function being called as FreeLibrary() completes; however
+ // nearly all win32 applications load this particular and will keep it
+ // in memory until the process exits.
+ HINSTANCE hInst = ::GetModuleHandle("Kernel32.dll");
+ if(hInst != NULL)
+ _fnYield = (Yield)::GetProcAddress(hInst, "SwitchToThread");
+
+ // REMIND: possibly need to use _T() macro for these strings
+ }
+
+ }
+
+ bool operator()() {
+
+ // Attempt to yield using the best function available
+ if(!_fnYield || !_fnYield())
+ ::Sleep(0);
+
+ return true;
+
+ }
+
+};
+
+bool ThreadOps::join(ThreadOps* ops) {
+
+ assert(ops);
+ assert(ops->_tid != 0);
+ assert(ops->_hThread != NULL);
+
+ if(::WaitForSingleObjectEx(ops->_hThread, INFINITE, FALSE) != WAIT_OBJECT_0)
+ return false;
+
+ ::CloseHandle(ops->_hThread);
+ ops->_hThread = NULL;
+
+ return true;
+
+}
+
+bool ThreadOps::yield() {
+
+ static YieldOps yielder;
+
+ yielder();
+
+ return true;
+
+}
+
+bool ThreadOps::setPriority(ThreadOps* impl, Priority p) {
+
+ assert(impl);
+
+#if !defined(ZTHREAD_DISABLE_PRIORITY)
+
+ bool result;
+
+ // Convert
+ int n;
+ switch(p) {
+ case Low:
+ n = THREAD_PRIORITY_BELOW_NORMAL;
+ break;
+ case High:
+ n = THREAD_PRIORITY_ABOVE_NORMAL;
+ break;
+ case Medium:
+ default:
+ n = THREAD_PRIORITY_NORMAL;
+ }
+
+
+ result = (::SetThreadPriority(impl->_hThread, n) != THREAD_PRIORITY_ERROR_RETURN);
+ return result;
+
+#else
+
+ return true;
+
+#endif
+
+}
+
+bool ThreadOps::getPriority(ThreadOps* impl, Priority& p) {
+
+ assert(impl);
+ bool result = true;
+
+#if !defined(ZTHREAD_DISABLE_PRIORITY)
+
+ // Convert to one of the PRIORITY values
+ switch(::GetThreadPriority(impl->_hThread)) {
+ case THREAD_PRIORITY_ERROR_RETURN:
+ result = false;
+ case THREAD_PRIORITY_BELOW_NORMAL:
+ p = Low;
+ break;
+ case THREAD_PRIORITY_ABOVE_NORMAL:
+ p = High;
+ break;
+ case THREAD_PRIORITY_NORMAL:
+ default:
+ p = Medium;
+ }
+
+#endif
+
+ return result;
+
+}
+
+
+bool ThreadOps::spawn(Runnable* task) {
+
+// Start the thread.
+#if defined(HAVE_BEGINTHREADEX)
+ _hThread = (HANDLE)::_beginthreadex(0, 0, &_dispatch, task, 0, (unsigned int*)&_tid);
+#else
+ _hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&_dispatch, task, 0, (DWORD*)&_tid);
+#endif
+
+ return _hThread != NULL;
+
+}
+
+unsigned int __stdcall ThreadOps::_dispatch(void *arg) {
+
+ Runnable* task = reinterpret_cast<Runnable*>(arg);
+ assert(task);
+
+ // Run the task from the correct context
+ task->run();
+
+ // Exit the thread
+#if defined(HAVE_BEGINTHREADEX)
+ ::_endthreadex(0);
+#else
+ ExitThread(0);
+#endif
+
+ return 0;
+
+}
+
+}
diff --git a/dep/src/zthread/win32/ThreadOps.h b/dep/src/zthread/win32/ThreadOps.h
new file mode 100644
index 00000000000..4a3eeac2ed9
--- /dev/null
+++ b/dep/src/zthread/win32/ThreadOps.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2005, Eric Crahen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __ZTTHREADOPS_H__
+#define __ZTTHREADOPS_H__
+
+#include "zthread/Priority.h"
+#include <windows.h>
+#include <assert.h>
+
+namespace ZThread {
+
+class Runnable;
+
+/**
+ * @class ThreadOps
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:33:59-0400>
+ * @version 2.2.8
+ *
+ * This class is an abstraction used to perform various operations on a
+ * native WIN32 thread.
+ */
+class ThreadOps {
+
+ //! Dispatch function for native thread
+ static unsigned int __stdcall _dispatch(void*);
+
+ //! TID while the thread is executing.
+ HANDLE _hThread;
+ DWORD _tid;
+
+ ThreadOps(DWORD tid) : _tid(tid) { }
+
+ public:
+
+ const static ThreadOps INVALID;
+
+ /**
+ * Create a new ThreadOps to represent a native thread.
+ */
+ ThreadOps() : _tid(0), _hThread(NULL) {}
+
+
+ inline bool operator==(const ThreadOps& ops) const {
+ return _tid == ops._tid;
+ }
+
+
+ static ThreadOps self() {
+ return ThreadOps(::GetCurrentThreadId());
+ }
+
+ /**
+ * Update the native tid for this thread so it matches the current
+ * thread.
+ */
+ static void activate(ThreadOps* ops) {
+
+ assert(ops);
+ assert(ops->_tid == 0);
+
+ ops->_tid = ::GetCurrentThreadId();
+
+ }
+
+ /**
+ * Test if this object representative of the currently executing
+ * native thread.
+ *
+ * @return bool true if successful
+ */
+ static bool isCurrent(ThreadOps* ops) {
+
+ assert(ops);
+
+ return ops->_tid == ::GetCurrentThreadId();
+
+ }
+
+ /**
+ * Join a native thread.
+ *
+ * @return bool true if successful
+ */
+ static bool join(ThreadOps*);
+
+ /**
+ * Force the current native thread to yield, letting the scheduler
+ * give the CPU time to another thread.
+ *
+ * @return bool true if successful
+ */
+ static bool yield();
+
+ /**
+ * Set the priority for the native thread if supported by the
+ * system.
+ *
+ * @param PRIORITY requested priority
+ * @return bool false if unsuccessful
+ */
+ static bool setPriority(ThreadOps*, Priority);
+
+ /**
+ * Set the priority for the native thread if supported by the
+ * system.
+ *
+ * @param Thread::PRIORITY& current priority
+ * @return bool false if unsuccessful
+ */
+ static bool getPriority(ThreadOps*, Priority&);
+
+protected:
+
+ /**
+ * Spawn a native thread.
+ *
+ * @param ThreadImpl* parent thread
+ * @param ThreadImpl* child thread being started.
+ * @param Runnable* task being executed.
+ *
+ * @return bool true if successful
+ */
+ bool spawn(Runnable*);
+
+
+};
+
+
+}
+
+#endif