aboutsummaryrefslogtreecommitdiff
path: root/dep/src/zthread/posix
diff options
context:
space:
mode:
authorNeo2003 <none@none>2008-10-02 16:23:55 -0500
committerNeo2003 <none@none>2008-10-02 16:23:55 -0500
commit9b1c0e006f20091f28f3f468cfcab1feb51286bd (patch)
treeb5d1ba94a656e6679f8737f9ea6bed1239b73b14 /dep/src/zthread/posix
[svn] * Proper SVN structureinit
--HG-- branch : trunk
Diffstat (limited to 'dep/src/zthread/posix')
-rw-r--r--dep/src/zthread/posix/ConditionRecursiveLock.h146
-rw-r--r--dep/src/zthread/posix/FastLock.h121
-rw-r--r--dep/src/zthread/posix/FtimeStrategy.h84
-rw-r--r--dep/src/zthread/posix/GetTimeOfDayStrategy.h75
-rw-r--r--dep/src/zthread/posix/Monitor.cxx257
-rw-r--r--dep/src/zthread/posix/Monitor.h153
-rw-r--r--dep/src/zthread/posix/PriorityOps.h51
-rw-r--r--dep/src/zthread/posix/TSS.h104
-rw-r--r--dep/src/zthread/posix/ThreadOps.cxx147
-rw-r--r--dep/src/zthread/posix/ThreadOps.h154
10 files changed, 1292 insertions, 0 deletions
diff --git a/dep/src/zthread/posix/ConditionRecursiveLock.h b/dep/src/zthread/posix/ConditionRecursiveLock.h
new file mode 100644
index 00000000000..a46ed35548c
--- /dev/null
+++ b/dep/src/zthread/posix/ConditionRecursiveLock.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 __ZTFASTRECURSIVELOCK_H__
+#define __ZTFASTRECURSIVELOCK_H__
+
+#include "zthread/NonCopyable.h"
+#include <pthread.h>
+#include <errno.h>
+#include <assert.h>
+
+namespace ZThread {
+
+/**
+ * @class FastRecursiveLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:28:37-0400>
+ * @version 2.2.0
+ *
+ * This is an implementation of a FastRecursiveLock for any vannila
+ * POSIX system. It is based on a condition variable and a mutex;
+ * because of this it is important to not that its waiting properties
+ * are not the same as other mutex implementations that generally
+ * based on spin locks. Under high contention, this implementation may
+ * be preferable to a spin lock, although refactoring the design of
+ * code that puts a mutex under alot of preasure may be worth investigating.
+ */
+class FastRecursiveLock : private NonCopyable {
+
+ //! Serialize state
+ pthread_mutex_t _mtx;
+
+ //! Wait for lock
+ pthread_cond_t _cond;
+
+ //! Owner
+ pthread_t _owner;
+
+ //! Count
+ volatile unsigned int _count;
+
+public:
+
+ inline FastRecursiveLock() : _owner(0), _count(0) {
+
+ pthread_mutex_init(&_mtx, 0);
+ if(pthread_cond_init(&_cond, 0) != 0) {
+ assert(0);
+ }
+
+ }
+
+ inline ~FastRecursiveLock() {
+
+ pthread_mutex_destroy(&_mtx);
+ if(pthread_cond_destroy(&_cond) != 0) {
+ assert(0);
+ }
+
+ }
+
+ inline void acquire() {
+
+ pthread_t self = pthread_self();
+ pthread_mutex_lock(&_mtx);
+
+ // If the caller does not own the lock, wait until there is no owner
+ if(_owner != 0 && !pthread_equal(_owner, self)) {
+
+ int status = 0;
+ do { // ignore signals
+ status = pthread_cond_wait(&_cond, &_mtx);
+ } while(status == EINTR && _owner == 0);
+
+ }
+
+ _owner = self;
+ _count++;
+
+ pthread_mutex_unlock(&_mtx);
+
+ }
+
+ inline bool tryAcquire(unsigned long timeout=0) {
+
+ pthread_t self = pthread_self();
+ pthread_mutex_lock(&_mtx);
+
+ // If the caller owns the lock, or there is no owner update the count
+ bool success = (_owner == 0 || pthread_equal(_owner, self));
+ if(success) {
+
+ _owner = self;
+ _count++;
+
+ }
+
+ pthread_mutex_unlock(&_mtx);
+
+ return success;
+
+ }
+
+ inline void release() {
+
+ assert(pthread_equal(_owner, pthread_self()));
+
+ pthread_mutex_lock(&_mtx);
+ if(--_count == 0) {
+
+ _owner = 0;
+ pthread_cond_signal(&_cond);
+
+ }
+
+ pthread_mutex_unlock(&_mtx);
+
+ }
+
+
+}; /* FastRecursiveLock */
+
+
+} // namespace ZThread
+
+#endif
diff --git a/dep/src/zthread/posix/FastLock.h b/dep/src/zthread/posix/FastLock.h
new file mode 100644
index 00000000000..87faf34d4ff
--- /dev/null
+++ b/dep/src/zthread/posix/FastLock.h
@@ -0,0 +1,121 @@
+/*
+ * 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 <pthread.h>
+#include <assert.h>
+
+namespace ZThread {
+
+/**
+ * @class FastLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:28:07-0400>
+ * @version 2.2.8
+ *
+ * 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.
+ */
+class FastLock : private NonCopyable {
+
+ pthread_mutex_t _mtx;
+
+ public:
+
+ /**
+ * Create a new FastLock. No safety or state checks are performed.
+ *
+ * @exception Initialization_Exception - not thrown
+ */
+ inline FastLock() {
+
+ if(pthread_mutex_init(&_mtx, 0) != 0)
+ throw Initialization_Exception();
+
+ }
+
+ /**
+ * Destroy a FastLock. No safety or state checks are performed.
+ */
+ inline ~FastLock() {
+
+ if(pthread_mutex_destroy(&_mtx) != 0) {
+ assert(0);
+ }
+
+ }
+
+ /**
+ * Acquire an exclusive lock. No safety or state checks are performed.
+ *
+ * @exception Synchronization_Exception - not thrown
+ */
+ inline void acquire() {
+
+ if(pthread_mutex_lock(&_mtx) != 0)
+ throw Synchronization_Exception();
+
+ }
+
+ /**
+ * 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 (pthread_mutex_trylock(&_mtx) == 0);
+
+ }
+
+ /**
+ * Release an exclusive lock. No safety or state checks are performed.
+ * The caller should have already acquired the lock, and release it
+ * only once.
+ *
+ * @exception Synchronization_Exception - not thrown
+ */
+ inline void release() {
+
+ if(pthread_mutex_unlock(&_mtx) != 0)
+ throw Synchronization_Exception();
+
+ }
+
+
+}; /* FastLock */
+
+
+};
+
+#endif
diff --git a/dep/src/zthread/posix/FtimeStrategy.h b/dep/src/zthread/posix/FtimeStrategy.h
new file mode 100644
index 00000000000..5e703970c5c
--- /dev/null
+++ b/dep/src/zthread/posix/FtimeStrategy.h
@@ -0,0 +1,84 @@
+/*
+ * 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 <sys/timeb.h>
+
+#if defined(_MSC_VER)
+
+# include <time.h>
+
+# define timeb _timeb
+# define ftime _ftime
+
+#endif
+
+namespace ZThread {
+
+/**
+ * @class TimeStrategy
+ *
+ * Implement a strategy for time operatons based on ftime
+ */
+class TimeStrategy {
+
+ struct timeb _value;
+
+public:
+
+ TimeStrategy() {
+ ftime(&_value);
+ }
+
+ inline unsigned long seconds() const {
+ return (unsigned long)_value.time;
+ }
+
+ inline unsigned long milliseconds() const {
+ return _value.millitm;
+ }
+
+ unsigned long seconds(unsigned long s) {
+
+ unsigned long z = seconds();
+ _value.time = s;
+
+ return z;
+
+ }
+
+ unsigned long milliseconds(unsigned long ms) {
+
+ unsigned long z = milliseconds();
+ _value.millitm = (unsigned short)ms;
+
+ return z;
+
+ }
+
+};
+
+};
+
+#endif // __ZTTIMESTRATEGY_H__
diff --git a/dep/src/zthread/posix/GetTimeOfDayStrategy.h b/dep/src/zthread/posix/GetTimeOfDayStrategy.h
new file mode 100644
index 00000000000..8588807f4f7
--- /dev/null
+++ b/dep/src/zthread/posix/GetTimeOfDayStrategy.h
@@ -0,0 +1,75 @@
+/*
+ * 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 <sys/time.h>
+
+namespace ZThread {
+
+/**
+ * @class TimeStrategy
+ *
+ * Implement a strategy for time operatons based on gettimeofday
+ */
+class TimeStrategy {
+
+ struct timeval _value;
+
+public:
+
+ TimeStrategy() {
+ gettimeofday(&_value, 0);
+ }
+
+ inline unsigned long seconds() const {
+ return _value.tv_sec;
+ }
+
+ inline unsigned long milliseconds() const {
+ return _value.tv_usec/1000;
+ }
+
+ unsigned long seconds(unsigned long s) {
+
+ unsigned long z = seconds();
+ _value.tv_sec = s;
+
+ return z;
+
+ }
+
+ unsigned long milliseconds(unsigned long ms) {
+
+ unsigned long z = milliseconds();
+ _value.tv_usec = ms*1000;
+
+ return z;
+
+ }
+
+};
+
+};
+
+#endif // __ZTTIMESTRATEGY_H__
diff --git a/dep/src/zthread/posix/Monitor.cxx b/dep/src/zthread/posix/Monitor.cxx
new file mode 100644
index 00000000000..bb157dae0dc
--- /dev/null
+++ b/dep/src/zthread/posix/Monitor.cxx
@@ -0,0 +1,257 @@
+/*
+ * 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"
+#include "../Debug.h"
+#include "../TimeStrategy.h"
+
+#include <errno.h>
+#include <assert.h>
+#include <signal.h>
+
+namespace ZThread {
+
+Monitor::Monitor() : _owner(0), _waiting(false) {
+
+ pthread_cond_init(&_waitCond, 0);
+ pthread_mutex_init(&_waitLock, 0);
+
+}
+
+Monitor::~Monitor() {
+
+ assert(!_waiting);
+
+ pthread_cond_destroy(&_waitCond);
+ pthread_mutex_destroy(&_waitLock);
+
+}
+
+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 = pthread_self();
+
+ STATE state(INVALID);
+
+ // Serialize access to the state of the Monitor
+ // and test the state to determine if a wait is needed.
+
+ pthread_mutex_lock(&_waitLock);
+
+ if(pending(ANYTHING)) {
+
+ // Return without waiting when possible
+ state = next();
+
+ pthread_mutex_unlock(&_waitLock);
+ 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;
+ int status = 0;
+
+ if(ms == 0) { // Wait forever
+
+ do { // ignore signals unless the state is interesting
+ status = pthread_cond_wait(&_waitCond, &_waitLock);
+ } while(status == EINTR && !pending(ANYTHING));
+
+ // Akwaken only when a state is pending
+ assert(status == 0);
+
+ } else {
+
+ // Find the target time
+ TimeStrategy t;
+
+ ms += t.milliseconds();
+
+ unsigned long s = t.seconds() + (ms / 1000);
+ ms %= 1000;
+
+ // Convert to a timespec
+ struct ::timespec timeout;
+
+ timeout.tv_sec = s;
+ timeout.tv_nsec = ms*1000000;
+
+ // Wait ignoring signals until the state is interesting
+ do {
+
+ // When a timeout occurs, update the state to reflect that.
+ status = pthread_cond_timedwait(&_waitCond, &_waitLock, &timeout);
+
+ } while(status == EINTR && !pending(ANYTHING));
+
+ // Akwaken only when a state is pending or when the timeout expired
+ assert(status == 0 || status == ETIMEDOUT);
+
+ if(status == ETIMEDOUT)
+ push(TIMEDOUT);
+
+ }
+
+ // Get the next available STATE
+ state = next();
+ _waiting = false;
+
+ pthread_mutex_unlock(&_waitLock);
+
+ // Reaquire the external lock, keep from deadlocking threads calling
+ // notify(), interrupt(), etc.
+
+ _lock.acquire();
+
+ return state;
+
+}
+
+
+bool Monitor::interrupt() {
+
+ // Serialize access to the state
+ pthread_mutex_lock(&_waitLock);
+
+ 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))
+ pthread_cond_signal(&_waitCond);
+ else
+ wasInterruptable = !pthread_equal(_owner, pthread_self());
+
+ }
+
+ pthread_mutex_unlock(&_waitLock);
+
+ // Only returns true when an interrupted thread is not currently blocked
+ return wasInterruptable;
+
+}
+
+bool Monitor::isInterrupted() {
+
+ // Serialize access to the state
+ pthread_mutex_lock(&_waitLock);
+
+ bool wasInterrupted = pending(INTERRUPTED);
+
+ clear(INTERRUPTED);
+
+ pthread_mutex_unlock(&_waitLock);
+
+ return wasInterrupted;
+
+}
+
+bool Monitor::isCanceled() {
+
+ // Serialize access to the state
+ pthread_mutex_lock(&_waitLock);
+
+ bool wasCanceled = examine(CANCELED);
+
+ if(pthread_equal(_owner, pthread_self()))
+ clear(INTERRUPTED);
+
+ pthread_mutex_unlock(&_waitLock);
+
+ return wasCanceled;
+
+}
+
+bool Monitor::cancel() {
+
+ // Serialize access to the state
+ pthread_mutex_lock(&_waitLock);
+
+ bool wasInterrupted = !pending(INTERRUPTED);
+ bool hadWaiter = _waiting;
+
+ push(CANCELED);
+
+ if(wasInterrupted) {
+
+ // Update the state & wake the waiter if there is one
+ push(INTERRUPTED);
+
+ if(hadWaiter && !masked(Monitor::INTERRUPTED))
+ pthread_cond_signal(&_waitCond);
+
+ }
+
+ pthread_mutex_unlock(&_waitLock);
+
+ return wasInterrupted;
+
+}
+
+bool Monitor::notify() {
+
+ // Serialize access to the state
+ pthread_mutex_lock(&_waitLock);
+
+ bool wasNotifyable = !pending(INTERRUPTED);
+
+ if(wasNotifyable) {
+
+ // Set the flag and wake the waiter if there
+ // is one
+ push(SIGNALED);
+
+ if(_waiting)
+ pthread_cond_signal(&_waitCond);
+
+ }
+
+ pthread_mutex_unlock(&_waitLock);
+
+ return wasNotifyable;
+
+}
+
+} // namespace ZThread
+
diff --git a/dep/src/zthread/posix/Monitor.h b/dep/src/zthread/posix/Monitor.h
new file mode 100644
index 00000000000..945c879f421
--- /dev/null
+++ b/dep/src/zthread/posix/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-18T08:16:09-0400>
+ * @version 2.2.8
+ */
+class Monitor : public Status, private NonCopyable {
+ private:
+
+ //! Serialize access to external objects
+ FastLock _lock;
+
+ //! Condition variable used to block a thread.
+ pthread_cond_t _waitCond;
+
+ //! Serialize access to the internal state of the monitor
+ pthread_mutex_t _waitLock;
+
+ //! Owning thread
+ pthread_t _owner;
+
+ //! Waiting flag, to avoid uneccessary signals
+ volatile bool _waiting;
+
+ public:
+
+ typedef Status::STATE STATE;
+
+ //! Create a new monitor.
+ Monitor();
+
+ //! Destroy the monitor.
+ ~Monitor();
+
+ //! Acquire the lock for this monitor.
+ inline void acquire() {
+ _lock.acquire();
+ }
+
+ //! Acquire the lock for this monitor.
+ inline bool tryAcquire() {
+ return _lock.tryAcquire();
+ }
+
+ //! Release the 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/posix/PriorityOps.h b/dep/src/zthread/posix/PriorityOps.h
new file mode 100644
index 00000000000..92da66a9cff
--- /dev/null
+++ b/dep/src/zthread/posix/PriorityOps.h
@@ -0,0 +1,51 @@
+/*
+ * 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 __ZTPRIORITYOPS_H__
+#define __ZTPRIORITYOPS_H__
+
+#include "zthread/Priority.h"
+#include "../ThreadOps.h"
+
+namespace ZThread {
+
+/**
+ * @class PriorityOps
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:30:00-0400>
+ * @version 2.2.0
+ *
+ * This class is an abstraction used to perform various operations on a
+ * native POSIX thread.
+ */
+class PriorityOps {
+
+
+public:
+
+
+};
+
+
+} // namespace ZThread
+
+#endif // __ZTPRIORITYOPS_H__
diff --git a/dep/src/zthread/posix/TSS.h b/dep/src/zthread/posix/TSS.h
new file mode 100644
index 00000000000..931ff348b3d
--- /dev/null
+++ b/dep/src/zthread/posix/TSS.h
@@ -0,0 +1,104 @@
+/*
+ * 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 "zthread/NonCopyable.h"
+#include <pthread.h>
+#include <assert.h>
+
+namespace ZThread {
+
+ /**
+ * @class TSS
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-27T14:18:37-0400>
+ * @version 2.3.0
+ *
+ * An abstraction for dealing with POSIX thread specific storage (tss).
+ * Provides get/set and creation/destruction.
+ */
+ template <typename T>
+ class TSS : private NonCopyable {
+
+ pthread_key_t _key;
+
+ public:
+
+ /**
+ * Create a new object for accessing tss.
+ */
+ TSS() {
+
+ if(pthread_key_create(&_key, 0) != 0) {
+ assert(0); // Key creation failed
+ }
+
+ }
+
+ /**
+ * Destroy the underlying supoprt for accessing tss with this
+ * object.
+ */
+ ~TSS() {
+
+ pthread_key_delete(_key);
+
+ }
+
+ /**
+ * Get the value stored in tss.
+ *
+ * @return T
+ *
+ * @exception InvalidOp_exception thrown when the tss is not properly initialized
+ */
+ T get() const {
+ return reinterpret_cast<T>(pthread_getspecific(_key));
+ }
+
+
+ /**
+ * Store a value in tss.
+ *
+ * @param value T
+ * @return T old value
+ *
+ * @exception InvalidOp_exception thrown when the tss is not properly initialized
+ */
+ T set(T value) const {
+
+ T oldValue = get();
+ pthread_setspecific(_key, value);
+
+ return oldValue;
+
+ }
+
+ };
+
+}
+
+#endif
+
+
diff --git a/dep/src/zthread/posix/ThreadOps.cxx b/dep/src/zthread/posix/ThreadOps.cxx
new file mode 100644
index 00000000000..e72ef78ada3
--- /dev/null
+++ b/dep/src/zthread/posix/ThreadOps.cxx
@@ -0,0 +1,147 @@
+/*
+ * 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/Guard.h"
+#include "zthread/Runnable.h"
+#include <errno.h>
+
+#if defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+#endif
+
+namespace ZThread {
+
+const ThreadOps ThreadOps::INVALID(0);
+
+bool ThreadOps::join(ThreadOps* ops) {
+
+ assert(ops);
+ assert(ops->_tid != 0);
+
+ int err = 0;
+
+ do {
+
+ err = pthread_join(ops->_tid, NULL);
+
+ } while(err == EINTR);
+
+ return err == 0;
+
+}
+
+bool ThreadOps::yield() {
+
+ bool result = false;
+
+#if defined(HAVE_SCHED_YIELD)
+ result = sched_yield() == 0;
+#endif
+
+ return result;
+
+}
+
+bool ThreadOps::setPriority(ThreadOps* impl, Priority p) {
+
+ assert(impl);
+
+ bool result = true;
+
+#if !defined(ZTHREAD_DISABLE_PRIORITY)
+
+ struct sched_param param;
+
+ switch(p) {
+ case Low:
+ param.sched_priority = 0;
+ break;
+ case High:
+ param.sched_priority = 10;
+ break;
+ case Medium:
+ default:
+ param.sched_priority = 5;
+ }
+
+ result = pthread_setschedparam(impl->_tid, SCHED_OTHER, &param) == 0;
+
+#endif
+
+ return result;
+
+}
+
+bool ThreadOps::getPriority(ThreadOps* impl, Priority& p) {
+
+ assert(impl);
+
+ bool result = true;
+
+#if !defined(ZTHREAD_DISABLE_PRIORITY)
+
+ struct sched_param param;
+ int policy = SCHED_OTHER;
+
+ if(result = (pthread_getschedparam(impl->_tid, &policy, &param) == 0)) {
+
+ // Convert to one of the PRIORITY values
+ if(param.sched_priority < 10)
+ p = Low;
+ else if(param.sched_priority == 10)
+ p = Medium;
+ else
+ p = High;
+
+ }
+
+#endif
+
+ return result;
+
+}
+
+
+bool ThreadOps::spawn(Runnable* task) {
+ return pthread_create(&_tid, 0, _dispatch, task) == 0;
+}
+
+
+
+extern "C" void *_dispatch(void *arg) {
+
+ Runnable* task = reinterpret_cast<Runnable*>(arg);
+ assert(task);
+
+ // Run the task from the correct context
+ task->run();
+
+ // Exit the thread
+ pthread_exit((void**)0);
+ return (void*)0;
+
+}
+
+} // namespace ZThread
+
+
diff --git a/dep/src/zthread/posix/ThreadOps.h b/dep/src/zthread/posix/ThreadOps.h
new file mode 100644
index 00000000000..be754c2d659
--- /dev/null
+++ b/dep/src/zthread/posix/ThreadOps.h
@@ -0,0 +1,154 @@
+/*
+ * 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 <pthread.h>
+#include <assert.h>
+
+namespace ZThread {
+
+class Runnable;
+
+//! Dispatch function for native pthreads required extern C
+//! linkage.
+extern "C" void* _dispatch(void*);
+
+/**
+ * @class ThreadOps
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:30:25-0400>
+ * @version 2.2.8
+ *
+ * This class is an abstraction used to perform various operations on a
+ * native POSIX thread.
+ */
+class ThreadOps {
+
+ //! Keep track of the pthreads handle for the native thread
+ pthread_t _tid;
+
+ ThreadOps(pthread_t tid) : _tid(tid) { }
+
+public:
+
+ const static ThreadOps INVALID;
+
+ /**
+ * Create a new ThreadOps to manipulate a native thread.
+ */
+ ThreadOps() : _tid(0) { }
+
+
+ inline bool operator==(const ThreadOps& ops) const {
+ return pthread_equal(_tid, ops._tid);
+ }
+
+
+ static ThreadOps self() {
+ return ThreadOps(pthread_self());
+ }
+
+ /**
+ * Activating an instance of ThreadOps will map it onto the currently
+ * executing thread.
+ */
+ static void activate(ThreadOps* ops) {
+
+ assert(ops);
+ assert(ops->_tid == 0);
+
+ ops->_tid = pthread_self();
+
+ }
+
+ /**
+ * Test if this object represents the currently executing
+ * native thread.
+ *
+ * @return bool true if successful
+ */
+
+ static bool isCurrent(ThreadOps* ops) {
+
+ assert(ops);
+
+ return pthread_equal(pthread_self(), ops->_tid);
+
+ }
+
+ /**
+ * 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, false if the operation can't
+ * be supported.
+ */
+ 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 // __ZTTHREADOPS_H__