aboutsummaryrefslogtreecommitdiff
path: root/dep/include/zthread
diff options
context:
space:
mode:
Diffstat (limited to 'dep/include/zthread')
-rw-r--r--dep/include/zthread/AtomicCount.h74
-rw-r--r--dep/include/zthread/Barrier.h328
-rw-r--r--dep/include/zthread/BiasedReadWriteLock.h319
-rw-r--r--dep/include/zthread/BlockingQueue.h245
-rw-r--r--dep/include/zthread/BoundedQueue.h387
-rw-r--r--dep/include/zthread/Cancelable.h86
-rw-r--r--dep/include/zthread/ClassLockable.h74
-rw-r--r--dep/include/zthread/ConcurrentExecutor.h124
-rw-r--r--dep/include/zthread/Condition.h154
-rw-r--r--dep/include/zthread/Config.h218
-rw-r--r--dep/include/zthread/CountedPtr.h289
-rw-r--r--dep/include/zthread/CountingSemaphore.h138
-rw-r--r--dep/include/zthread/Exceptions.h244
-rw-r--r--dep/include/zthread/Executor.h94
-rw-r--r--dep/include/zthread/FairReadWriteLock.h183
-rw-r--r--dep/include/zthread/FastMutex.h111
-rw-r--r--dep/include/zthread/FastRecursiveMutex.h106
-rw-r--r--dep/include/zthread/Guard.h511
-rw-r--r--dep/include/zthread/GuardedClass.h103
-rw-r--r--dep/include/zthread/Lockable.h96
-rw-r--r--dep/include/zthread/LockedQueue.h197
-rw-r--r--dep/include/zthread/MonitoredQueue.h345
-rw-r--r--dep/include/zthread/Mutex.h135
-rw-r--r--dep/include/zthread/NonCopyable.h60
-rw-r--r--dep/include/zthread/PoolExecutor.h178
-rw-r--r--dep/include/zthread/Priority.h39
-rw-r--r--dep/include/zthread/PriorityCondition.h89
-rw-r--r--dep/include/zthread/PriorityInheritanceMutex.h93
-rw-r--r--dep/include/zthread/PriorityMutex.h86
-rw-r--r--dep/include/zthread/PrioritySemaphore.h111
-rw-r--r--dep/include/zthread/Queue.h189
-rw-r--r--dep/include/zthread/ReadWriteLock.h80
-rw-r--r--dep/include/zthread/RecursiveMutex.h123
-rw-r--r--dep/include/zthread/Runnable.h58
-rw-r--r--dep/include/zthread/Semaphore.h150
-rw-r--r--dep/include/zthread/Singleton.h249
-rw-r--r--dep/include/zthread/SynchronousExecutor.h126
-rw-r--r--dep/include/zthread/Task.h78
-rw-r--r--dep/include/zthread/Thread.h381
-rw-r--r--dep/include/zthread/ThreadLocal.h382
-rw-r--r--dep/include/zthread/ThreadLocalImpl.h108
-rw-r--r--dep/include/zthread/ThreadedExecutor.h136
-rw-r--r--dep/include/zthread/Time.h225
-rw-r--r--dep/include/zthread/Waitable.h94
-rw-r--r--dep/include/zthread/ZThread.h67
45 files changed, 7663 insertions, 0 deletions
diff --git a/dep/include/zthread/AtomicCount.h b/dep/include/zthread/AtomicCount.h
new file mode 100644
index 00000000000..ea042a7feb2
--- /dev/null
+++ b/dep/include/zthread/AtomicCount.h
@@ -0,0 +1,74 @@
+/*
+ * 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 __ZTATOMICCOUNT_H__
+#define __ZTATOMICCOUNT_H__
+
+#include <cstdlib>
+
+#include "zthread/Config.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ /**
+ * @class AtomicCount
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T09:41:55-0400>
+ * @version 2.3.0
+ *
+ * This class provides an interface to a small integer whose value can be
+ * incremented or decremented atomically. It's designed to be as simple and
+ * lightweight as possible so that it can be used cheaply to create reference
+ * counts.
+ */
+ class ZTHREAD_API AtomicCount : public NonCopyable {
+
+ void* _value;
+
+ public:
+
+ //! Create a new AtomicCount, initialized to a value of 1
+ AtomicCount();
+
+ //! Destroy a new AtomicCount
+ ~AtomicCount();
+
+ //! Postfix decrement and return the current value
+ size_t operator--(int);
+
+ //! Postfix increment and return the current value
+ size_t operator++(int);
+
+ //! Prefix decrement and return the current value
+ size_t operator--();
+
+ //! Prefix increment and return the current value
+ size_t operator++();
+
+
+ }; /* AtomicCount */
+
+
+} // namespace ZThread
+
+#endif // __ZTATOMICCOUNT_H__
diff --git a/dep/include/zthread/Barrier.h b/dep/include/zthread/Barrier.h
new file mode 100644
index 00000000000..6aaafa93678
--- /dev/null
+++ b/dep/include/zthread/Barrier.h
@@ -0,0 +1,328 @@
+/*
+ * 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 __ZTBARRIER_H__
+#define __ZTBARRIER_H__
+
+#include "zthread/Condition.h"
+#include "zthread/Guard.h"
+#include "zthread/Waitable.h"
+#include "zthread/Runnable.h"
+
+namespace ZThread {
+
+ /**
+ * @class Barrier
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T09:54:01-0400>
+ * @version 2.2.1
+ *
+ * A Barrier is a Waitable object that serves as synchronization points for
+ * a set of threads. A Barrier is constructed for a fixed number (<i>N</i>) of threads.
+ * Threads attempting to wait() on a Barrier (<i> 1 - N</i>) will block until the <i>N</i>th
+ * thread arrives. The <i>N</i>th thread will awaken all the the others.
+ *
+ * An optional Runnable command may be associated with the Barrier. This will be run()
+ * when the <i>N</i>th thread arrives and Barrier is not broken.
+ *
+ * <b>Error Checking</b>
+ *
+ * A Barrier uses an all-or-nothing. All threads involved must successfully
+ * meet at Barrier. If any one of those threads leaves before all the threads
+ * have (as the result of an error or exception) then all threads present at
+ * the Barrier will throw BrokenBarrier_Exception.
+ *
+ * A broken Barrier will cause all threads attempting to wait() on it to
+ * throw a BrokenBarrier_Exception.
+ *
+ * A Barrier will remain 'broken', until it is manually reset().
+ */
+ template <unsigned int Count, class LockType>
+ class Barrier : public Waitable, private NonCopyable {
+
+ //! Broken flag
+ bool _broken;
+ //! Task flag
+ bool _haveTask;
+ //! Thread count
+ unsigned int _count;
+ //! Wait generation
+ unsigned int _generation;
+ //! Serialize access
+ LockType _lock;
+ //! Signaled when all thread arrive
+ Condition _arrived;
+ //! Command to run when all the thread arrive
+ Task _task;
+
+ public:
+
+ //! Create a Barrier
+ Barrier()
+ : _broken(false), _haveTask(false), _count(Count), _generation(0), _arrived(_lock), _task(0) { }
+
+ /**
+ * Create a Barrier that executes the given task when all threads arrive
+ * without error
+ *
+ * @param task Task to associate with this Barrier
+ */
+ Barrier(const Task& task)
+ : _broken(false), _haveTask(true), _count(Count), _generation(0), _arrived(_lock),
+ _task(task) { }
+
+ //! Destroy this Barrier
+ virtual ~Barrier() {}
+
+ /**
+ * Enter barrier and wait for the other threads to arrive. This can block for an indefinite
+ * amount of time.
+ *
+ * @exception BrokenBarrier_Exception thrown when any thread has left a wait on this
+ * Barrier as a result of an error.
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending a wait
+ * for one thread and breaking the barrier for all threads
+ *
+ * @see Waitable::wait()
+ *
+ * @post If no exception was thrown, all threads have successfully arrived
+ * @post If an exception was thrown, the barrier is broken
+ */
+ virtual void wait() {
+
+ Guard<LockType> g(_lock);
+
+ if(_broken)
+ throw BrokenBarrier_Exception();
+
+ // Break the barrier if an arriving thread is interrupted
+ if(Thread::interrupted()) {
+
+ // Release the other waiter, propagate the exception
+ _arrived.broadcast();
+ _broken = true;
+
+ throw Interrupted_Exception();
+
+ }
+
+ if(--_count == 0) {
+
+ // Wake the other threads if this was the last
+ // arriving thread
+ _arrived.broadcast();
+
+ // Try to run the associated task, if it throws then
+ // break the barrier and propagate the exception
+ try {
+
+ if(_task)
+ _task->run();
+
+ _generation++;
+
+ } catch(Synchronization_Exception&) {
+
+ _broken = true;
+ throw;
+
+ } catch(...) { assert(0); }
+
+ } else {
+
+ int myGeneration = _generation;
+
+ try {
+
+ // Wait for the other threads to arrive
+ _arrived.wait();
+
+ } catch(Interrupted_Exception&) {
+
+ // Its possible for a thread to be interrupted before the
+ // last thread arrives. If the interrupted thread hasn't
+ // resumed, then just propagate the interruption
+
+ if(myGeneration != _generation)
+ Thread().interrupt();
+
+ else _broken = true;
+
+ } catch(Synchronization_Exception&) {
+
+ // Break the barrier and propagate the exception
+ _broken = true;
+ throw;
+
+ }
+
+ // If the thread woke because it was notified by the thread
+ // that broke the barrier, throw.
+ if(_broken)
+ throw BrokenBarrier_Exception();
+
+ }
+
+ }
+
+ /**
+ * Enter barrier and wait for the other threads to arrive. This can block up to the
+ * amount of time specified with the timeout parameter. The barrier will not break
+ * if a thread leaves this function due to a timeout.
+ *
+ * @param timeout maximum amount of time, in milliseconds, to wait before
+ *
+ * @return
+ * - <em>true</em> if the set of tasks being wait for complete before
+ * <i>timeout</i> milliseconds elapse.
+ * - <em>false</em> otherwise.
+ *
+ * @exception BrokenBarrier_Exception thrown when any thread has left a wait on this
+ * Barrier as a result of an error.
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending a wait
+ * for one thread and breaking the barrier for all threads
+ *
+ * @see Waitable::wait(unsigned long timeout)
+ *
+ * @post If no exception was thrown, all threads have successfully arrived
+ * @post If an exception was thrown, the barrier is broken
+ */
+ virtual bool wait(unsigned long timeout) {
+
+ Guard<LockType> g(_lock);
+
+ if(_broken)
+ throw BrokenBarrier_Exception();
+
+ // Break the barrier if an arriving thread is interrupted
+ if(Thread::interrupted()) {
+
+ // Release the other waiter, propagate the exception
+ _arrived.broadcast();
+ _broken = true;
+
+ throw Interrupted_Exception();
+
+ }
+
+
+ if(--_count == 0) {
+
+ // Wake the other threads if this was the last
+ // arriving thread
+ _arrived.broadcast();
+
+ // Try to run the associated task, if it throws then
+ // break the barrier and propagate the exception
+ try {
+
+ if(_task)
+ _task->run();
+
+ _generation++;
+
+ } catch(Synchronization_Exception&) {
+
+ _broken = true;
+ throw;
+
+ } catch(...) { assert(0); }
+
+ } else {
+
+ int myGeneration = _generation;
+
+ try {
+
+ // Wait for the other threads to arrive
+ if(!_arrived.wait(timeout))
+ _broken = true;
+
+ } catch(Interrupted_Exception&) {
+
+ // Its possible for a thread to be interrupted before the
+ // last thread arrives. If the interrupted thread hasn't
+ // resumed, then just propagate the interruption
+
+ if(myGeneration != _generation)
+ Thread().interrupt();
+
+ else _broken = true;
+
+ } catch(Synchronization_Exception&) {
+
+ // Break the barrier and propagate the exception
+ _broken = true;
+ throw;
+
+ }
+
+ // If the thread woke because it was notified by the thread
+ // that broke the barrier, throw.
+ if(_broken)
+ throw BrokenBarrier_Exception();
+
+ }
+
+ return true;
+
+ }
+
+ /**
+ * Break the Barrier ending the wait for any threads that were waiting on
+ * the barrier.
+ *
+ * @post the Barrier is broken, all waiting threads will throw the
+ * BrokenBarrier_Exception
+ */
+ void shatter() {
+
+ Guard<LockType> g(_lock);
+
+ _broken = true;
+ _arrived.broadcast();
+
+ }
+
+ /**
+ * Reset the Barrier.
+ *
+ * @post the Barrier is no longer Broken and can be used again.
+ */
+ void reset() {
+
+ Guard<LockType> g(_lock);
+
+ _broken = false;
+ _generation++;
+ _count = Count;
+
+ }
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTBARRIER_H__
diff --git a/dep/include/zthread/BiasedReadWriteLock.h b/dep/include/zthread/BiasedReadWriteLock.h
new file mode 100644
index 00000000000..b1de74292cf
--- /dev/null
+++ b/dep/include/zthread/BiasedReadWriteLock.h
@@ -0,0 +1,319 @@
+/*
+ * 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 __ZTBIASEDREADWRITELOCK_H__
+#define __ZTBIASEDREADWRITELOCK_H__
+
+#include "zthread/ReadWriteLock.h"
+#include "zthread/Condition.h"
+#include "zthread/Guard.h"
+#include "zthread/FastMutex.h"
+
+namespace ZThread {
+
+ /**
+ * @class BiasedReadWriteLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T10:22:34-0400>
+ * @version 2.2.7
+ *
+ * A BiasedReadWriteLock has a bias toward writers. It will prefer read-write access over
+ * read-only access when many threads are contending for access to either Lockable this
+ * ReadWriteLock provides.
+ *
+ * @see ReadWriteLock
+ */
+ class BiasedReadWriteLock : public ReadWriteLock {
+
+ FastMutex _lock;
+ Condition _condRead;
+ Condition _condWrite;
+
+ volatile int _activeWriters;
+ volatile int _activeReaders;
+
+ volatile int _waitingReaders;
+ volatile int _waitingWriters;
+
+ //! @class ReadLock
+ class ReadLock : public Lockable {
+
+ BiasedReadWriteLock& _rwlock;
+
+ public:
+
+ ReadLock(BiasedReadWriteLock& rwlock) : _rwlock(rwlock) {}
+
+ virtual ~ReadLock() {}
+
+ virtual void acquire() {
+ _rwlock.beforeRead();
+ }
+
+ virtual bool tryAcquire(unsigned long timeout) {
+ return _rwlock.beforeReadAttempt(timeout);
+ }
+
+ virtual void release() {
+ _rwlock.afterRead();
+ }
+
+ };
+
+ //! @class WriteLock
+ class WriteLock : public Lockable {
+
+ BiasedReadWriteLock& _rwlock;
+
+ public:
+
+ WriteLock(BiasedReadWriteLock& rwlock) : _rwlock(rwlock) {}
+
+ virtual ~WriteLock() {}
+
+
+ virtual void acquire() {
+ _rwlock.beforeWrite();
+ }
+
+ virtual bool tryAcquire(unsigned long timeout) {
+ return _rwlock.beforeWriteAttempt(timeout);
+ }
+
+ virtual void release() {
+ _rwlock.afterWrite();
+ }
+
+ };
+
+ friend class ReadLock;
+ friend class WriteLock;
+
+ ReadLock _rlock;
+ WriteLock _wlock;
+
+ public:
+
+ /**
+ * Create a BiasedReadWriteLock
+ *
+ * @exception Initialization_Exception thrown if resources could not be
+ * allocated for this object.
+ */
+ BiasedReadWriteLock() : _condRead(_lock), _condWrite(_lock), _rlock(*this), _wlock(*this) {
+
+ _activeWriters = 0;
+ _activeReaders = 0;
+
+ _waitingReaders = 0;
+ _waitingWriters = 0;
+
+ }
+
+ //! Destroy this ReadWriteLock
+ virtual ~BiasedReadWriteLock() {}
+
+ /**
+ * @see ReadWriteLock::getReadLock()
+ */
+ virtual Lockable& getReadLock() { return _rlock; }
+
+ /**
+ * @see ReadWriteLock::getWriteLock()
+ */
+ virtual Lockable& getWriteLock() { return _wlock; }
+
+
+ protected:
+
+ void beforeRead() {
+
+ Guard<FastMutex> guard(_lock);
+
+ ++_waitingReaders;
+
+ while(!allowReader()) {
+
+ try {
+
+ // wait
+ _condRead.wait();
+
+ } catch(...) {
+
+ --_waitingReaders;
+ throw;
+
+ }
+
+ }
+
+ --_waitingReaders;
+ ++_activeReaders;
+
+ }
+
+ bool beforeReadAttempt(unsigned long timeout) {
+
+ Guard<FastMutex> guard(_lock);
+ bool result = false;
+
+ ++_waitingReaders;
+
+ while(!allowReader()) {
+
+ try {
+
+ result = _condRead.wait(timeout);
+
+ } catch(...) {
+
+ --_waitingReaders;
+ throw;
+
+ }
+
+ }
+
+ --_waitingReaders;
+ ++_activeReaders;
+
+ return result;
+ }
+
+
+ void afterRead() {
+
+ bool wakeReader = false;
+ bool wakeWriter = false;
+
+ {
+
+ Guard<FastMutex> guard(_lock);
+
+ --_activeReaders;
+
+ wakeReader = (_waitingReaders > 0);
+ wakeWriter = (_waitingWriters > 0);
+
+ }
+
+ if(wakeWriter)
+ _condWrite.signal();
+
+ else if(wakeReader)
+ _condRead.signal();
+
+ }
+
+ void beforeWrite() {
+
+ Guard<FastMutex> guard(_lock);
+
+ ++_waitingWriters;
+
+ while(!allowWriter()) {
+
+ try {
+
+ _condWrite.wait();
+
+ } catch(...) {
+
+ --_waitingWriters;
+ throw;
+
+ }
+
+ }
+
+ --_waitingWriters;
+ ++_activeWriters;
+
+ }
+
+ bool beforeWriteAttempt(unsigned long timeout) {
+
+ Guard<FastMutex> guard(_lock);
+ bool result = false;
+
+ ++_waitingWriters;
+
+ while(!allowWriter()) {
+
+ try {
+
+ result = _condWrite.wait(timeout);
+
+ } catch(...) {
+
+ --_waitingWriters;
+ throw;
+ }
+
+ }
+
+ --_waitingWriters;
+ ++_activeWriters;
+
+ return result;
+
+ }
+
+ void afterWrite() {
+
+ bool wakeReader = false;
+ bool wakeWriter = false;
+
+ {
+
+ Guard<FastMutex> guard(_lock);
+
+ --_activeWriters;
+
+ wakeReader = (_waitingReaders > 0);
+ wakeWriter = (_waitingWriters > 0);
+
+ }
+
+ if(wakeWriter)
+ _condWrite.signal();
+
+ else if(wakeReader)
+ _condRead.signal();
+
+ }
+
+ bool allowReader() {
+ return (_activeWriters == 0);
+ }
+
+ bool allowWriter() {
+ return (_activeWriters == 0 && _activeReaders == 0);
+ }
+
+ };
+
+}; // __ZTBIASEDREADWRITELOCK_H__
+
+#endif
diff --git a/dep/include/zthread/BlockingQueue.h b/dep/include/zthread/BlockingQueue.h
new file mode 100644
index 00000000000..ac17347d1cc
--- /dev/null
+++ b/dep/include/zthread/BlockingQueue.h
@@ -0,0 +1,245 @@
+/*
+ * 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 __ZTBLOCKINGQUEUE_H__
+#define __ZTBLOCKINGQUEUE_H__
+
+#include "zthread/Guard.h"
+#include "zthread/Condition.h"
+#include "zthread/Queue.h"
+
+#include <deque>
+
+namespace ZThread {
+
+ /**
+ * @class BlockingQueue
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T12:01:43-0400>
+ * @version 2.3.0
+ *
+ * Like a LockedQueue, a BlockingQueue is a Queue implementation that provides
+ * serialized access to the items added to it. It differs by causing threads
+ * accessing the next() methods to block until a value becomes available.
+ */
+ template <class T, class LockType, typename StorageType = std::deque<T> >
+ class BlockingQueue : public Queue<T>, public Lockable {
+
+ //! Serialize access
+ LockType _lock;
+
+ //! Signaled when empty
+ Condition _notEmpty;
+
+ //! Storage backing the queue
+ StorageType _queue;
+
+ //! Cancellation flag
+ volatile bool _canceled;
+
+ public:
+
+ //! Create a new BlockingQueue
+ BlockingQueue() : _notEmpty(_lock), _canceled(false) {}
+
+ //! Destroy this BlockingQueue
+ virtual ~BlockingQueue() { }
+
+ /**
+ * @see Queue::add(const T& item)
+ */
+ virtual void add(const T& item) {
+
+ Guard<LockType> g(_lock);
+
+ if(_canceled)
+ throw Cancellation_Exception();
+
+ _queue.push_back(item);
+
+ _notEmpty.signal();
+
+ }
+
+ /**
+ * @see Queue::add(const T& item, unsigned long timeout)
+ */
+ virtual bool add(T item, unsigned long timeout) {
+
+ try {
+
+ Guard<LockType> g(_lock, timeout);
+
+ if(_canceled)
+ throw Cancellation_Exception();
+
+ _queue.push_back(item);
+
+ _notEmpty.signal();
+
+ } catch(Timeout_Exception&) { return false; }
+
+ return true;
+
+ }
+
+ /**
+ * Get a value from this Queue. The calling thread may block indefinitely.
+ *
+ * @return <em>T</em> next available value
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted
+ * before a value becomes available.
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post The value returned will have been removed from the Queue.
+ *
+ * @see Queue::next()
+ */
+ virtual T next() {
+
+ Guard<LockType> g(_lock);
+
+ while(_queue.empty() && !_canceled)
+ _notEmpty.wait();
+
+ if( _queue.empty() )
+ throw Cancellation_Exception();
+
+ T item = _queue.front();
+ _queue.pop_front();
+
+ return item;
+
+ }
+
+
+ /**
+ * Get a value from this Queue. The calling thread may block indefinitely.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return <em>T</em> next available value
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Timeout_Exception thrown if the timeout expires before a value
+ * can be retrieved.
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted
+ * before a value becomes available.
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post The value returned will have been removed from the Queue.
+ *
+ * @see Queue::next(unsigned long timeout)
+ */
+ virtual T next(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+
+ while(_queue.empty() && !_canceled) {
+ if(!_notEmpty.wait(timeout))
+ throw Timeout_Exception();
+ }
+
+ if(_queue.empty() )
+ throw Cancellation_Exception();
+
+ T item = _queue.front();
+ _queue.pop_front();
+
+ return item;
+
+ }
+
+
+ /**
+ * @see Queue::cancel()
+ *
+ * @post If threads are blocked on one of the next() functions then
+ * they will be awakened with a Cancellation_Exception.
+ */
+ virtual void cancel() {
+
+ Guard<LockType> g(_lock);
+
+ _notEmpty.broadcast();
+ _canceled = true;
+
+ }
+
+ /**
+ * @see Queue::isCanceled()
+ */
+ virtual bool isCanceled() {
+
+ // Faster check since the queue will not become un-canceled
+ if(_canceled)
+ return true;
+
+ Guard<LockType> g(_lock);
+
+ return _canceled;
+
+ }
+
+ /**
+ * @see Queue::size()
+ */
+ virtual size_t size() {
+
+ Guard<LockType> g(_lock);
+ return _queue.size();
+
+ }
+
+ /**
+ * @see Queue::size(unsigned long timeout)
+ */
+ virtual size_t size(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+ return _queue.size();
+
+ }
+
+ public:
+
+ virtual void acquire() {
+ _lock.acquire();
+ }
+
+ virtual bool tryAcquire(unsigned long timeout) {
+ return _lock.tryAcquire(timeout);
+ }
+
+ virtual void release() {
+ _lock.release();
+ }
+
+ }; /* BlockingQueue */
+
+} // namespace ZThread
+
+#endif // __ZTBLOCKINGQUEUE_H__
diff --git a/dep/include/zthread/BoundedQueue.h b/dep/include/zthread/BoundedQueue.h
new file mode 100644
index 00000000000..2b3a616f1fb
--- /dev/null
+++ b/dep/include/zthread/BoundedQueue.h
@@ -0,0 +1,387 @@
+/*
+ * 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 __ZTBOUNDEDQUEUE_H__
+#define __ZTBOUNDEDQUEUE_H__
+
+#include "zthread/Condition.h"
+#include "zthread/Guard.h"
+#include "zthread/Queue.h"
+
+#include <deque>
+
+namespace ZThread {
+
+ /**
+ * @class BoundedQueue
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T13:54:04-0400>
+ * @version 2.3.0
+ *
+ * A BoundedQueue provides serialized access to a set of values. It differs from other
+ * Queues by adding a maximum capacity, giving it the following properties:
+ *
+ * - Threads calling the empty() methods will be blocked until the BoundedQueue becomes empty.
+ * - Threads calling the next() methods will be blocked until the BoundedQueue has a value to
+ * return.
+ * - Threads calling the add() methods will be blocked until the number of values in the
+ * Queue drops below the maximum capacity.
+ *
+ * @see Queue
+ */
+ template <class T, class LockType, typename StorageType=std::deque<T> >
+ class BoundedQueue : public Queue<T>, public Lockable {
+
+ //! Maximum capacity for the Queue
+ size_t _capacity;
+
+ //! Serialize access
+ LockType _lock;
+
+ //! Signaled if not full
+ Condition _notFull;
+
+ //! Signaled if not empty
+ Condition _notEmpty;
+
+ //! Signaled if empty
+ Condition _isEmpty;
+
+ //! Storage backing the queue
+ StorageType _queue;
+
+ //! Cancellation flag
+ volatile bool _canceled;
+
+ public:
+
+ /**
+ * Create a BoundedQueue with the given capacity.
+ *
+ * @param capacity maximum number of values to allow in the Queue at
+ * at any time
+ */
+ BoundedQueue(size_t capacity)
+ : _notFull(_lock), _notEmpty(_lock), _isEmpty(_lock),
+ _capacity(capacity), _canceled(false) {}
+
+ //! Destroy this Queue
+ virtual ~BoundedQueue() { }
+
+ /**
+ * Get the maximum capacity of this Queue.
+ *
+ * @return <i>size_t</i> maximum capacity
+ */
+ size_t capacity() {
+ return _capacity;
+ }
+
+ /**
+ * Add a value to this Queue.
+ *
+ * If the number of values in the queue matches the value returned by <i>capacity</i>()
+ * then the calling thread will be blocked until at least one value is removed from
+ * the Queue.
+ *
+ * @param item value to be added to the Queue
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Interrupted_Exception thrown if the thread was interrupted while waiting
+ * to add a value
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post If no exception is thrown, a copy of <i>item</i> will have been added to the Queue.
+ *
+ * @see Queue::add(const T& item)
+ */
+ virtual void add(const T& item) {
+
+ Guard<LockType> g(_lock);
+
+ // Wait for the capacity of the Queue to drop
+ while ((_queue.size() == _capacity) && !_canceled)
+ _notFull.wait();
+
+ if(_canceled)
+ throw Cancellation_Exception();
+
+ _queue.push_back(item);
+ _notEmpty.signal(); // Wake any waiters
+
+
+ }
+
+ /**
+ * Add a value to this Queue.
+ *
+ * If the number of values in the queue matches the value returned by <i>capacity</i>()
+ * then the calling thread will be blocked until at least one value is removed from
+ * the Queue.
+ *
+ * @param item value to be added to the Queue
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return
+ * - <em>true</em> if a copy of <i>item</i> can be added before <i>timeout</i>
+ * milliseconds elapse.
+ * - <em>false</em> otherwise.
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Interrupted_Exception thrown if the thread was interrupted while waiting
+ * to add a value
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post If no exception is thrown, a copy of <i>item</i> will have been added to the Queue.
+ *
+ * @see Queue::add(const T& item, unsigned long timeout)
+ */
+ virtual bool add(const T& item, unsigned long timeout) {
+
+ try {
+
+ Guard<LockType> g(_lock, timeout);
+
+ // Wait for the capacity of the Queue to drop
+ while ((_queue.size() == _capacity) && !_canceled)
+ if(!_notFull.wait(timeout))
+ return false;
+
+ if(_canceled)
+ throw Cancellation_Exception();
+
+ _queue.push_back(item);
+ _notEmpty.signal(); // Wake any waiters
+
+ } catch(Timeout_Exception&) { return false; }
+
+ return true;
+
+ }
+
+ /**
+ * Retrieve and remove a value from this Queue.
+ *
+ * If invoked when there are no values present to return then the calling thread
+ * will be blocked until a value arrives in the Queue.
+ *
+ * @return <em>T</em> next available value
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Interrupted_Exception thrown if the thread was interrupted while waiting
+ * to retrieve a value
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post The value returned will have been removed from the Queue.
+ */
+ virtual T next() {
+
+ Guard<LockType> g(_lock);
+
+ while ( _queue.empty() && !_canceled)
+ _notEmpty.wait();
+
+ if( _queue.empty()) // Queue canceled
+ throw Cancellation_Exception();
+
+ T item = _queue.front();
+ _queue.pop_front();
+
+ _notFull.signal(); // Wake any thread trying to add
+
+ if(_queue.empty()) // Wake empty waiters
+ _isEmpty.broadcast();
+
+ return item;
+
+ }
+
+ /**
+ * Retrieve and remove a value from this Queue.
+ *
+ * If invoked when there are no values present to return then the calling thread
+ * will be blocked until a value arrives in the Queue.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return <em>T</em> next available value
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Timeout_Exception thrown if the timeout expires before a value
+ * can be retrieved.
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post The value returned will have been removed from the Queue.
+ */
+ virtual T next(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+
+ // Wait for items to be added
+ while (_queue.empty() && !_canceled) {
+ if(!_notEmpty.wait(timeout))
+ throw Timeout_Exception();
+ }
+
+ if(_queue.empty()) // Queue canceled
+ throw Cancellation_Exception();
+
+ T item = _queue.front();
+ _queue.pop_front();
+
+ _notFull.signal(); // Wake add() waiters
+
+ if(_queue.empty()) // Wake empty() waiters
+ _isEmpty.broadcast();
+
+ return item;
+
+ }
+
+ /**
+ * Cancel this queue.
+ *
+ * @post Any threads blocked by an add() function will throw a Cancellation_Exception.
+ * @post Any threads blocked by a next() function will throw a Cancellation_Exception.
+ *
+ * @see Queue::cancel()
+ */
+ virtual void cancel() {
+
+ Guard<LockType> g(_lock);
+
+ _canceled = true;
+ _notEmpty.broadcast(); // Wake next() waiters
+
+ }
+
+ /**
+ * @see Queue::isCanceled()
+ */
+ virtual bool isCanceled() {
+
+ // Faster check since the Queue will not become un-canceled
+ if(_canceled)
+ return true;
+
+ Guard<LockType> g(_lock);
+
+ return _canceled;
+
+ }
+
+ /**
+ * @see Queue::size()
+ */
+ virtual size_t size() {
+
+ Guard<LockType> g(_lock);
+ return _queue.size();
+
+ }
+
+ /**
+ * @see Queue::size(unsigned long timeout)
+ */
+ virtual size_t size(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+ return _queue.size();
+
+ }
+
+ /**
+ * Test whether any values are available in this Queue.
+ *
+ * The calling thread is blocked until there are no values present
+ * in the Queue.
+ *
+ * @return
+ * - <em>true</em> if there are no values available.
+ * - <em>false</em> if there <i>are</i> values available.
+ *
+ * @see Queue::empty()
+ */
+ virtual bool empty() {
+
+ Guard<LockType> g(_lock);
+
+ while(!_queue.empty()) // Wait for an empty signal
+ _isEmpty.wait();
+
+ return true;
+
+
+ }
+
+
+ /**
+ * Test whether any values are available in this Queue.
+ *
+ * The calling thread is blocked until there are no values present
+ * in the Queue.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return
+ * - <em>true</em> if there are no values available.
+ * - <em>false</em> if there <i>are</i> values available.
+ *
+ * @exception Timeout_Exception thrown if <i>timeout</i> milliseconds
+ * expire before a value becomes available
+ *
+ * @see Queue::empty()
+ */
+ virtual bool empty(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+
+ while(!_queue.empty()) // Wait for an empty signal
+ _isEmpty.wait(timeout);
+
+ return true;
+
+ }
+
+ public:
+
+ virtual void acquire() {
+ _lock.acquire();
+ }
+
+ virtual bool tryAcquire(unsigned long timeout) {
+ return _lock.tryAcquire(timeout);
+ }
+
+ virtual void release() {
+ _lock.release();
+ }
+
+ }; /* BoundedQueue */
+
+} // namespace ZThread
+
+#endif // __ZTBOUNDEDQUEUE_H__
diff --git a/dep/include/zthread/Cancelable.h b/dep/include/zthread/Cancelable.h
new file mode 100644
index 00000000000..9151ec8dd03
--- /dev/null
+++ b/dep/include/zthread/Cancelable.h
@@ -0,0 +1,86 @@
+/*
+ * 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 __ZTCANCELABLE_H__
+#define __ZTCANCELABLE_H__
+
+#include "zthread/Exceptions.h"
+
+namespace ZThread {
+
+ /**
+ * @class Cancelable
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T09:28:46-0400>
+ * @version 2.3.0
+ *
+ * The Cancelable interface defines a common method of adding general <i>disable-and-exit</i>
+ * semantics to some object. By cancel()ing a Cancelable object, a request is
+ * made to disable that object.
+ *
+ * <b>Disabling</b>
+ *
+ * A cancel()ed object may not necessarily abort it work immediately. Often, it much more
+ * elegant for a cancel()ed object to complete handling whatever responsibilities have
+ * been assigned to it, but it will <i>not</i> take on any new responsibility.
+ *
+ * <b>Exiting</b>
+ *
+ * A cancel()ed should complete its responsibilities as soon as possible.
+ * Canceling is not only a request to stop taking on new responsibility, and to
+ * complete its current responsibility. Its also a request to complete dealing with its
+ * current responsibilities, quickly when possible.
+ */
+ class Cancelable {
+ public:
+
+ //! Destroy a Cancelable object.
+ virtual ~Cancelable() {}
+
+ /**
+ * Canceling a Cancelable object makes a request to disable that object.
+ * This entails refusing to take on any new responsibility, and completing
+ * its current responsibilities quickly.
+ *
+ * Canceling an object more than once has no effect.
+ *
+ * @post The Cancelable object will have permanently transitioned to a
+ * disabled state; it will now refuse to accept new responsibility.
+ */
+ virtual void cancel() = 0;
+
+ /**
+ * Determine if a Cancelable object has been canceled.
+ *
+ * @return
+ * - <em>true</em> if cancel() was called prior to this function.
+ * - <em>false</em> otherwise.
+ */
+ virtual bool isCanceled() = 0;
+
+ }; /* Cancelable */
+
+
+} // namespace ZThread
+
+#endif // __ZTCANCELABLE_H__
diff --git a/dep/include/zthread/ClassLockable.h b/dep/include/zthread/ClassLockable.h
new file mode 100644
index 00000000000..a10fb4932a2
--- /dev/null
+++ b/dep/include/zthread/ClassLockable.h
@@ -0,0 +1,74 @@
+/*
+ * 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 __ZTCLASSLOCKABLE_H__
+#define __ZTCLASSLOCKABLE_H__
+
+#include "zthread/CountedPtr.h"
+#include "zthread/Mutex.h"
+
+namespace ZThread {
+
+ /**
+ * @class ClassLockable
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T23:37:38-0400>
+ * @version 2.3.0
+ *
+ *
+ */
+ template <typename ClassType, class LockType = Mutex>
+ class ClassLockable : public Lockable {
+
+ static CountedPtr<LockType> _instance;
+ CountedPtr<LockType> _lock;
+
+ public:
+
+ //! Create a ClassLockable
+ ClassLockable()
+ : _lock(_instance) {}
+
+ //! acquire() the ClassLockable
+ virtual void acquire() {
+ _lock->acquire();
+ }
+
+ //! tryAcquire() the ClassLockable
+ virtual bool tryAcquire(unsigned long timeout) {
+ return _lock->tryAcquire(timeout);
+ }
+
+ //! release() the ClassLockable
+ virtual void release() {
+ _lock->release();
+ }
+
+ };
+
+ template <typename ClassType, class LockType>
+ CountedPtr<LockType> ClassLockable<ClassType, LockType>::_instance(new LockType);
+
+} // namespace ZThread
+
+#endif // __ZTCLASSLOCKABLE_H__
diff --git a/dep/include/zthread/ConcurrentExecutor.h b/dep/include/zthread/ConcurrentExecutor.h
new file mode 100644
index 00000000000..199fe306e08
--- /dev/null
+++ b/dep/include/zthread/ConcurrentExecutor.h
@@ -0,0 +1,124 @@
+/*
+ * 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 __ZTCONCURRENTEXECUTOR_H__
+#define __ZTCONCURRENTEXECUTOR_H__
+
+#include "zthread/PoolExecutor.h"
+
+namespace ZThread {
+
+ /**
+ * @class ConcurrentExecutor
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T22:36:11-0400>
+ * @version 2.3.0
+ *
+ * A ConcurrentExecutor spawns a single thread to service a series of Tasks.
+ *
+ * @see PoolExecutor.
+ */
+ class ConcurrentExecutor : public Executor {
+
+ PoolExecutor _executor;
+
+ public:
+
+ //! Create a ConcurrentExecutor
+ ConcurrentExecutor();
+
+ /**
+ * Interrupting a ConcurrentExecutor will cause the thread running the tasks to be
+ * be interrupted once during the execution of each task that has been submitted
+ * at the time this function is called.
+ *
+ * Tasks that are submitted after this function is called will
+ * not be interrupt()ed; unless this function is invoked again().
+ *
+ * @code
+ *
+ * void aFunction() {
+ *
+ * ConcurrentExecutor executor;
+ *
+ * // Submit p Tasks
+ * for(size_t n = 0; n < p; n++)
+ * executor.execute(new aRunnable);
+ *
+ * // Tasks [m, p) may be interrupted, where m is the first task that has
+ * // not completed at the time the interrupt() is invoked.
+ * executor.interrupt();
+ *
+ * // Submit (q - p) Tasks
+ * for(size_t n = p; n < q; n++)
+ * executor.execute(new Chore);
+ *
+ * // Tasks [p, q) are not interrupted
+ *
+ * }
+ *
+ * @endcode
+ */
+ virtual void interrupt();
+
+ /**
+ * Submit a Task to this Executor. This will not block the current thread
+ * for very long. The task will be enqueued internally and eventually run
+ * in the context of the single thread driving all the Tasks submitted to this
+ * Executor.
+ *
+ * @exception Cancellation_Exception thrown if this Executor has been canceled.
+ * The Task being submitted will not be executed by this Executor.
+ *
+ * @exception Synchronization_Exception thrown only in the event of an error
+ * in the implementation of the library.
+ *
+ * @see Executor::execute(const Task&)
+ */
+ virtual void execute(const Task&);
+
+ /**
+ * @see Cancelable::cancel()
+ */
+ virtual void cancel();
+
+ /**
+ * @see Cancelable::isCanceled()
+ */
+ virtual bool isCanceled();
+
+ /**
+ * @see PoolExecutor::wait()
+ */
+ virtual void wait();
+
+ /**
+ * @see PoolExecutor::wait(unsigned long timeout)
+ */
+ virtual bool wait(unsigned long timeout);
+
+ }; /* ConcurrentExecutor */
+
+} // namespace ZThread
+
+#endif // __ZTCONCURRENTEXECUTOR_H__
diff --git a/dep/include/zthread/Condition.h b/dep/include/zthread/Condition.h
new file mode 100644
index 00000000000..eba93619bfe
--- /dev/null
+++ b/dep/include/zthread/Condition.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 __ZTCONDITION_H__
+#define __ZTCONDITION_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+#include "zthread/Waitable.h"
+
+namespace ZThread {
+
+ class FifoConditionImpl;
+
+ /**
+ * @class Condition
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T14:38:59-0400>
+ * @version 2.2.1
+ *
+ * A Condition is a Waitable object used to block a thread until a particular
+ * condition is met. A Condition object is always used in conjunction with Lockable
+ * object. This object should be a FastMutex, Mutex, PriorityMutex or PriorityInheritanceMutex.
+ *
+ * Condition objects are reminiscent of POSIX condition variables in several ways but
+ * are slightly different.
+ *
+ * A Condition is <i>not</i> subject to spurious wakeup.
+ *
+ * Like all Waitable objects, Conditions are sensitive to Thread::interupt() which can
+ * be used to prematurely end a wait().
+ *
+ * @see Thread::interupt()
+ *
+ * Before a wait() is performed on a Condition, the associated Lockable object should
+ * have been acquire()ed. When the wait() begins, that Lockable object is release()d
+ * (wait() will atomically begin the wait and unlock the Lockable).
+ *
+ * A thread blocked by wait() will remain so until an exception occurs, or until
+ * the thread awakened by a signal() or broadcast(). When the thread resumes execution,
+ * the associated Lockable is acquire()d before wait() returns.
+ *
+ * <b>Scheduling</b>
+ *
+ * Threads blocked on a Condition are resumed in FIFO order.
+ */
+ class ZTHREAD_API Condition : public Waitable, private NonCopyable {
+
+ FifoConditionImpl* _impl;
+
+ public:
+
+ /**
+ * Create a Condition associated with the given Lockable object.
+ *
+ * @param l Lockable object to associate with this Condition object.
+ */
+ Condition(Lockable& l);
+
+ //! Destroy Condition object
+ virtual ~Condition();
+
+ /**
+ * Wake <em>one</em> thread waiting on this Condition.
+ *
+ * The associated Lockable need not have been acquire when this function is
+ * invoked.
+ *
+ * @post a waiting thread, if any exists, will be awakened.
+ */
+ void signal();
+
+ /**
+ * Wake <em>all</em> threads wait()ing on this Condition.
+ *
+ * The associated Lockable need not have been acquire when this function is
+ * invoked.
+ *
+ * @post all wait()ing threads, if any exist, will be awakened.
+ */
+ void broadcast();
+
+ /**
+ * Wait for this Condition, blocking the calling thread until a signal or broadcast
+ * is received.
+ *
+ * This operation atomically releases the associated Lockable and blocks the calling thread.
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ *
+ * @pre The thread calling this method must have first acquired the associated
+ * Lockable object.
+ *
+ * @post A thread that has resumed execution without exception (because of a signal(),
+ * broadcast() or exception) will have acquire()d the associated Lockable object
+ * before returning from a wait().
+ *
+ * @see Waitable::wait()
+ */
+ virtual void wait();
+
+ /**
+ * Wait for this Condition, blocking the calling thread until a signal or broadcast
+ * is received.
+ *
+ * This operation atomically releases the associated Lockable and blocks the calling thread.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method could block
+ *
+ * @return
+ * - <em>true</em> if the Condition receives a signal or broadcast before
+ * <i>timeout</i> milliseconds elapse.
+ * - <em>false</em> otherwise.
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ *
+ * @pre The thread calling this method must have first acquired the associated
+ * Lockable object.
+ *
+ * @post A thread that has resumed execution without exception (because of a signal(),
+ * broadcast() or exception) will have acquire()d the associated Lockable object
+ * before returning from a wait().
+ *
+ * @see Waitable::wait(unsigned long timeout)
+ */
+ virtual bool wait(unsigned long timeout);
+
+
+ };
+
+} // namespace ZThread
+
+#endif // __ZTCONDITION_H__
diff --git a/dep/include/zthread/Config.h b/dep/include/zthread/Config.h
new file mode 100644
index 00000000000..21e08bf8461
--- /dev/null
+++ b/dep/include/zthread/Config.h
@@ -0,0 +1,218 @@
+/*
+ * 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 __ZTCONFIG_H__
+#define __ZTCONFIG_H__
+
+// =====================================================================================
+// The following section describes the symbols the configure program will define.
+// If you are not using configure (autoconf), then you make want to set these by
+// uncommenting them here, or whatever other means you'd like.
+// =====================================================================================
+
+// (configure)
+// Uncomment to disable actually changing the operating systems real thread priority
+// #define ZTHREAD_DISABLE_PRIORITY 1
+
+// (configure)
+// Uncomment to disable compiling the interrupt() hook mechanisms.
+// #define ZTHREAD_DISABLE_INTERRUPT 1
+
+// (configure)
+// Uncomment to select a Win32 ThreadOps implementation that uses _beginthreadex()
+// otherwise, CreateThread() will be used for a Windows compilation
+// #define HAVE_BEGINTHREADEX 1
+
+// (configure)
+// Uncomment to select a pthreads based implementation
+// #define ZT_POSIX 1
+
+// (configure)
+// Uncomment to select a Windows based implementation that uses features not
+// supported by windows 98 and 95
+// #define ZT_WIN32 1
+
+// (configure)
+// Uncomment to select a Windows based implementation that does not use features not
+// supported by windows 98 and 95, but may not be compatible with 64 bit or alpha systems
+// #define ZT_WIN9X 1
+
+// (configure)
+// Uncomment to select a MacOS based implementation
+// #define ZT_MACOS 1
+
+// (configure)
+// Uncomment to prefer vanilla implementations of primatives when possible
+// #define ZT_VANILLA 1
+
+// =====================================================================================
+// The following section can be customized to select the implementation that is compiled
+// Eventually, the configure program will be updated to define these symbols as well.
+// =====================================================================================
+
+// Uncomment to select very simple spinlock based implementations
+// #define ZTHREAD_USE_SPIN_LOCKS 1
+
+// Uncomment to select the vannila dual mutex implementation of FastRecursiveLock
+// #define ZTHREAD_DUAL_LOCKS 1
+
+// Uncomment to select a POSIX implementation of FastRecursiveLock that does not
+// spin, but instead sleeps on a condition variable.
+// #define ZTHREAD_CONDITION_LOCKS 1
+
+// Uncomment if you want to eliminate inlined code used as a part of some template classes
+// #define ZTHREAD_NOINLINE
+
+// Uncomment if you want to compile a DLL version of the library. (Win32)
+// #define ZTHREAD_EXPORTS 1
+
+// Uncomment if you want to compile a client using the DLL version of the library. (Win32)
+// #define ZTHREAD_IMPORTS 1
+
+// ===================================================================================
+// The following section will attempt to guess the best configuration for your system
+// ===================================================================================
+
+// Select an implementation by checking out the environment, first looking for
+// compilers, then by looking for other definitions that could be present
+
+#if !defined(ZT_POSIX) && !defined(ZT_WIN9X) && !defined(ZT_WIN32) && !defined(ZT_MACOS)
+
+// Check for well known compilers
+#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__BCPLUSPLUS__) || defined(__MINGW32__)
+
+# define ZT_WIN32
+
+#elif defined(__CYGWIN__)
+
+# define ZT_POSIX
+
+// Check for well known platforms
+#elif defined(__linux__) || \
+ defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
+ defined(__hpux) || \
+ defined(__sgi) || \
+ defined(__sun)
+
+# define ZT_POSIX
+
+// Check for definitions from well known headers
+#elif defined(_POSIX_SOURCE) || defined(_XOPEN_SOURCE)
+
+# define ZT_POSIX
+
+#elif defined(WIN32_LEAN_AND_MEAN)
+
+# define ZT_WIN32
+
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+
+# define ZT_MACOS
+
+#else
+# error "Could not select implementation, define ZT_WIN9X, ZT_WIN32, ZT_POSIX or ZT_MACOS"
+#endif
+
+#endif
+
+// Once an implementation has been selected, configure the API decorator
+// for shared libraries if its needed.
+
+#if defined(ZTHREAD_SHARED) // Compatibility w/ past releases
+
+# define ZTHREAD_IMPORTS
+
+#elif defined(ZTHREAD_STATIC)
+
+# undef ZTHREAD_EXPORTS
+# undef ZTHREAD_IMPORTS
+
+#endif
+
+// Windows users will get a static build by default, unless they
+// define either ZTHREAD_IMPORTS or ZTHREAD_EXPORTS. Client code
+// of a dll version of this library should define the first flag;
+// To build the dll version of this library, define the second.
+
+#if defined(ZTHREAD_IMPORTS) && defined(ZTHREAD_EXPORTS)
+# error "Import and export declarations are not valid"
+#else
+
+# if defined(ZTHREAD_IMPORTS)
+# define ZTHREAD_API __declspec(dllimport)
+# elif defined(ZTHREAD_EXPORTS)
+# define ZTHREAD_API __declspec(dllexport)
+# else
+# define ZTHREAD_API
+# endif
+
+#endif
+
+// Once the API decorator is configured, create a macro for
+// explicit template instantiation (whose need can hopefully
+// be removed from the library)
+
+#if defined(ZTHREAD_EXPORTS)
+# define EXPLICIT_TEMPLATE(X) template class __declspec( dllexport ) X;
+#elif defined(ZTHREAD_IMPORTS)
+# define EXPLICIT_TEMPLATE(X) template class __declspec( dllimport ) X;
+#else
+# define EXPLICIT_TEMPLATE(X)
+#endif
+
+// Give libc a hint, should be defined by the user - but people tend
+// to forget.
+
+#if !defined(REENTRANT)
+# define REENTRANT
+#endif
+
+#if !defined(_REENTRANT)
+# define _REENTRANT
+#endif
+
+#if defined(_MSC_VER)
+# pragma warning(disable:4275)
+# pragma warning(disable:4290)
+# pragma warning(disable:4786)
+# pragma warning(disable:4251)
+# pragma warning(disable:4355)
+#endif
+
+// Ensure that only one implementation is selected
+#if \
+(defined(ZT_POSIX) && defined(ZT_WIN32)) \
+ || (defined(ZT_POSIX) && defined(ZT_WIN9X)) \
+ || (defined(ZT_WIN32) && defined(ZT_WIN9X))
+
+# error "Only one implementation should be selected!"
+
+#endif
+
+#if defined(ZTHREAD_NOINLINE)
+# define ZTHREAD_INLINE
+#else
+# define ZTHREAD_INLINE inline
+#endif
+
+#endif // __ZTCONFIG_H__
+
diff --git a/dep/include/zthread/CountedPtr.h b/dep/include/zthread/CountedPtr.h
new file mode 100644
index 00000000000..a4dcc6ef248
--- /dev/null
+++ b/dep/include/zthread/CountedPtr.h
@@ -0,0 +1,289 @@
+/*
+ * 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 __ZTCOUNTEDPTR_H__
+#define __ZTCOUNTEDPTR_H__
+
+#include <algorithm>
+#include <cassert>
+
+#include "zthread/AtomicCount.h"
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4786) // warning: long template symbol name
+# pragma warning(push)
+# pragma warning(disable:4284) // warning: odd return type for operator->
+#endif
+
+namespace ZThread {
+
+ /**
+ * @class CountedPtr
+ *
+ * @author Eric Crahen <http://www.code-foo.com/>
+ * @date <2003-07-29T06:43:48-0400>
+ * @version 2.3.0
+ *
+ */
+ template <typename T, typename CountT = AtomicCount>
+ class CountedPtr {
+
+#if !defined(__MWERKS__)
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+ template <typename U, typename V> friend class CountedPtr;
+#endif
+#endif
+
+ CountT* _count;
+ T* _instance;
+
+ public:
+
+ CountedPtr() : _count(0), _instance(0) { }
+
+#if !defined(__MWERKS__)
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+
+ explicit CountedPtr(T* raw) : _count(new CountT()), _instance(raw) {
+ (*_count)++;
+ }
+
+#endif
+#endif
+
+ template <typename U>
+ explicit CountedPtr(U* raw) : _count(new CountT()), _instance(raw) {
+ (*_count)++;
+ }
+
+#if !defined(__MWERKS__)
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+
+ CountedPtr(const CountedPtr& ptr) : _count(ptr._count), _instance(ptr._instance) {
+
+ if(_count)
+ (*_count)++;
+
+ }
+
+#endif
+#endif
+
+ template <typename U, typename V>
+ CountedPtr(const CountedPtr<U, V>& ptr) : _count(ptr._count), _instance(ptr._instance) {
+
+ if(_count)
+ (*_count)++;
+
+ }
+
+ ~CountedPtr() {
+
+ if(_count && --(*_count) == 0) {
+
+ if(_instance)
+ delete _instance;
+
+ delete _count;
+
+ }
+
+ }
+
+
+#if !defined(__MWERKS__)
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+
+ const CountedPtr& operator=(const CountedPtr& ptr) {
+
+ typedef CountedPtr<T, CountT> ThisT;
+
+ ThisT(ptr).swap(*this);
+ return *this;
+
+ }
+
+#endif
+#endif
+
+ template <typename U, typename V>
+ const CountedPtr& operator=(const CountedPtr<U, V>& ptr) {
+
+ typedef CountedPtr<T, CountT> ThisT;
+
+ ThisT(ptr).swap(*this);
+ return *this;
+
+ }
+
+ void reset() {
+
+ typedef CountedPtr<T, CountT> ThisT;
+ ThisT().swap(*this);
+
+ }
+
+#if !defined(__MWERKS__)
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+
+ void swap(CountedPtr& ptr) {
+
+ std::swap(_count, ptr._count);
+ std::swap(_instance, ptr._instance);
+
+ }
+
+#endif
+#endif
+
+ template <typename U, typename V>
+ void swap(CountedPtr<U, V>& ptr) {
+
+ std::swap(_count, ptr._count);
+ std::swap(_instance, ptr._instance);
+
+ }
+
+ // Convience operators
+
+#if !defined(__MWERKS__)
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+
+ bool less(const CountedPtr& ptr) const {
+ return _instance < ptr._instance;
+ }
+
+#endif
+#endif
+
+ template <typename U, typename V>
+ bool less(const CountedPtr<U, V>& ptr) const {
+ return _instance < ptr._instance;
+ }
+
+
+#if !defined(__MWERKS__)
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+
+ bool equal(const CountedPtr& ptr) const {
+ return _count == ptr._count;
+ }
+
+#endif
+#endif
+
+ template <typename U, typename V>
+ bool equal(const CountedPtr<U, V>& ptr) const {
+ return _count == ptr._count;
+ }
+
+
+ friend inline bool operator==(const CountedPtr& lhs, const CountedPtr& rhs) {
+ return lhs.equal(rhs);
+ }
+
+ friend inline bool operator<(const CountedPtr& lhs, const CountedPtr& rhs) {
+ return lhs.less(rhs);
+ }
+
+
+ T& operator*() {
+ assert(_instance != 0);
+ return *_instance;
+ }
+
+ T* operator->() {
+ assert(_instance != 0);
+ return _instance;
+ }
+
+ const T* operator->() const {
+ assert(_instance != 0);
+ return _instance;
+ }
+
+ bool operator!() const {
+ return _instance == 0;
+ }
+
+ operator bool() const {
+ return _instance != 0;
+ }
+
+ }; /* CountedPtr */
+
+ template<typename U, typename V, typename X, typename Y>
+ inline bool operator<(CountedPtr<U, V> const &lhs, CountedPtr<X, Y> const &rhs) {
+ return lhs.less(rhs);
+ }
+
+ template<typename U, typename V, typename X, typename Y>
+ inline bool operator==(CountedPtr<U, V> const &lhs, CountedPtr<X, Y> const &rhs) {
+ return lhs.equal(rhs.get);
+ }
+
+ template<typename U, typename V, typename X, typename Y>
+ inline bool operator!=(CountedPtr<U, V> const &lhs, CountedPtr<X, Y> const &rhs) {
+ return !(lhs.equal(rhs.get));
+ }
+
+ template<typename U, typename V, typename X, typename Y>
+ inline void swap(CountedPtr<U, V> const &lhs, CountedPtr<X, Y> const &rhs) {
+ lhs.swap(rhs);
+ }
+
+#if !defined(__MWERKS__)
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+
+ template<typename U, typename V>
+ inline bool operator<(CountedPtr<U, V> const &lhs, CountedPtr<U, V> const &rhs) {
+ return lhs.less(rhs);
+ }
+
+ template<typename U, typename V>
+ inline bool operator==(CountedPtr<U, V> const &lhs, CountedPtr<U, V> const &rhs) {
+ return lhs.equal(rhs.get);
+ }
+
+ template<typename U, typename V>
+ inline bool operator!=(CountedPtr<U, V> const &lhs, CountedPtr<U, V> const &rhs) {
+ return !(lhs.equal(rhs.get));
+ }
+
+ template<typename U, typename V>
+ inline void swap(CountedPtr<U, V> const &lhs, CountedPtr<U, V> const &rhs) {
+ lhs.swap(rhs);
+ }
+
+#endif
+#endif
+
+} // namespace ZThread
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+# pragma warning(pop)
+#endif
+
+
+#endif // __ZTCOUNTEDPTR_H__
diff --git a/dep/include/zthread/CountingSemaphore.h b/dep/include/zthread/CountingSemaphore.h
new file mode 100644
index 00000000000..f580a65f726
--- /dev/null
+++ b/dep/include/zthread/CountingSemaphore.h
@@ -0,0 +1,138 @@
+/*
+ * 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 __ZTCOUNTINGSEMAPHORE_H__
+#define __ZTCOUNTINGSEMAPHORE_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class FifoSemaphoreImpl;
+
+ /**
+ * @class CountingSemaphore
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T15:26:18-0400>
+ * @version 2.2.1
+ *
+ * A CountingSemaphore is an owner-less Lockable object.
+ *
+ * It differs from a normal Semaphore in that there is no upper bound on the count
+ * and it will not throw an exception because a maximum value has been exceeded.
+ *
+ * @see Semaphore
+ *
+ * Threads blocked on a CountingSemaphore are resumed in FIFO order.
+ */
+ class ZTHREAD_API CountingSemaphore : public Lockable, private NonCopyable {
+
+ FifoSemaphoreImpl* _impl;
+
+ public:
+
+ /**
+ * Create a new CountingSemaphore.
+ *
+ * @param count - initial count
+ */
+ CountingSemaphore(int initialCount = 0);
+
+ //! Destroy the CountingSemaphore
+ virtual ~CountingSemaphore();
+
+ /**
+ * <i>Provided to reflect the traditional Semaphore semantics</i>
+ *
+ * @see acquire()
+ */
+ void wait();
+
+
+ /**
+ * <i>Provided to reflect the traditional Semaphore semantics</i>
+ *
+ * @see tryAcquire(unsigned long timeout)
+ */
+ bool tryWait(unsigned long timeout);
+
+ /**
+ * <i>Provided to reflect the traditional Semaphore semantics</i>
+ *
+ * @see release()
+ */
+ void post();
+
+
+ /**
+ * Get the current count of the semaphore.
+ *
+ * This value may change immediately after this function returns to the calling thread.
+ *
+ * @return <em>int</em> count
+ */
+ virtual int count();
+
+ /**
+ * Decrement the count, blocking that calling thread if the count becomes 0 or
+ * less than 0. The calling thread will remain blocked until the count is
+ * raised above 0, an exception is thrown or the given amount of time expires.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method could block
+ *
+ * @return
+ * - <em>true</em> if the Semaphore was acquired before <i>timeout</i> milliseconds elapse.
+ * - <em>false</em> otherwise.
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ *
+ * @see Lockable::tryAcquire(unsigned long timeout)
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+ /**
+ * Decrement the count, blocking that calling thread if the count becomes 0 or
+ * less than 0. The calling thread will remain blocked until the count is
+ * raised above 0 or if an exception is thrown.
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ *
+ * @see Lockable::acquire()
+ */
+ virtual void acquire();
+
+ /**
+ * Increment the count, unblocking one thread if count is positive.
+ *
+ * @see Lockable::release()
+ */
+ virtual void release();
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTCOUNTINGSEMAPHORE_H__
diff --git a/dep/include/zthread/Exceptions.h b/dep/include/zthread/Exceptions.h
new file mode 100644
index 00000000000..b7207932af4
--- /dev/null
+++ b/dep/include/zthread/Exceptions.h
@@ -0,0 +1,244 @@
+/*
+ * 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 __ZTEXCEPTIONS_H__
+#define __ZTEXCEPTIONS_H__
+
+
+#include "zthread/Config.h"
+#include <string>
+
+namespace ZThread {
+
+/**
+ * @class Synchronization_Exception
+ *
+ * Serves as a general base class for the Exception hierarchy used within
+ * this package.
+ *
+ */
+class Synchronization_Exception {
+
+ // Restrict heap allocation
+ static void * operator new(size_t size);
+ static void * operator new[](size_t size);
+
+ std::string _msg;
+
+public:
+
+ /**
+ * Create a new exception with a default error message 'Synchronization
+ * Exception'
+ */
+ Synchronization_Exception() : _msg("Synchronization exception") { }
+
+ /**
+ * Create a new exception with a given error message
+ *
+ * @param const char* - error message
+ */
+ Synchronization_Exception(const char* msg) : _msg(msg) { }
+
+ /**
+ * Get additional info about the exception
+ *
+ * @return const char* for the error message
+ */
+ const char* what() const {
+ return _msg.c_str();
+ }
+
+};
+
+
+/**
+ * @class Interrupted_Exception
+ *
+ * Used to describe an interrupted operation that would have normally
+ * blocked the calling thread
+ */
+class Interrupted_Exception : public Synchronization_Exception {
+
+ public:
+
+ //! Create a new exception
+ Interrupted_Exception() : Synchronization_Exception("Thread interrupted") { }
+
+ //! Create a new exception
+ Interrupted_Exception(const char* msg) : Synchronization_Exception(msg) { }
+
+};
+
+
+
+/**
+ * @class Deadlock_Exception
+ *
+ * Thrown when deadlock has been detected
+ */
+class Deadlock_Exception : public Synchronization_Exception {
+ public:
+
+ //! Create a new exception
+ Deadlock_Exception() : Synchronization_Exception("Deadlock detected") { }
+
+ //! Create a new exception
+ Deadlock_Exception(const char* msg) : Synchronization_Exception(msg) { }
+
+};
+
+
+/**
+ * @class InvalidOp_Exception
+ *
+ * Thrown when performing an illegal operation this object
+ */
+class InvalidOp_Exception : public Synchronization_Exception {
+ public:
+
+ //! Create a new exception
+ InvalidOp_Exception() : Synchronization_Exception("Invalid operation") { }
+ //! Create a new exception
+ InvalidOp_Exception(const char* msg) : Synchronization_Exception(msg) { }
+
+};
+
+
+
+/**
+ * @class Initialization_Exception
+ *
+ * Thrown when the system has no more resources to create new
+ * synchronization controls
+ */
+class Initialization_Exception : public Synchronization_Exception {
+
+ public:
+
+ //! Create a new exception
+ Initialization_Exception() : Synchronization_Exception("Initialization error") { }
+ //! Create a new exception
+ Initialization_Exception(const char*msg) : Synchronization_Exception(msg) { }
+
+};
+
+/**
+ * @class Cancellation_Exception
+ *
+ * Cancellation_Exceptions are thrown by 'Canceled' objects.
+ * @see Cancelable
+ */
+class Cancellation_Exception : public Synchronization_Exception {
+
+ public:
+
+ //! Create a new Cancelltion_Exception
+ Cancellation_Exception() : Synchronization_Exception("Canceled") { }
+ //! Create a new Cancelltion_Exception
+ Cancellation_Exception(const char*msg) : Synchronization_Exception(msg) { }
+
+};
+
+
+/**
+ * @class Timeout_Exception
+ *
+ * There is no need for error messaged simply indicates the last
+ * operation timed out
+ */
+class Timeout_Exception : public Synchronization_Exception {
+ public:
+
+ //! Create a new Timeout_Exception
+ Timeout_Exception() : Synchronization_Exception("Timeout") { }
+ //! Create a new
+ Timeout_Exception(const char*msg) : Synchronization_Exception(msg) { }
+
+};
+
+/**
+ * @class NoSuchElement_Exception
+ *
+ * The last operation that was attempted on a Queue could not find
+ * the item that was indicated (during that last Queue method invocation)
+ */
+class NoSuchElement_Exception {
+ public:
+
+ //! Create a new exception
+ NoSuchElement_Exception() {}
+
+};
+
+/**
+ * @class InvalidTask_Exception
+ *
+ * Thrown when a task is not valid (e.g. null or start()ing a thread with
+ * no overriden run() method)
+ */
+class InvalidTask_Exception : public InvalidOp_Exception {
+ public:
+
+ //! Create a new exception
+ InvalidTask_Exception() : InvalidOp_Exception("Invalid task") {}
+
+};
+
+/**
+ * @class BrokenBarrier_Exception
+ *
+ * Thrown when a Barrier is broken because one of the participating threads
+ * has been interrupted.
+ */
+class BrokenBarrier_Exception : public Synchronization_Exception {
+
+ public:
+
+ //! Create a new exception
+ BrokenBarrier_Exception() : Synchronization_Exception("Barrier broken") { }
+
+ //! Create a new exception
+ BrokenBarrier_Exception(const char* msg) : Synchronization_Exception(msg) { }
+
+};
+
+/**
+ * @class Future_Exception
+ *
+ * Thrown when there is an error using a Future.
+ */
+class Future_Exception : public Synchronization_Exception {
+
+ public:
+
+ //! Create a new exception
+ Future_Exception() : Synchronization_Exception() { }
+
+ //! Create a new exception
+ Future_Exception(const char* msg) : Synchronization_Exception(msg) { }
+
+};
+
+};
+
+#endif // __ZTEXCEPTIONS_H__
diff --git a/dep/include/zthread/Executor.h b/dep/include/zthread/Executor.h
new file mode 100644
index 00000000000..833d0d4c3d1
--- /dev/null
+++ b/dep/include/zthread/Executor.h
@@ -0,0 +1,94 @@
+/*
+ * 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 __ZTEXECUTOR_H__
+#define __ZTEXECUTOR_H__
+
+#include "zthread/Thread.h"
+#include "zthread/Waitable.h"
+
+namespace ZThread {
+
+
+ /**
+ * @class Executor
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T22:39:39-0400>
+ * @version 2.3.0
+ *
+ * Execeutors are an implementation of the Executor pattern. This is
+ * a more versatile construct than a thread pool. A paper describing can
+ * be found in the proceedings of the 2002 VikingPLOP conference.
+ *
+ * <b>Executing</b>
+ *
+ * - <em>execute</em>()ing task with an Executor will submit the task, scheduling
+ * it for execution at some future time depending on the Executor being used.
+ *
+ * <b>Disabling</b>
+ *
+ * - <em>cancel</em>()ing an Executor will cause it to stop accepting
+ * new tasks.
+ *
+ * <b>Interrupting</b>
+ *
+ * - <em>interrupt</em>()ing an Executor will cause the any thread running
+ * a task which was submitted prior to the invocation of this function to
+ * be interrupted during the execution of that task.
+ *
+ * <b>Waiting</b>
+ *
+ * - <em>wait</em>()ing on a PoolExecutor will block the calling thread
+ * until all tasks that were submitted prior to the invocation of this function
+ * have completed.
+ *
+ * @see Cancelable
+ * @see Waitable
+ */
+ class Executor : public Cancelable, public Waitable, private NonCopyable {
+ public:
+
+ /**
+ * If supported by the Executor, interrupt all tasks submitted prior to
+ * the invocation of this function.
+ */
+ virtual void interrupt() = 0;
+
+ /**
+ * Submit a task to this Executor.
+ *
+ * @param task Task to be run by a thread managed by this executor
+ *
+ * @pre The Executor should have been canceled prior to this invocation.
+ * @post The submitted task will be run at some point in the future by this Executor.
+ *
+ * @exception Cancellation_Exception thrown if the Executor was canceled prior to
+ * the invocation of this function.
+ */
+ virtual void execute(const Task& task) = 0;
+
+ };
+
+} // namespace ZThread
+
+#endif // __ZTEXECUTOR_H__
diff --git a/dep/include/zthread/FairReadWriteLock.h b/dep/include/zthread/FairReadWriteLock.h
new file mode 100644
index 00000000000..8f183b62839
--- /dev/null
+++ b/dep/include/zthread/FairReadWriteLock.h
@@ -0,0 +1,183 @@
+/*
+ * 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 __ZTFAIRREADWRITELOCK_H__
+#define __ZTFAIRREADWRITELOCK_H__
+
+#include "zthread/ReadWriteLock.h"
+#include "zthread/Condition.h"
+#include "zthread/Guard.h"
+#include "zthread/Mutex.h"
+
+namespace ZThread {
+
+ /**
+ * @class FairReadWriteLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T10:26:25-0400>
+ * @version 2.2.7
+ *
+ * A FairReadWriteLock maintains a balance between the order read-only access
+ * and read-write access is allowed. Threads contending for the pair of Lockable
+ * objects this ReadWriteLock provides will gain access to the locks in FIFO order.
+ *
+ * @see ReadWriteLock
+ */
+ class FairReadWriteLock : public ReadWriteLock {
+
+ Mutex _lock;
+ Condition _cond;
+
+ volatile int _readers;
+
+ //! @class ReadLock
+ class ReadLock : public Lockable {
+
+ FairReadWriteLock& _rwlock;
+
+ public:
+
+ ReadLock(FairReadWriteLock& rwlock) : _rwlock(rwlock) {}
+
+ virtual ~ReadLock() {}
+
+ virtual void acquire() {
+
+ Guard<Mutex> g(_rwlock._lock);
+ ++_rwlock._readers;
+
+ }
+
+ virtual bool tryAcquire(unsigned long timeout) {
+
+ if(!_rwlock._lock.tryAcquire(timeout))
+ return false;
+
+ ++_rwlock._readers;
+ _rwlock._lock.release();
+
+ return true;
+ }
+
+ virtual void release() {
+
+ Guard<Mutex> g(_rwlock._lock);
+ --_rwlock._readers;
+
+ if(_rwlock._readers == 0)
+ _rwlock._cond.signal();
+
+ }
+
+ };
+
+ //! @class WriteLock
+ class WriteLock : public Lockable {
+
+ FairReadWriteLock& _rwlock;
+
+ public:
+
+ WriteLock(FairReadWriteLock& rwlock) : _rwlock(rwlock) {}
+
+ virtual ~WriteLock() {}
+
+ virtual void acquire() {
+
+ _rwlock._lock.acquire();
+
+ try {
+
+ while(_rwlock._readers > 0)
+ _rwlock._cond.wait();
+
+ } catch(...) {
+
+ _rwlock._lock.release();
+ throw;
+
+ }
+
+ }
+
+ virtual bool tryAcquire(unsigned long timeout) {
+
+ if(!_rwlock._lock.tryAcquire(timeout))
+ return false;
+
+ try {
+
+ while(_rwlock._readers > 0)
+ _rwlock._cond.wait(timeout);
+
+ } catch(...) {
+
+ _rwlock._lock.release();
+ throw;
+
+ }
+
+ return true;
+
+ }
+
+ virtual void release() {
+ _rwlock._lock.release();
+ }
+
+ };
+
+ friend class ReadLock;
+ friend class WriteLock;
+
+ ReadLock _rlock;
+ WriteLock _wlock;
+
+ public:
+
+ /**
+ * Create a BiasedReadWriteLock
+ *
+ * @exception Initialization_Exception thrown if resources could not be
+ * allocated for this object.
+ */
+ FairReadWriteLock() : _cond(_lock), _readers(0), _rlock(*this), _wlock(*this) {}
+
+ //! Destroy this ReadWriteLock
+ virtual ~FairReadWriteLock() {}
+
+ /**
+ * @see ReadWriteLock::getReadLock()
+ */
+ virtual Lockable& getReadLock() { return _rlock; }
+
+ /**
+ * @see ReadWriteLock::getWriteLock()
+ */
+ virtual Lockable& getWriteLock() { return _wlock; }
+
+ };
+
+}; // __ZTFAIRREADWRITELOCK_H__
+
+#endif
diff --git a/dep/include/zthread/FastMutex.h b/dep/include/zthread/FastMutex.h
new file mode 100644
index 00000000000..1812c3e55a5
--- /dev/null
+++ b/dep/include/zthread/FastMutex.h
@@ -0,0 +1,111 @@
+/*
+ * 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 __ZTFASTMUTEX_H__
+#define __ZTFASTMUTEX_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class FastLock;
+
+ /**
+ * @class FastMutex
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-19T18:45:39-0400>
+ * @version 2.2.0
+ *
+ * A FastMutex is a small fast implementation of a non-recursive, mutually exclusive
+ * Lockable object. This implementation is a bit faster than the other Mutex classes
+ * as it involved the least overhead. However, this slight increase in speed is
+ * gained by sacrificing the robustness provided by the other classes.
+ *
+ * A FastMutex has the useful property of not being interruptable; that is to say
+ * that acquire() and tryAcquire() will not throw Interrupted_Exceptions.
+ *
+ * @see Mutex
+ *
+ * <b>Scheduling</b>
+ *
+ * Scheduling is left to the operating systems and may vary.
+ *
+ * <b>Error Checking</b>
+ *
+ * No error checking is performed, this means there is the potential for deadlock.
+ */
+ class ZTHREAD_API FastMutex : public Lockable, private NonCopyable {
+
+ FastLock* _lock;
+
+ public:
+
+ //! Create a FastMutex
+ FastMutex();
+
+ //! Destroy a FastMutex
+ virtual ~FastMutex();
+
+ /**
+ * Acquire exclusive access to the mutex. The calling thread will block until the
+ * lock can be acquired. No safety or state checks are performed.
+ *
+ * @pre The calling thread should <i>not</i> have previously acquired this lock.
+ * Deadlock will result if the same thread attempts to acquire the mutex more
+ * than once.
+ *
+ * @post The calling thread obtains the lock successfully if no exception is thrown.
+ * @exception Interrupted_Exception never thrown
+ */
+ virtual void acquire();
+
+ /**
+ * Release exclusive access. No safety or state checks are performed.
+ *
+ * @pre the caller should have previously acquired this lock
+ */
+ virtual void release();
+
+ /**
+ * Try to acquire exclusive access to the mutex. The calling thread will block until the
+ * lock can be acquired. No safety or state checks are performed.
+ *
+ * @pre The calling thread should <i>not</i> have previously acquired this lock.
+ * Deadlock will result if the same thread attempts to acquire the mutex more
+ * than once.
+ *
+ * @param timeout unused
+ * @return
+ * - <em>true</em> if the lock was acquired
+ * - <em>false</em> if the lock was acquired
+ *
+ * @post The calling thread obtains the lock successfully if no exception is thrown.
+ * @exception Interrupted_Exception never thrown
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+ }; /* FastMutex */
+
+};
+
+#endif // __ZTFASTMUTEX_H__
diff --git a/dep/include/zthread/FastRecursiveMutex.h b/dep/include/zthread/FastRecursiveMutex.h
new file mode 100644
index 00000000000..a30f4b53aa7
--- /dev/null
+++ b/dep/include/zthread/FastRecursiveMutex.h
@@ -0,0 +1,106 @@
+/*
+ * 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 __ZTFASTRECURSIVEMUTEX_H__
+#define __ZTFASTRECURSIVEMUTEX_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class FastRecursiveLock;
+
+ /**
+ * @class FastRecursiveMutex
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-19T19:00:25-0400>
+ * @version 2.2.0
+ *
+ * A FastRecursiveMutex is a small fast implementation of a recursive, mutally exclusive
+ * Lockable object. This implementation is a bit faster than the other Mutex classes
+ * as it involved the least overhead. However, this slight increase in speed is
+ * gained by sacrificing the robustness provided by the other classes.
+ *
+ * A FastRecursiveMutex has the useful property of not being interruptable; that is to say
+ * that acquire() and tryAcquire() will not throw Interrupted_Exceptions.
+ *
+ * @see RecursiveMutex
+ *
+ * <b>Scheduling</b>
+ *
+ * Scheduling is left to the operating systems and may vary.
+ *
+ * <b>Error Checking</b>
+ *
+ * No error checking is performed, this means there is the potential for deadlock.
+ */
+ class ZTHREAD_API FastRecursiveMutex : public Lockable, private NonCopyable {
+
+ FastRecursiveLock* _lock;
+
+ public:
+
+ //! Create a new FastRecursiveMutex
+ FastRecursiveMutex();
+
+ //! Destroy this FastRecursiveMutex
+ virtual ~FastRecursiveMutex();
+
+ /**
+ * Acquire exclusive access to the mutex. The calling thread will block until the
+ * lock can be acquired. No safety or state checks are performed. The calling thread
+ * may acquire the mutex nore than once.
+ *
+ * @post The calling thread obtains the lock successfully if no exception is thrown.
+ * @exception Interrupted_Exception never thrown
+ */
+ virtual void acquire();
+
+ /**
+ * Release access. No safety or state checks are performed.
+ *
+ * @pre the caller should have previously acquired this lock at least once.
+ */
+ virtual void release();
+
+ /**
+ * Try to acquire exclusive access to the mutex. The calling thread will block until the
+ * lock can be acquired. No safety or state checks are performed. The calling thread
+ * may acquire the mutex more than once.
+ *
+ * @param timeout unused
+ * @return
+ * - <em>true</em> if the lock was acquired
+ * - <em>false</em> if the lock was acquired
+ *
+ * @post The calling thread obtains the lock successfully if no exception is thrown.
+ * @exception Interrupted_Exception never thrown
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+ };
+
+} // namespace ZThread
+
+#endif // __ZTFASTRECURSIVEMUTEX_H__
diff --git a/dep/include/zthread/Guard.h b/dep/include/zthread/Guard.h
new file mode 100644
index 00000000000..988c3cfa3c2
--- /dev/null
+++ b/dep/include/zthread/Guard.h
@@ -0,0 +1,511 @@
+/*
+ * 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 __ZTGUARD_H__
+#define __ZTGUARD_H__
+
+#include "zthread/NonCopyable.h"
+#include "zthread/Exceptions.h"
+
+namespace ZThread {
+
+//
+// GuardLockingPolicyContract {
+//
+// createScope(lock_type&)
+// bool createScope(lock_type&, unsigned long)
+// destroyScope(lock_type&)
+//
+// }
+//
+
+/**
+ * @class LockHolder
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:55:42-0400>
+ * @version 2.2.0
+ *
+ * This is a simple base class for Guards class. It allows Guards
+ * that have compatible targets to refer to each others targets
+ * allowing for the construction of Guards that share the same lock
+ * but have different locking policies.
+ */
+template <class LockType>
+class LockHolder {
+
+ LockType &_lock;
+ bool _enabled;
+
+ public:
+
+ template <class T>
+ LockHolder(T& t) : _lock(extract(t)._lock), _enabled(true) { }
+
+ LockHolder(LockHolder& holder) : _lock(holder._lock), _enabled(true) { }
+
+ LockHolder(LockType& lock) : _lock(lock), _enabled(true) { }
+
+ void disable() {
+ _enabled = false;
+ }
+
+ bool isDisabled() {
+ return !_enabled;
+ }
+
+ LockType& getLock() {
+ return _lock;
+ }
+
+ protected:
+
+ template <class T>
+ static LockHolder& extract(T& t) {
+ // Design and Evolution of C++, page 328
+ return (LockHolder&)(t);
+ }
+
+};
+
+/**
+ * @class CompoundScope
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:55:42-0400>
+ * @version 2.2.0
+ *
+ * Locking policy that aggregates two policies that share a target.
+ * It is not appropriate to use with any type of OverlappedScope
+ */
+template <class Scope1, class Scope2>
+class CompoundScope {
+ public:
+
+ template <class LockType>
+ static void createScope(LockHolder<LockType>& l) {
+
+ Scope1::createScope(l);
+ Scope2::createScope(l);
+
+ }
+
+ template <class LockType>
+ static void createScope(LockHolder<LockType>& l, unsigned long ms) {
+
+ if(Scope1::createScope(l, ms))
+ if(!Scope2::createScope(l, ms)) {
+
+ Scope1::destroyScope(l);
+ return false;
+
+ }
+
+ return true;
+
+ }
+
+ template <class LockType>
+ static void destroyScope(LockHolder<LockType>& l) {
+
+ Scope1::destroyScope(l);
+ Scope2::destroyScope(l);
+
+ }
+
+};
+
+
+/**
+ * @class LockedScope
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:55:42-0400>
+ * @version 2.2.0
+ *
+ * Locking policy for Lockable objects. This policy acquire()s a Lockable
+ * when the protection scope is created, and it release()s a Lockable
+ * when the scope is destroyed.
+ */
+class LockedScope {
+ public:
+
+ /**
+ * A new protection scope is being created by l2, using an existing scope
+ * created by l1.
+ *
+ * @param lock1 LockType1& is the LockHolder that holds the desired lock
+ * @param lock2 LockType1& is the LockHolder that wants to share
+ template <class LockType1, class LockType2>
+ static void shareScope(LockHolder<LockType1>& l1, LockHolder<LockType2>& l2) {
+
+ l2.getLock().acquire();
+
+ }
+ */
+
+ /**
+ * A new protection scope is being created.
+ *
+ * @param lock LockType& is a type of LockHolder.
+ */
+ template <class LockType>
+ static bool createScope(LockHolder<LockType>& l, unsigned long ms) {
+
+ return l.getLock().tryAcquire(ms);
+
+ }
+
+ /**
+ * A new protection scope is being created.
+ *
+ * @param lock LockType& is a type of LockHolder.
+ */
+ template <class LockType>
+ static void createScope(LockHolder<LockType>& l) {
+
+ l.getLock().acquire();
+
+ }
+
+ /**
+ * A protection scope is being destroyed.
+ *
+ * @param lock LockType& is a type of LockHolder.
+ */
+ template <class LockType>
+ static void destroyScope(LockHolder<LockType>& l) {
+
+ l.getLock().release();
+
+ }
+
+};
+
+
+/**
+ * @class UnlockedScope
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:55:42-0400>
+ * @version 2.2.0
+ *
+ * Locking policy for Lockable objects. This policy release()s a Lockable
+ * when the protection scope is created, and it acquire()s a Lockable
+ * when the scope is destroyed.
+ */
+class UnlockedScope {
+ public:
+
+ /**
+ * A new protection scope is being created by l2, using an existing scope
+ * created by l1.
+ *
+ * @param lock1 LockType1& is the LockHolder that holds the desired lock
+ * @param lock2 LockType1& is the LockHolder that wants to share
+ */
+ template <class LockType1, class LockType2>
+ static void shareScope(LockHolder<LockType1>& /*l1*/, LockHolder<LockType2>& l2) {
+
+ l2.getLock().release();
+
+ }
+
+ /**
+ * A new protection scope is being created.
+ *
+ * @param lock LockType& is a type of LockHolder.
+ template <class LockType>
+ static void createScope(LockHolder<LockType>& l) {
+
+ l.getLock().release();
+
+ }
+ */
+
+ /**
+ * A protection scope is being destroyed.
+ *
+ * @param lock LockType& is a type of LockHolder.
+ */
+ template <class LockType>
+ static void destroyScope(LockHolder<LockType>& l) {
+
+ l.getLock().acquire();
+
+ }
+
+};
+
+
+
+/**
+ * @class TimedLockedScope
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:55:42-0400>
+ * @version 2.2.0
+ *
+ * Locking policy that attempts to enterScope some resource
+ * in a certain amount of time using an tryEnterScope-relase protocol.
+ */
+template <int TimeOut>
+class TimedLockedScope {
+ public:
+
+ /**
+ * Try to enterScope the given LockHolder.
+ *
+ * @param lock LockType& is a type of LockHolder.
+ */
+ template <class LockType1, class LockType2>
+ static void shareScope(LockHolder<LockType1>& l1, LockHolder<LockType2>& l2) {
+
+ if(!l2.getLock().tryAcquire(TimeOut))
+ throw Timeout_Exception();
+
+ }
+
+ template <class LockType>
+ static void createScope(LockHolder<LockType>& l) {
+
+ if(!l.getLock().tryAcquire(TimeOut))
+ throw Timeout_Exception();
+
+ }
+
+ template <class LockType>
+ static void destroyScope(LockHolder<LockType>& l) {
+
+ l.getLock().release();
+
+ }
+
+};
+
+
+/**
+ * @class OverlappedScope
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:55:42-0400>
+ * @version 2.2.0
+ *
+ * Locking policy allows the effective scope of two locks to overlap
+ * by releasing and disabling one lock before its Guard does so.
+ */
+class OverlappedScope {
+ public:
+
+ template <class LockType1, class LockType2>
+ static void transferScope(LockHolder<LockType1>& l1, LockHolder<LockType2>& l2) {
+
+ l1.getLock().acquire();
+
+ l2.getLock().release();
+ l2.disable();
+
+ }
+
+ template <class LockType>
+ static void destroyScope(LockHolder<LockType>& l) {
+
+ l.getLock().release();
+
+ }
+
+};
+
+
+
+/**
+ * @class Guard
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:55:42-0400>
+ * @version 2.2.0
+ *
+ * Scoped locking utility. This template class can be given a Lockable
+ * synchronization object and can 'Guard' or serialize access to
+ * that method.
+ *
+ * For instance, consider a case in which a class or program have a
+ * Mutex object associated with it. Access can be serialized with a
+ * Guard as shown below.
+ *
+ * @code
+ *
+ * Mutex _mtx;
+ * void guarded() {
+ *
+ * Guard<Mutex> g(_mtx);
+ *
+ * }
+ *
+ * @endcode
+ *
+ * The Guard will lock the synchronization object when it is created and
+ * automatically unlock it when it goes out of scope. This eliminates
+ * common mistakes like forgetting to unlock your mutex.
+ *
+ * An alternative to the above example would be
+ *
+ * @code
+ *
+ * void guarded() {
+ *
+ * (Guard<Mutex>)(_mtx);
+ *
+ * }
+ *
+ * @endcode
+ *
+ * HOWEVER; using a Guard in this method is dangerous. Depending on your
+ * compiler an anonymous variable like this can go out of scope immediately
+ * which can result in unexpected behavior. - This is the case with MSVC
+ * and was the reason for introducing assertions into the Win32_MutexImpl
+ * to track this problem down
+ *
+ */
+template <class LockType, class LockingPolicy = LockedScope>
+class Guard : private LockHolder<LockType>, private NonCopyable {
+
+ friend class LockHolder<LockType>;
+
+public:
+
+ /**
+ * Create a Guard that enforces a the effective protection scope
+ * throughout the lifetime of the Guard object or until the protection
+ * scope is modified by another Guard.
+ *
+ * @param lock LockType the lock this Guard will use to enforce its
+ * protection scope.
+ * @post the protection scope may be ended prematurely
+ */
+ Guard(LockType& lock) : LockHolder<LockType>(lock) {
+
+ LockingPolicy::createScope(*this);
+
+ };
+
+ /**
+ * Create a Guard that enforces a the effective protection scope
+ * throughout the lifetime of the Guard object or until the protection
+ * scope is modified by another Guard.
+ *
+ * @param lock LockType the lock this Guard will use to enforce its
+ * protection scope.
+ * @post the protection scope may be ended prematurely
+ */
+ Guard(LockType& lock, unsigned long timeout) : LockHolder<LockType>(lock) {
+
+ if(!LockingPolicy::createScope(*this, timeout))
+ throw Timeout_Exception();
+
+ };
+
+ /**
+ * Create a Guard that shares the effective protection scope
+ * from the given Guard to this Guard.
+ *
+ * @param g Guard<U, V> guard that is currently enabled
+ * @param lock LockType the lock this Guard will use to enforce its
+ * protection scope.
+ */
+ template <class U, class V>
+ Guard(Guard<U, V>& g) : LockHolder<LockType>(g) {
+
+ LockingPolicy::shareScope(*this, extract(g));
+
+ }
+
+ /**
+ * Create a Guard that shares the effective protection scope
+ * from the given Guard to this Guard.
+ *
+ * @param g Guard guard that is currently enabled
+ * @param lock LockType the lock this Guard will use to enforce its
+ * protection scope.
+ */
+ Guard(Guard& g) : LockHolder<LockType>(g) {
+
+ LockingPolicy::shareScope(*this, g);
+
+ }
+
+
+ /**
+ * Create a Guard that transfers the effective protection scope
+ * from the given Guard to this Guard.
+ *
+ * @param g Guard<U, V> guard that is currently enabled
+ * @param lock LockType the lock this Guard will use to enforce its
+ * protection scope.
+ */
+ template <class U, class V>
+ Guard(Guard<U, V>& g, LockType& lock) : LockHolder<LockType>(lock) {
+
+ LockingPolicy::transferScope(*this, extract(g));
+
+ }
+
+
+ /**
+ * Create a Guard that transfers the effective protection scope
+ * from the given Guard to this Guard.
+ *
+ * @param g Guard guard that is currently enabled
+ * @param lock LockType the lock this Guard will use to enforce its
+ * protection scope.
+ */
+ Guard(Guard& g, LockType& lock) : LockHolder<LockType>(lock) {
+
+ LockingPolicy::transferScope(*this, g);
+
+ }
+
+
+ /**
+ * Unlock a given Lockable object with the destruction of this Guard
+ */
+ ~Guard() throw();
+
+}; /* Guard */
+
+
+template <class LockType, class LockingPolicy>
+Guard<LockType, LockingPolicy>::~Guard() throw() {
+
+ try {
+
+ if(!this->isDisabled())
+ LockingPolicy::destroyScope(*this);
+
+ } catch (...) { /* ignore */ }
+
+}
+
+
+};
+
+#endif // __ZTGUARD_H__
+
+
+
+
+
+
+
diff --git a/dep/include/zthread/GuardedClass.h b/dep/include/zthread/GuardedClass.h
new file mode 100644
index 00000000000..4ef3879cb08
--- /dev/null
+++ b/dep/include/zthread/GuardedClass.h
@@ -0,0 +1,103 @@
+/*
+ * 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 __GUARDEDCLASS_H__
+#define __GUARDEDCLASS_H__
+
+#include "zthread/Guard.h"
+#include "zthread/Mutex.h"
+
+namespace ZThread {
+
+ /**
+ * @class GuardedClass
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-20T20:17:34-0400>
+ * @version 2.3.0
+ *
+ * A simple wrapper template that uses Guard's to provide
+ * serialized access to an objects member functions.
+ */
+ template <class T, class LockType = Mutex>
+ class GuardedClass {
+
+ LockType _lock;
+ T* _ptr;
+
+ class TransferedScope {
+ public:
+
+ template <class LockType1, class LockType2>
+ static void shareScope(LockHolder<LockType1>& l1,
+ LockHolder<LockType2>& l2) {
+ l1.disable();
+ l2.getLock().acquire();
+ }
+
+ template <class LockType1>
+ static void createScope(LockHolder<LockType1>& l) {
+ // Don't acquire the lock when scope the Guard is created
+ }
+
+ template <class LockType1>
+ static void destroyScope(LockHolder<LockType1>& l) {
+ l.getLock().release();
+ }
+
+ };
+
+ class Proxy : Guard<LockType, TransferedScope> {
+
+ T* _object;
+
+ public:
+
+ Proxy(LockType& lock, T* object) :
+ Guard<LockType, TransferedScope>(lock), _object(object) { }
+
+ T* operator->() {
+ return _object;
+ }
+
+ };
+
+ GuardedClass();
+ GuardedClass& operator=(const GuardedClass&);
+
+ public:
+
+ GuardedClass(T* ptr) : _ptr(ptr) {}
+ ~GuardedClass() {
+ if(_ptr)
+ delete _ptr;
+ }
+
+ Proxy operator->() {
+ Proxy p(_lock, _ptr);
+ return p;
+ }
+
+ };
+
+} // namespace ZThread
+
+#endif // __ZTGUARDEDCLASS_H__
diff --git a/dep/include/zthread/Lockable.h b/dep/include/zthread/Lockable.h
new file mode 100644
index 00000000000..32f7eeda97b
--- /dev/null
+++ b/dep/include/zthread/Lockable.h
@@ -0,0 +1,96 @@
+/*
+ * 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 __ZTLOCKABLE_H__
+#define __ZTLOCKABLE_H__
+
+#include "zthread/Exceptions.h"
+
+namespace ZThread {
+
+ /**
+ * @class Lockable
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T10:33:32-0400>
+ * @version 2.3.0
+ *
+ * The Lockable interface defines a common method of adding general <i>acquire-release</i>
+ * semantics to an object. An <i>acquire-release</i> protocol does not necessarily imply
+ * exclusive access.
+ */
+ class Lockable {
+ public:
+
+ //! Destroy a Lockable object.
+ virtual ~Lockable() {}
+
+ /**
+ * Acquire the Lockable object.
+ *
+ * This method may or may not block the caller for an indefinite amount
+ * of time. Those details are defined by specializations of this class.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted before
+ * the operation completes.
+ *
+ * @post The Lockable is acquired only if no exception was thrown.
+ */
+ virtual void acquire() = 0;
+
+ /**
+ * Attempt to acquire the Lockable object.
+ *
+ * This method may or may not block the caller for a definite amount
+ * of time. Those details are defined by specializations of this class;
+ * however, this method includes a timeout value that can be used to
+ * limit the maximum amount of time that a specialization <i>could</i> block.
+ *
+ * @param timeout - maximum amount of time (milliseconds) this method could block
+ *
+ * @return
+ * - <em>true</em> if the operation completes and the Lockable is acquired before
+ * the timeout expires.
+ * - <em>false</em> if the operation times out before the Lockable can be acquired.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted before
+ * the operation completes.
+ *
+ * @post The Lockable is acquired only if no exception was thrown.
+ */
+ virtual bool tryAcquire(unsigned long timeout) = 0;
+
+ /**
+ * Release the Lockable object.
+ *
+ * This method may or may not block the caller for an indefinite amount
+ * of time. Those details are defined by specializations of this class.
+ *
+ * @post The Lockable is released only if no exception was thrown.
+ */
+ virtual void release() = 0;
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTLOCKABLE_H__
diff --git a/dep/include/zthread/LockedQueue.h b/dep/include/zthread/LockedQueue.h
new file mode 100644
index 00000000000..a1f0df26431
--- /dev/null
+++ b/dep/include/zthread/LockedQueue.h
@@ -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.
+ *
+ */
+
+#ifndef __ZTLOCKEDQUEUE_H__
+#define __ZTLOCKEDQUEUE_H__
+
+#include "zthread/Guard.h"
+#include "zthread/Queue.h"
+
+#include <deque>
+
+namespace ZThread {
+
+ /**
+ * @class LockedQueue
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T11:42:33-0400>
+ * @version 2.3.0
+ *
+ * A LockedQueue is the simple Queue implementation that provides
+ * serialized access to the values added to it.
+ */
+ template <class T, class LockType, typename StorageType=std::deque<T> >
+ class LockedQueue : public Queue<T> {
+
+ //! Serialize access to the Queue
+ LockType _lock;
+
+ //! Storage backing the queue
+ StorageType _queue;
+
+ //! Cancellation flag
+ volatile bool _canceled;
+
+ public:
+
+ //! Create a LockedQueue
+ LockedQueue() : _canceled(false) {}
+
+ //! Destroy a LockedQueue
+ virtual ~LockedQueue() { }
+
+ /**
+ * @see Queue::add(const T& item)
+ */
+ virtual void add(const T& item) {
+
+ Guard<LockType> g(_lock);
+
+ if(_canceled)
+ throw Cancellation_Exception();
+
+ _queue.push_back(item);
+
+ }
+
+ /**
+ * @see Queue::add(const T& item, unsigned long timeout)
+ */
+ virtual bool add(const T& item, unsigned long timeout) {
+
+ try {
+
+ Guard<LockType> g(_lock, timeout);
+
+ if(_canceled)
+ throw Cancellation_Exception();
+
+ _queue.push_back(item);
+
+ } catch(Timeout_Exception&) { return false; }
+
+ return true;
+
+ }
+
+ /**
+ * @see Queue::next()
+ */
+ virtual T next() {
+
+ Guard<LockType> g(_lock);
+
+ if(_queue.empty() && _canceled)
+ throw Cancellation_Exception();
+
+ if(_queue.empty())
+ throw NoSuchElement_Exception();
+
+ T item = _queue.front();
+ _queue.pop_front();
+
+ return item;
+
+ }
+
+
+ /**
+ * @see Queue::next(unsigned long timeout)
+ */
+ virtual T next(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+
+ if(_queue.empty() && _canceled)
+ throw Cancellation_Exception();
+
+ if(_queue.empty())
+ throw NoSuchElement_Exception();
+
+ T item = _queue.front();
+ _queue.pop_front();
+
+ return item;
+
+ }
+
+ virtual T front()
+ {
+ Guard<LockType> g(_lock);
+
+ if(_queue.empty())
+ throw NoSuchElement_Exception();
+
+ return _queue.front();
+ }
+
+ /**
+ * @see Queue::cancel()
+ */
+ virtual void cancel() {
+
+ Guard<LockType> g(_lock);
+
+ _canceled = true;
+
+ }
+
+ /**
+ * @see Queue::isCanceled()
+ */
+ virtual bool isCanceled() {
+
+ // Faster check since the queue will not become un-canceled
+ if(_canceled)
+ return true;
+
+ Guard<LockType> g(_lock);
+
+ return _canceled;
+
+ }
+
+ /**
+ * @see Queue::size()
+ */
+ virtual size_t size() {
+
+ Guard<LockType> g(_lock);
+ return _queue.size();
+
+ }
+
+ /**
+ * @see Queue::size(unsigned long timeout)
+ */
+ virtual size_t size(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+ return _queue.size();
+
+ }
+
+ }; /* LockedQueue */
+
+} // namespace ZThread
+
+#endif // __ZTLOCKEDQUEUE_H__
diff --git a/dep/include/zthread/MonitoredQueue.h b/dep/include/zthread/MonitoredQueue.h
new file mode 100644
index 00000000000..8578fe62b96
--- /dev/null
+++ b/dep/include/zthread/MonitoredQueue.h
@@ -0,0 +1,345 @@
+/*
+ * 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 __ZTMONITOREDQUEUE_H__
+#define __ZTMONITOREDQUEUE_H__
+
+#include "zthread/Condition.h"
+#include "zthread/Guard.h"
+#include "zthread/Queue.h"
+
+#include <deque>
+
+namespace ZThread {
+
+ /**
+ * @class MonitoredQueue
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T20:23:28-0400>
+ * @version 2.3.0
+ *
+ * A MonitoredQueue is a Queue implementation that provides serialized access to the
+ * items added to it.
+ *
+ * - Threads calling the empty() methods will be blocked until the BoundedQueue becomes empty.
+ * - Threads calling the next() methods will be blocked until the BoundedQueue has a value to
+ * return.
+ *
+ * @see Queue
+ */
+ template <class T, class LockType, typename StorageType=std::deque<T> >
+ class MonitoredQueue : public Queue<T>, public Lockable {
+
+ //! Serialize access
+ LockType _lock;
+
+ //! Signaled on not empty
+ Condition _notEmpty;
+
+ //! Signaled on empty
+ Condition _isEmpty;
+
+ //! Storage backing the queue
+ StorageType _queue;
+
+ //! Cancellation flag
+ volatile bool _canceled;
+
+ public:
+
+ //! Create a new MonitoredQueue
+ MonitoredQueue()
+ : _notEmpty(_lock), _isEmpty(_lock), _canceled(false) {}
+
+ //! Destroy a MonitoredQueue, delete remaining items
+ virtual ~MonitoredQueue() { }
+
+ /**
+ * Add a value to this Queue.
+ *
+ * @param item value to be added to the Queue
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Interrupted_Exception thrown if the thread was interrupted while waiting
+ * to add a value
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post If no exception is thrown, a copy of <i>item</i> will have been added to the Queue.
+ *
+ * @see Queue::add(const T& item)
+ */
+ virtual void add(const T& item) {
+
+ Guard<LockType> g(_lock);
+
+ // Allow no further additions in the canceled state
+ if(_canceled)
+ throw Cancellation_Exception();
+
+ _queue.push_back( item );
+
+ _notEmpty.signal(); // Wake one waiter
+
+ }
+
+ /**
+ * Add a value to this Queue.
+ *
+ * @param item value to be added to the Queue
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return
+ * - <em>true</em> if a copy of <i>item</i> can be added before <i>timeout</i>
+ * milliseconds elapse.
+ * - <em>false</em> otherwise.
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Interrupted_Exception thrown if the thread was interrupted while waiting
+ * to add a value
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post If no exception is thrown, a copy of <i>item</i> will have been added to the Queue.
+ *
+ * @see Queue::add(const T& item, unsigned long timeout)
+ */
+ virtual bool add(const T& item, unsigned long timeout) {
+
+ try {
+
+ Guard<LockType> g(_lock, timeout);
+
+ if(_canceled)
+ throw Cancellation_Exception();
+
+ _queue.push_back(item);
+
+ _notEmpty.signal();
+
+ } catch(Timeout_Exception&) { return false; }
+
+ return true;
+
+ }
+
+ /**
+ * Retrieve and remove a value from this Queue.
+ *
+ * If invoked when there are no values present to return then the calling thread
+ * will be blocked until a value arrives in the Queue.
+ *
+ * @return <em>T</em> next available value
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Interrupted_Exception thrown if the thread was interrupted while waiting
+ * to retrieve a value
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post The value returned will have been removed from the Queue.
+ */
+ virtual T next() {
+
+ Guard<LockType> g(_lock);
+
+ while (_queue.empty() && !_canceled)
+ _notEmpty.wait();
+
+ if(_queue.empty()) // Queue canceled
+ throw Cancellation_Exception();
+
+ T item = _queue.front();
+ _queue.pop_front();
+
+ if(_queue.empty()) // Wake empty waiters
+ _isEmpty.broadcast();
+
+ return item;
+
+ }
+
+ /**
+ * Retrieve and remove a value from this Queue.
+ *
+ * If invoked when there are no values present to return then the calling thread
+ * will be blocked until a value arrives in the Queue.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return <em>T</em> next available value
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Timeout_Exception thrown if the timeout expires before a value
+ * can be retrieved.
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post The value returned will have been removed from the Queue.
+ */
+ virtual T next(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+
+ while(_queue.empty() && !_canceled) {
+ if(!_notEmpty.wait(timeout))
+ throw Timeout_Exception();
+ }
+
+ if( _queue.empty()) // Queue canceled
+ throw Cancellation_Exception();
+
+ T item = _queue.front();
+ _queue.pop_front();
+
+ if(_queue.empty()) // Wake empty waiters
+ _isEmpty.broadcast();
+
+ return item;
+
+ }
+
+
+ /**
+ * Cancel this queue.
+ *
+ * @post Any threads blocked by a next() function will throw a Cancellation_Exception.
+ *
+ * @see Queue::cancel()
+ */
+ virtual void cancel() {
+
+ Guard<LockType> g(_lock);
+
+ _canceled = true;
+ _notEmpty.broadcast(); // Wake next() waiters
+
+ }
+
+ /**
+ * @see Queue::isCanceled()
+ */
+ virtual bool isCanceled() {
+
+ // Faster check since the queue will not become un-canceled
+ if(_canceled)
+ return true;
+
+ Guard<LockType> g(_lock);
+
+ return _canceled;
+
+ }
+
+
+ /**
+ * @see Queue::size()
+ */
+ virtual size_t size() {
+
+ Guard<LockType> g(_lock);
+ return _queue.size();
+
+ }
+
+ /**
+ * @see Queue::size(unsigned long timeout)
+ */
+ virtual size_t size(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+ return _queue.size();
+
+ }
+
+ /**
+ * Test whether any values are available in this Queue.
+ *
+ * The calling thread is blocked until there are no values present
+ * in the Queue.
+ *
+ * @return
+ * - <em>true</em> if there are no values available.
+ * - <em>false</em> if there <i>are</i> values available.
+ *
+ * @see Queue::empty()
+ */
+ virtual bool empty() {
+
+ Guard<LockType> g(_lock);
+
+ while(!_queue.empty()) // Wait for an empty signal
+ _isEmpty.wait();
+
+ return true;
+
+ }
+
+ /**
+ * Test whether any values are available in this Queue.
+ *
+ * The calling thread is blocked until there are no values present
+ * in the Queue.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return
+ * - <em>true</em> if there are no values available.
+ * - <em>false</em> if there <i>are</i> values available.
+ *
+ * @exception Timeout_Exception thrown if <i>timeout</i> milliseconds
+ * expire before a value becomes available
+ *
+ * @see Queue::empty()
+ */
+ virtual bool empty(unsigned long timeout) {
+
+ Guard<LockType> g(_lock, timeout);
+
+ while(!_queue.empty()) // Wait for an empty signal
+ _isEmpty.wait(timeout);
+
+ return true;
+
+ }
+
+ public:
+
+ virtual void acquire() {
+ _lock.acquire();
+ }
+
+ virtual bool tryAcquire(unsigned long timeout) {
+ return _lock.tryAcquire(timeout);
+ }
+
+ virtual void release() {
+ _lock.release();
+ }
+
+
+ }; /* MonitoredQueue */
+
+
+} // namespace ZThread
+
+#endif // __ZTMONITOREDQUEUE_H__
+
diff --git a/dep/include/zthread/Mutex.h b/dep/include/zthread/Mutex.h
new file mode 100644
index 00000000000..1b521b1598d
--- /dev/null
+++ b/dep/include/zthread/Mutex.h
@@ -0,0 +1,135 @@
+/*
+ * 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 __ZTMUTEX_H__
+#define __ZTMUTEX_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class FifoMutexImpl;
+
+ /**
+ * @class Mutex
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T19:35:28-0400>
+ * @version 2.2.1
+ *
+ * A Mutex is used to provide serialized (one thread at a time) access to some portion
+ * of code. This is accomplished by attempting to acquire the Mutex before entering that
+ * piece of code, and by releasing the Mutex when leaving that region. It is a non-reentrant,
+ * MUTual EXclusion Lockable object.
+ *
+ * @see Guard
+ *
+ * <b>Scheduling</b>
+ *
+ * Threads competing to acquire() a Mutex are granted access in FIFO order.
+ *
+ * <b>Error Checking</b>
+ *
+ * A Mutex will throw a Deadlock_Exception if an attempt to acquire a Mutex more
+ * than once is made from the context of the same thread.
+ *
+ * A Mutex will throw an InvalidOp_Exception if an attempt to release a Mutex is
+ * made from the context of a thread that does not currently own that Mutex.
+ */
+ class ZTHREAD_API Mutex : public Lockable, private NonCopyable {
+
+ FifoMutexImpl* _impl;
+
+ public:
+
+ //! Create a new Mutex.
+ Mutex();
+
+ //! Destroy this Mutex.
+ virtual ~Mutex();
+
+ /**
+ * Acquire a Mutex, possibly blocking until either the current owner of the
+ * Mutex releases it or until an exception is thrown.
+ *
+ * Only one thread may acquire() the Mutex at any given time.
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ * @exception Deadlock_Exception thrown when the same thread attempts to acquire
+ * a Mutex more than once, without having first release()ed it.
+ *
+ * @pre the calling thread must not have already acquired Mutex
+ *
+ * @post the calling thread successfully acquired Mutex only if no exception
+ * was thrown.
+ *
+ * @see Lockable::acquire()
+ */
+ virtual void acquire();
+
+ /**
+ * Acquire a Mutex, possibly blocking until the current owner of the
+ * Mutex releases it, until an exception is thrown or until the given amount
+ * of time expires.
+ *
+ * Only one thread may acquire the Mutex at any given time.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method could block
+ * @return
+ * - <em>true</em> if the lock was acquired
+ * - <em>false</em> if the lock was acquired
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ * @exception Deadlock_Exception thrown when the same thread attempts to acquire
+ * a Mutex more than once, without having first released it.
+ *
+ * @pre the calling thread must not have already acquired Mutex
+ *
+ * @post the calling thread successfully acquired Mutex only if no exception
+ * was thrown.
+ *
+ * @see Lockable::tryAcquire(unsigned long timeout)
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+ /**
+ * Release a Mutex allowing another thread to acquire it.
+ *
+ * @exception InvalidOp_Exception - thrown if there is an attempt to release is
+ * a Mutex that was not owner by the calling thread.
+ *
+ * @pre the calling thread must have first acquired the Mutex.
+ * @post the calling thread successfully released Mutex only if no exception
+ * was thrown.
+ *
+ * @see Lockable::release()
+ */
+ virtual void release();
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTMUTEX_H__
diff --git a/dep/include/zthread/NonCopyable.h b/dep/include/zthread/NonCopyable.h
new file mode 100644
index 00000000000..5c33f345f46
--- /dev/null
+++ b/dep/include/zthread/NonCopyable.h
@@ -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 __ZTNONCOPYABLE_H__
+#define __ZTNONCOPYABLE_H__
+
+namespace ZThread {
+
+ /**
+ * @class NonCopyable
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T19:36:00-0400>
+ * @version 2.2.11
+ *
+ * Some objects kind of objects should not be copied. This is particularly true
+ * of objects involved in providing mutually exclusive access to something
+ * (e.g. Mutexes, Queues, Semaphores, etc.)
+ *
+ * Based on Dave Abrahams contribution to the Boost library.
+ */
+ class NonCopyable {
+
+ //! Restrict the copy constructor
+ NonCopyable(const NonCopyable&);
+
+ //! Restrict the assignment operator
+ const NonCopyable& operator=(const NonCopyable&);
+
+ protected:
+
+ //! Create a NonCopyable object
+ NonCopyable() { }
+
+ //! Destroy a NonCopyable object
+ ~NonCopyable() { }
+
+ }; /* NonCopyable */
+
+} // namespace ZThread
+
+#endif // __ZTNONCOPYABLE_H__
diff --git a/dep/include/zthread/PoolExecutor.h b/dep/include/zthread/PoolExecutor.h
new file mode 100644
index 00000000000..82f5c4f05ba
--- /dev/null
+++ b/dep/include/zthread/PoolExecutor.h
@@ -0,0 +1,178 @@
+/*
+ * 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 __ZTPOOLEXECUTOR_H__
+#define __ZTPOOLEXECUTOR_H__
+
+#include "zthread/Executor.h"
+#include "zthread/CountedPtr.h"
+#include "zthread/Thread.h"
+
+namespace ZThread {
+
+ namespace { class ExecutorImpl; }
+
+ /**
+ * @class PoolExecutor
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T22:41:07-0400>
+ * @version 2.3.0
+ *
+ * A PoolExecutor spawns a set of threads that are used to run tasks
+ * that are submitted in parallel. A PoolExecutor supports the following
+ * optional operations,
+ *
+ * - <em>cancel</em>()ing a PoolExecutor will cause it to stop accepting
+ * new tasks.
+ *
+ * - <em>interrupt</em>()ing a PoolExecutor will cause the any thread running
+ * a task which was submitted prior to the invocation of this function to
+ * be interrupted during the execution of that task.
+ *
+ * - <em>wait</em>()ing on a PoolExecutor will block the calling thread
+ * until all tasks that were submitted prior to the invocation of this function
+ * have completed.
+ *
+ * @see Executor.
+ */
+ class PoolExecutor : public Executor {
+
+ //! Reference to the internal implementation
+ CountedPtr< ExecutorImpl > _impl;
+
+ //! Cancellation task
+ Task _shutdown;
+
+ public:
+
+ /**
+ * Create a PoolExecutor
+ *
+ * @param n number of threads to service tasks with
+ */
+ PoolExecutor(size_t n);
+
+ //! Destroy a PoolExecutor
+ virtual ~PoolExecutor();
+
+ /**
+ * Invoking this function causes each task that had been submitted prior to
+ * this function to be interrupted. Tasks submitted after the invocation of
+ * this function are unaffected.
+ *
+ * @post Any task submitted prior to the invocation of this function will be
+ * run in the context of an interrupted thread.
+ * @post Any thread already executing a task which was submitted prior to the
+ * invocation of this function will be interrupted.
+ */
+ virtual void interrupt();
+
+ /**
+ * Alter the number of threads being used to execute submitted tasks.
+ *
+ * @param n number of worker threads.
+ *
+ * @pre <i>n</i> must be greater than 0.
+ * @post <i>n</i> threads will be executing tasks submitted to this executor.
+ *
+ * @exception InvalidOp_Exception thrown if the new number of threads
+ * <i>n</i> is less than 1.
+ */
+ void size(size_t n);
+
+ /**
+ * Get the current number of threads being used to execute submitted tasks.
+ *
+ * @return n number of worker threads.
+ */
+ size_t size();
+
+ /**
+ * Submit a task to this Executor.
+ *
+ * This will not block the calling thread very long. The submitted task will
+ * be executed at some later point by another thread.
+ *
+ * @param task Task to be run by a thread managed by this executor
+ *
+ * @pre The Executor should have been canceled prior to this invocation.
+ * @post The submitted task will be run at some point in the future by this Executor.
+ *
+ * @exception Cancellation_Exception thrown if the Executor was canceled prior to
+ * the invocation of this function.
+ *
+ * @see PoolExecutor::cancel()
+ * @see Executor::execute(const Task& task)
+ */
+ virtual void execute(const Task& task);
+
+ /**
+ * @see Cancelable::cancel()
+ */
+ virtual void cancel();
+
+ /**
+ * @see Cancelable::isCanceled()
+ */
+ virtual bool isCanceled();
+
+ /**
+ * Block the calling thread until all tasks submitted prior to this invocation
+ * complete.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted
+ * before the set of tasks being wait for can complete.
+ *
+ * @see Waitable::wait()
+ */
+ virtual void wait();
+
+ /**
+ * Block the calling thread until all tasks submitted prior to this invocation
+ * complete or until the calling thread is interrupted.
+ *
+ * @param timeout maximum amount of time, in milliseconds, to wait for the
+ * currently submitted set of Tasks to complete.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted
+ * before the set of tasks being wait for can complete.
+ *
+ * @return
+ * - <em>true</em> if the set of tasks being wait for complete before
+ * <i>timeout</i> milliseconds elapse.
+ * - <em>false</em> otherwise.
+ *
+ * @see Waitable::wait(unsigned long timeout)
+ */
+ virtual bool wait(unsigned long timeout);
+
+ }; /* PoolExecutor */
+
+
+} // namespace ZThread
+
+#endif // __ZTPOOLEXECUTOR_H__
+
+
+
+
diff --git a/dep/include/zthread/Priority.h b/dep/include/zthread/Priority.h
new file mode 100644
index 00000000000..907d1f153a8
--- /dev/null
+++ b/dep/include/zthread/Priority.h
@@ -0,0 +1,39 @@
+/*
+ * 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 __ZTPRIORITY_H__
+#define __ZTPRIORITY_H__
+
+namespace ZThread {
+
+ //! Priorities
+ typedef enum {
+
+ Low,
+ Medium = Low + 1,
+ High = Low + 2
+
+ } Priority;
+
+}
+
+#endif // __ZTPRIORITY_H__
diff --git a/dep/include/zthread/PriorityCondition.h b/dep/include/zthread/PriorityCondition.h
new file mode 100644
index 00000000000..1fd86c41c11
--- /dev/null
+++ b/dep/include/zthread/PriorityCondition.h
@@ -0,0 +1,89 @@
+/*
+ * 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 __ZTPRIORITYCONDITION_H__
+#define __ZTPRIORITYCONDITION_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+#include "zthread/Waitable.h"
+
+namespace ZThread {
+
+ class PriorityConditionImpl;
+
+ /**
+ * @class PriorityCondition
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:35:28-0400>
+ * @version 2.2.1
+ *
+ * A PriorityCondition is a Condition that is sensitive to thread priority.
+ *
+ * @see Condition
+ *
+ * <b>Scheduling</b>
+ *
+ * Threads blocked on a PriorityCondition are resumed in priority order, highest priority
+ * first
+ */
+ class ZTHREAD_API PriorityCondition : public Waitable, private NonCopyable {
+
+ PriorityConditionImpl* _impl;
+
+ public:
+
+ /**
+ * @see Condition::Condition(Lockable& l)
+ */
+ PriorityCondition(Lockable& l);
+
+ /**
+ * @see Condition::~Condition()
+ */
+ ~PriorityCondition();
+
+ /**
+ * @see Condition::signal()
+ */
+ void signal();
+
+ /**
+ * @see Condition::broadcast()
+ */
+ void broadcast();
+
+ /**
+ * @see Condition::wait()
+ */
+ virtual void wait();
+
+ /**
+ * @see Condition::wait(unsigned long timeout)
+ */
+ virtual bool wait(unsigned long timeout);
+
+ };
+
+} // namespace ZThread
+
+#endif // __ZTPRIORITYCONDITION_H__
diff --git a/dep/include/zthread/PriorityInheritanceMutex.h b/dep/include/zthread/PriorityInheritanceMutex.h
new file mode 100644
index 00000000000..1a5f5bfd300
--- /dev/null
+++ b/dep/include/zthread/PriorityInheritanceMutex.h
@@ -0,0 +1,93 @@
+/*
+ * 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 __ZTPRIORITYINHERITANCEMUTEX_H__
+#define __ZTPRIORITYINHERITANCEMUTEX_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class PriorityInheritanceMutexImpl;
+
+ /**
+ * @class PriorityInheritanceMutex
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T19:37:36-0400>
+ * @version 2.2.1
+ *
+ * A PriorityInheritanceMutex is similar to a PriorityMutex, it is a non-reentrant,
+ * priority sensitive MUTual EXclusion Lockable object. It differs only in its
+ * scheduling policy.
+ *
+ * @see PriorityMutex
+ *
+ * <b>Scheduling</b>
+ *
+ * Threads competing to acquire() a PriorityInheritanceMutex are granted access in
+ * order of priority. Threads with a higher priority will be given access first.
+ *
+ * When a higher priority thread tries to acquire() a PriorityInheritanceMutex and is
+ * about to be blocked by a lower priority thread that has already acquire()d it, the
+ * lower priority thread will temporarily have its effective priority raised to that
+ * of the higher priority thread until it release()s the mutex; at which point its
+ * previous priority will be restored.
+ */
+ class ZTHREAD_API PriorityInheritanceMutex : public Lockable, private NonCopyable {
+
+ PriorityInheritanceMutexImpl* _impl;
+
+ public:
+
+ /**
+ * @see Mutex::Mutex()
+ */
+ PriorityInheritanceMutex();
+
+ /**
+ * @see Mutex::~Mutex()
+ */
+ virtual ~PriorityInheritanceMutex();
+
+ /**
+ * @see Mutex::acquire()
+ */
+ virtual void acquire();
+
+ /**
+ * @see Mutex::tryAcquire(unsigned long timeout)
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+ /**
+ * @see Mutex::release()
+ */
+ virtual void release();
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTPRIORITYINHERITANCEMUTEX_H__
diff --git a/dep/include/zthread/PriorityMutex.h b/dep/include/zthread/PriorityMutex.h
new file mode 100644
index 00000000000..477c8d9fd4d
--- /dev/null
+++ b/dep/include/zthread/PriorityMutex.h
@@ -0,0 +1,86 @@
+/*
+ * 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 __ZTPRIORITYMUTEX_H__
+#define __ZTPRIORITYMUTEX_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class PriorityMutexImpl;
+
+ /**
+ * @class PriorityMutex
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:35:46-0400>
+ * @version 2.2.1
+ *
+ * A PriorityMutex is similar to a Mutex, with exception that a PriorityMutex
+ * has a difference scheduling policy. It is a non-reentrant, priority sensitive
+ * MUTual EXclusion Lockable object.
+ *
+ * @see Mutex
+ *
+ * <b>Scheduling</b>
+ *
+ * Threads competing to acquire() a Mutex are granted access in order of priority. Threads
+ * with a higher priority will be given access first.
+ */
+ class ZTHREAD_API PriorityMutex : public Lockable, private NonCopyable {
+
+ PriorityMutexImpl* _impl;
+
+ public:
+
+ /**
+ * @see Mutex::Mutex()
+ */
+ PriorityMutex();
+
+ /**
+ * @see Mutex::~Mutex()
+ */
+ virtual ~PriorityMutex();
+
+ /**
+ * @see Mutex::acquire()
+ */
+ virtual void acquire();
+
+ /**
+ * @see Mutex::tryAcquire(unsigned long timeout)
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+ /**
+ * @see Mutex::release()
+ */
+ virtual void release();
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTPRIORITYMUTEX_H__
diff --git a/dep/include/zthread/PrioritySemaphore.h b/dep/include/zthread/PrioritySemaphore.h
new file mode 100644
index 00000000000..54ef2c48c52
--- /dev/null
+++ b/dep/include/zthread/PrioritySemaphore.h
@@ -0,0 +1,111 @@
+/*
+ * 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 __ZTPRIORITYSEMAPHORE_H__
+#define __ZTPRIORITYSEMAPHORE_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class PrioritySemaphoreImpl;
+
+ /**
+ * @class PrioritySemaphore
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T15:36:07-0400>
+ * @version 2.2.1
+ *
+ * A PrioritySemaphore operates in the same way as a Semaphore. Its an owner-less
+ * Lockable object that is sensitive to priority.
+ *
+ * <b>Scheduling</b>
+ *
+ * Threads blocked on a PrioritySemaphore are resumed in priority order, highest
+ * priority first.
+ *
+ * <b>Error Checking</b>
+ *
+ * An attempt to increase a PrioritySemaphore beyond its maximum value will result in
+ * an InvalidOp_Exception.
+ *
+ * @see Semaphore
+ */
+ class ZTHREAD_API PrioritySemaphore : public Lockable, private NonCopyable {
+
+ PrioritySemaphoreImpl* _impl;
+
+ public:
+
+ /**
+ * @see Semaphore::Semaphore(int count, unsigned int maxCount)
+ */
+ PrioritySemaphore(int count = 1, unsigned int maxCount = 1);
+
+ /**
+ * @see Semaphore::~Semaphore()
+ */
+ virtual ~PrioritySemaphore();
+
+ /**
+ * @see Semaphore::wait()
+ */
+ void wait();
+
+ /**
+ * @see Semaphore::tryWait(unsigned long)
+ */
+ bool tryWait(unsigned long);
+
+ /**
+ * @see Semaphore::post()
+ */
+ void post();
+
+ /**
+ * @see Semaphore::count()
+ */
+ virtual int count();
+
+ /**
+ * @see Semaphore::tryAcquire(unsigned long timeout)
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+ /**
+ * @see Semaphore::acquire()
+ */
+ virtual void acquire();
+
+ /**
+ * @see Semaphore::release()
+ */
+ virtual void release();
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTPRIORITYSEMAPHORE_H__
diff --git a/dep/include/zthread/Queue.h b/dep/include/zthread/Queue.h
new file mode 100644
index 00000000000..98b83a10c63
--- /dev/null
+++ b/dep/include/zthread/Queue.h
@@ -0,0 +1,189 @@
+/*
+ * 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 __ZTQUEUE_H__
+#define __ZTQUEUE_H__
+
+#include "zthread/Cancelable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ /**
+ * @class Queue
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T11:32:42-0400>
+ * @version 2.3.0
+ *
+ * A Queue defines an interface for a value-oriented collection objects (similar to
+ * STL collections).
+ */
+ template <typename T>
+ class Queue : public Cancelable, private NonCopyable {
+ public:
+
+ //! Destroy a Queue
+ virtual ~Queue() { }
+
+ /**
+ * Add an object to this Queue.
+ *
+ * @param item value to be added to the Queue
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post If no exception is thrown, a copy of <i>item</i> will have been added to the Queue.
+ */
+ virtual void add(const T& item) = 0;
+
+ /**
+ * Add an object to this Queue.
+ *
+ * @param item value to be added to the Queue
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return
+ * - <em>true</em> if a copy of <i>item</i> can be added before <i>timeout</i>
+ * milliseconds elapse.
+ * - <em>false</em> otherwise.
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post If this function returns true a copy of <i>item</i> will have been added to the Queue.
+ */
+ virtual bool add(const T& item, unsigned long timeout) = 0;
+
+ /**
+ * Retrieve and remove a value from this Queue.
+ *
+ * @return <em>T</em> next available value
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post The value returned will have been removed from the Queue.
+ */
+ virtual T next() = 0;
+
+ /**
+ * Retrieve and remove a value from this Queue.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return <em>T</em> next available value
+ *
+ * @exception Cancellation_Exception thrown if this Queue has been canceled.
+ * @exception Timeout_Exception thrown if the timeout expires before a value
+ * can be retrieved.
+ *
+ * @pre The Queue should not have been canceled prior to the invocation of this function.
+ * @post The value returned will have been removed from the Queue.
+ */
+ virtual T next(unsigned long timeout) = 0;
+
+ /**
+ * Canceling a Queue disables it, disallowing further additions. Values already
+ * present in the Queue can still be retrieved and are still available through
+ * the next() methods.
+ *
+ * Canceling a Queue more than once has no effect.
+ *
+ * @post The next() methods will continue to return objects until
+ * the Queue has been emptied.
+ * @post Once emptied, the next() methods will throw a Cancellation_Exception.
+ * @post The add() methods will throw a Cancellation_Exceptions from this point on.
+ */
+ virtual void cancel() = 0;
+
+ /**
+ * Count the values present in this Queue.
+ *
+ * @return <em>size_t</em> number of elements available in the Queue.
+ */
+ virtual size_t size() = 0;
+
+ /**
+ * Count the values present in this Queue.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return <em>size_t</em> number of elements available in the Queue.
+ *
+ * @exception Timeout_Exception thrown if <i>timeout</i> milliseconds
+ * expire before a value becomes available
+ */
+ virtual size_t size(unsigned long timeout) = 0;
+
+ /**
+ * Test whether any values are available in this Queue.
+ *
+ * @return
+ * - <em>true</em> if there are no values available.
+ * - <em>false</em> if there <i>are</i> values available.
+ */
+ virtual bool empty() {
+
+ try {
+
+ return size() == 0;
+
+ } catch(Cancellation_Exception&) { }
+
+ return true;
+
+ }
+
+ /**
+ * Test whether any values are available in this Queue.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method may block
+ * the calling thread.
+ *
+ * @return
+ * - <em>true</em> if there are no values available.
+ * - <em>false</em> if there <i>are</i> values available.
+ *
+ * @exception Timeout_Exception thrown if <i>timeout</i> milliseconds
+ * expire before a value becomes available
+ */
+ virtual bool empty(unsigned long timeout) {
+
+ try {
+
+ return size(timeout) == 0;
+
+ } catch(Cancellation_Exception&) { }
+
+ return true;
+
+ }
+
+ }; /* Queue */
+
+} // namespace ZThread
+
+#endif // __ZTQUEUE_H__
diff --git a/dep/include/zthread/ReadWriteLock.h b/dep/include/zthread/ReadWriteLock.h
new file mode 100644
index 00000000000..e01643f1993
--- /dev/null
+++ b/dep/include/zthread/ReadWriteLock.h
@@ -0,0 +1,80 @@
+/*
+ * 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 __ZTREADWRITELOCK_H__
+#define __ZTREADWRITELOCK_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ /**
+ * @class ReadWriteLock
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T10:17:31-0400>
+ * @version 2.2.7
+ *
+ * A ReadWriteLock provides a set of coordinated Lockable objects that can be used to
+ * guard an object; One for read-only access, and another for read-write access.
+ *
+ * @see BiasedReadWriteLock
+ * @see FairReadWriteLock
+ */
+ class ReadWriteLock : public NonCopyable {
+ public:
+
+ /**
+ * Create a ReadWriteLock
+ *
+ * @exception Initialization_Exception thrown if resources could not be
+ * allocated for this object.
+ */
+ ReadWriteLock() {}
+
+ //! Destroy this ReadWriteLock
+ virtual ~ReadWriteLock() {}
+
+ /**
+ * Get a reference to the read-only Lockable.
+ *
+ * @return <em>Lockable&</em> reference to a Lockable that provides read-only
+ * access.
+ */
+ virtual Lockable& getReadLock() = 0;
+
+ /**
+ * Get a reference to the read-write Lockable.
+ *
+ * @return <em>Lockable&</em> reference to a Lockable that provides read-write
+ * access.
+ */
+ virtual Lockable& getWriteLock() = 0;
+
+
+ }; /* ReadWriteLock */
+
+
+}; // __ZTREADWRITELOCK_H__
+
+#endif
diff --git a/dep/include/zthread/RecursiveMutex.h b/dep/include/zthread/RecursiveMutex.h
new file mode 100644
index 00000000000..7dda9c5119b
--- /dev/null
+++ b/dep/include/zthread/RecursiveMutex.h
@@ -0,0 +1,123 @@
+/*
+ * 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 __ZTRECURSIVEMUTEX_H__
+#define __ZTRECURSIVEMUTEX_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class RecursiveMutexImpl;
+
+ /**
+ * @class RecursiveMutex
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:51:33-0400>
+ * @version 2.2.1
+ *
+ * A RecursiveMutex is a recursive, MUTual EXclusion Lockable object. It is
+ * recursive because it can be acquire()d and release()d more than once
+ * by the same thread, instead of causing a Deadlock_Exception.
+ *
+ * @see Mutex
+ * @see Guard
+ *
+ * <b>Scheduling</b>
+ *
+ * Threads competing to acquire() a Mutex are granted access in FIFO order.
+ *
+ * <b>Error Checking</b>
+ *
+ * A Mutex will throw an InvalidOp_Exception if an attempt to release() a Mutex is
+ * made from the context of a thread that does not currently own that Mutex.
+ */
+ class ZTHREAD_API RecursiveMutex : public Lockable, private NonCopyable {
+
+ RecursiveMutexImpl* _impl;
+
+ public:
+
+ //! Create a new RecursiveMutex.
+ RecursiveMutex();
+
+ //! Destroy this RecursiveMutex.
+ virtual ~RecursiveMutex();
+
+ /**
+ * Acquire a RecursiveMutex, possibly blocking until the the current owner of the
+ * releases it or until an exception is thrown.
+ *
+ * Only one thread may acquire the RecursiveMutex at any given time.
+ * The same thread may acquire a RecursiveMutex multiple times.
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ *
+ * @post the calling thread successfully acquire ed RecursiveMutex only if no exception
+ * was thrown.
+ *
+ * @see Lockable::acquire()
+ */
+ virtual void acquire();
+
+ /**
+ * Acquire a RecursiveMutex, possibly blocking until the the current owner
+ * releases it, until an exception is thrown or until the given amount
+ * of time expires.
+ *
+ * Only one thread may acquire the RecursiveMutex at any given time.
+ * The same thread may acquire a RecursiveMutex multiple times.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method could block
+ * @return
+ * - <em>true</em> if the lock was acquired
+ * - <em>false</em> if the lock was acquired
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ *
+ * @post the calling thread successfully acquired RecursiveMutex only if no exception
+ * was thrown.
+ *
+ * @see Lockable::tryAcquire(unsigned long timeout)
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+
+ /**
+ * Release exclusive access. No safety or state checks are performed.
+ *
+ * @pre This should not be called more times than the acquire() method was
+ * called.
+ *
+ * @see Lockable::release()
+ */
+ virtual void release();
+
+ };
+
+} // namespace ZThread
+
+#endif // __ZTRECURSIVEMUTEX_H__
diff --git a/dep/include/zthread/Runnable.h b/dep/include/zthread/Runnable.h
new file mode 100644
index 00000000000..98628530a14
--- /dev/null
+++ b/dep/include/zthread/Runnable.h
@@ -0,0 +1,58 @@
+/*
+ * 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 __ZTRUNNABLE_H__
+#define __ZTRUNNABLE_H__
+
+#include "zthread/Config.h"
+
+namespace ZThread {
+
+ /**
+ * @class Runnable
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:45:35-0400>
+ * @version 2.2.11
+ *
+ * Encapsulates a Runnable task.
+ */
+ class Runnable {
+ public:
+
+ /**
+ * Runnables should never throw in their destructors
+ */
+ virtual ~Runnable() {}
+
+ /**
+ * Task to be performed in another thread of execution
+ */
+ virtual void run() = 0;
+
+ };
+
+
+}
+
+#endif // __ZTRUNNABLE_H__
diff --git a/dep/include/zthread/Semaphore.h b/dep/include/zthread/Semaphore.h
new file mode 100644
index 00000000000..2a9e4d02d03
--- /dev/null
+++ b/dep/include/zthread/Semaphore.h
@@ -0,0 +1,150 @@
+/*
+ * 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 __ZTSEMAPHORE_H__
+#define __ZTSEMAPHORE_H__
+
+#include "zthread/Lockable.h"
+#include "zthread/NonCopyable.h"
+
+namespace ZThread {
+
+ class FifoSemaphoreImpl;
+
+ /**
+ * @class Semaphore
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T15:28:01-0400>
+ * @version 2.2.1
+ *
+ * A Semaphore is an owner-less Lockable object. Its probably best described as
+ * a set of 'permits'. A Semaphore is initialized with an initial count and
+ * a maximum count, these would correspond to the number of 'permits' currently
+ * available and the number of' permits' in total.
+ *
+ * - Acquiring the Semaphore means taking a permit, but if there are none
+ * (the count is 0) the Semaphore will block the calling thread.
+ *
+ * - Releasing the Semaphore means returning a permit, unblocking a thread
+ * waiting for one.
+ *
+ * A Semaphore with an initial value of 1 and maximum value of 1 will act as
+ * a Mutex.
+ *
+ * Threads blocked on a Semaphore are resumed in FIFO order.
+ *
+ */
+ class ZTHREAD_API Semaphore : public Lockable, private NonCopyable {
+
+ FifoSemaphoreImpl* _impl;
+
+ public:
+
+ /**
+ * Create a new Semaphore.
+ *
+ * @param count initial count
+ * @param maxCount maximum count
+ */
+ Semaphore(int count = 1, unsigned int maxCount = 1);
+
+ //! Destroy the Semaphore
+ virtual ~Semaphore();
+
+ /**
+ * <i>Provided to reflect the traditional Semaphore semantics</i>
+ *
+ * @see acquire()
+ */
+ void wait();
+
+
+ /**
+ * <i>Provided to reflect the traditional Semaphore semantics</i>
+ *
+ * @see tryAcquire(unsigned long timeout)
+ */
+ bool tryWait(unsigned long timeout);
+
+ /**
+ * <i>Provided to reflect the traditional Semaphore semantics</i>
+ *
+ * @see release()
+ */
+ void post();
+
+
+ /**
+ * Get the current count of the semaphore.
+ *
+ * This value may change immediately after this function returns to the calling thread.
+ *
+ * @return <em>int</em> count
+ */
+ virtual int count();
+
+ /**
+ * Decrement the count, blocking that calling thread if the count becomes 0 or
+ * less than 0. The calling thread will remain blocked until the count is
+ * raised above 0, an exception is thrown or the given amount of time expires.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method could block
+ *
+ * @return
+ * - <em>true</em> if the Semaphore was acquired before <i>timeout</i> milliseconds elapse.
+ * - <em>false</em> otherwise.
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ *
+ * @see Lockable::tryAcquire(unsigned long timeout)
+ */
+ virtual bool tryAcquire(unsigned long timeout);
+
+
+ /**
+ * Decrement the count, blocking that calling thread if the count becomes 0 or
+ * less than 0. The calling thread will remain blocked until the count is
+ * raised above 0 or if an exception is thrown.
+ *
+ * @exception Interrupted_Exception thrown when the calling thread is interrupted.
+ * A thread may be interrupted at any time, prematurely ending any wait.
+ *
+ * @see Lockable::acquire()
+ */
+ virtual void acquire();
+
+ /**
+ * Increment the count, unblocking one thread if count is positive.
+ *
+ * @exception InvalidOp_Exception thrown if the maximum count would be exceeded.
+ *
+ * @see Lockable::release()
+ */
+ virtual void release();
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTSEMAPHORE_H__
diff --git a/dep/include/zthread/Singleton.h b/dep/include/zthread/Singleton.h
new file mode 100644
index 00000000000..b66c9d0898a
--- /dev/null
+++ b/dep/include/zthread/Singleton.h
@@ -0,0 +1,249 @@
+/*
+ * 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 __ZTSINGLETON_H__
+#define __ZTSINGLETON_H__
+
+#include "zthread/Guard.h"
+#include "zthread/FastMutex.h"
+#include <assert.h>
+
+namespace ZThread {
+
+//
+// This policy controls how an object is instantiated
+// as well as how and when its destroyed. Phoenix-style
+// singletons are not supported easily with type of policy,
+// this is intentional since I do not believe that is in
+// the true spirit of a singleton.
+//
+// InstantiationPolicContract {
+//
+// create(pointer_type&)
+//
+// }
+
+/**
+ * @class LocalStaticInstantiation
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:57:45-0400>
+ * @version 2.2.0
+ *
+ * The LocalStaticInstantiation policy allows the creation
+ * and lifetime of an instance of a particular type
+ * to be managed using static local values. This will
+ * abide by the standard C++ rules for static objects
+ * lifetimes.
+ */
+class LocalStaticInstantiation {
+protected:
+
+ /**
+ * Create an instance of an object, using a local static. The
+ * object will be destroyed by the system.
+ *
+ * @param ptr reference to location to receive the address
+ * of the allocated object
+ */
+ template <class T>
+ static void create(T*& ptr) {
+
+ static T instance;
+ ptr = &instance;
+
+ }
+
+};
+
+//! Helper class
+template <class T>
+class StaticInstantiationHelper {
+ //! Friend class
+ friend class StaticInstantiation;
+ //! Holder
+ static T instance;
+
+ };
+
+ template <class T>
+ T StaticInstantiationHelper<T>::instance;
+
+/**
+ * @class StaticInstantiation
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:57:45-0400>
+ * @version 2.2.0
+ *
+ * The StaticInstantiation policy allows the creation
+ * and lifetime of an instance of a particular type
+ * to be managed using static instantiation. This will
+ * abide by the standard C++ rules for static objects
+ * lifetimes.
+ */
+class StaticInstantiation {
+protected:
+
+ /**
+ * Create an instance of an object using by simply allocating it statically.
+ *
+ * @param ptr reference to location to receive the address
+ * of the allocated object
+ */
+ template <class T>
+ static void create(T*& ptr) {
+ ptr = &StaticInstantiationHelper<T>::instance;
+ }
+
+};
+
+//! SingletonDestroyer
+template <class T>
+class Destroyer {
+
+ T* doomed;
+
+ public:
+
+ Destroyer(T* q) : doomed(q) {
+ assert(doomed);
+ }
+
+ ~Destroyer();
+
+};
+
+template <class T>
+Destroyer<T>::~Destroyer() {
+
+ try {
+
+ if(doomed)
+ delete doomed;
+
+ } catch(...) { }
+
+ doomed = 0;
+
+}
+
+
+/**
+ * @class LazyInstantiation
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:57:45-0400>
+ * @version 2.2.0
+ *
+ * The LazyInstantiation policy allows the creation
+ * and lifetime of an instance of a particular type
+ * to be managed using dynamic allocation and a singleton
+ * destroyer. This will abide by the standard C++ rules
+ * for static objects lifetimes.
+ */
+class LazyInstantiation {
+protected:
+
+ /**
+ * Create an instance of an object, using new, that will be
+ * destroyed when an associated Destroyer object (allocated
+ * statically) goes out of scope.
+ *
+ * @param ptr reference to location to receive the address
+ * of the allocated object
+ */
+ template <class T>
+ static void create(T*& ptr) {
+
+ ptr = new T;
+ static Destroyer<T> destroyer(ptr);
+
+ }
+
+};
+
+
+/**
+ * @class Singleton
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:57:45-0400>
+ * @version 2.2.0
+ *
+ * Based on the work of John Vlissidles in his book 'Pattern Hatching'
+ * an article by Douglas Schmidtt on double-checked locking and policy
+ * templates described by Andrei Alexandrescu.
+ *
+ * This is a thread safe wrapper for creating Singleton classes. The
+ * synchronization method and instantiation methods can be changed
+ * easily by specifying different policy implementations as the
+ * templates parameters.
+ *
+ * @code
+ *
+ * // Most common Singleton
+ * Singletion<LonesomeType>
+ *
+ * // Singleton that uses static storage
+ * Singletion<LonesomeType, StaticInstantiation>
+ *
+ * // Single-threaded singleton that uses static storage (Meyers-like)
+ * Singletion<LonesomeType, LocalStaticInstantiation, NotLocked>
+ *
+ * @endcode
+ */
+template <class T, class InstantiationPolicy=LazyInstantiation, class LockType=FastMutex>
+class Singleton : private InstantiationPolicy, private NonCopyable {
+public:
+
+ /**
+ * Provide access to the single instance through double-checked locking
+ *
+ * @return T* single instance
+ */
+ static T* instance();
+
+};
+
+template <class T, class InstantiationPolicy, class LockType>
+T* Singleton<T, InstantiationPolicy, LockType>::instance() {
+
+ // Uses local static storage to avoid static construction
+ // sequence issues. (regaring when the lock is created)
+ static T* ptr = 0;
+ static LockType lock;
+
+ if(!ptr) {
+
+ Guard<LockType, LockedScope> g(lock);
+ if(!ptr)
+ InstantiationPolicy::create(ptr);
+
+ }
+
+ return const_cast<T*>(ptr);
+
+ }
+
+
+};
+
+#endif
+
+
diff --git a/dep/include/zthread/SynchronousExecutor.h b/dep/include/zthread/SynchronousExecutor.h
new file mode 100644
index 00000000000..b6dbbef6af6
--- /dev/null
+++ b/dep/include/zthread/SynchronousExecutor.h
@@ -0,0 +1,126 @@
+/*
+ * 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 __ZTSYNCHRONOUSEXECUTOR_H__
+#define __ZTSYNCHRONOUSEXECUTOR_H__
+
+#include "zthread/Executor.h"
+#include "zthread/Guard.h"
+#include "zthread/Mutex.h"
+#include "zthread/Thread.h"
+
+namespace ZThread {
+
+ /**
+ * @class SynchronousExecutor
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T22:33:51-0400>
+ * @version 2.3.0
+ *
+ * A SynchronousExecutor is an Executor which runs tasks using the thread that
+ * submits the task. It runs tasks serially, one at a time, in the order they
+ * were submitted to the executor.
+ *
+ * @see Executor.
+ */
+ class SynchronousExecutor : public Executor {
+
+ //! Serialize access
+ Mutex _lock;
+
+ //! Cancellation flag
+ bool _canceled;
+
+ public:
+
+ //! Create a new SynchronousExecutor
+ SynchronousExecutor();
+
+ //! Destroy a SynchronousExecutor
+ virtual ~SynchronousExecutor();
+
+ /**
+ * This operation is not supported by this executor.
+ */
+ virtual void interrupt();
+
+ /**
+ * Submit a task to this Executor, blocking the calling thread until the
+ * task is executed.
+ *
+ * @param task Task to be run by a thread managed by this executor
+ *
+ * @pre The Executor should have been canceled prior to this invocation.
+ * @post The submitted task will be run at some point in the future by this Executor.
+ *
+ * @exception Cancellation_Exception thrown if the Executor was canceled prior to
+ * the invocation of this function.
+ *
+ * @see Executor::execute(const Task& task)
+ */
+ virtual void execute(const Task& task);
+
+ /**
+ * @see Cancelable::cancel()
+ */
+ virtual void cancel();
+
+ /**
+ * @see Cancelable::cancel()
+ */
+ virtual bool isCanceled();
+
+ /**
+ * Block the calling thread until all tasks submitted prior to this invocation
+ * complete.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted
+ * before the set of tasks being wait for can complete.
+ *
+ * @see Executor::wait()
+ */
+ virtual void wait();
+
+ /**
+ * Block the calling thread until all tasks submitted prior to this invocation
+ * complete or until the calling thread is interrupted.
+ *
+ * @param timeout - maximum amount of time, in milliseconds, to wait for the
+ * currently submitted set of Tasks to complete.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted
+ * before the set of tasks being wait for can complete.
+ *
+ * @return
+ * - <em>true</em> if the set of tasks being wait for complete before
+ * <i>timeout</i> milliseconds elapse.
+ * - <em>false</em> othewise.
+ */
+ virtual bool wait(unsigned long timeout);
+
+
+ }; /* SynchronousExecutor */
+
+} // namespace ZThread
+
+#endif // __ZTSYNCHRONOUSEXECUTOR_H__
diff --git a/dep/include/zthread/Task.h b/dep/include/zthread/Task.h
new file mode 100644
index 00000000000..6503be66f33
--- /dev/null
+++ b/dep/include/zthread/Task.h
@@ -0,0 +1,78 @@
+/*
+ * 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 __ZTTASK_H__
+#define __ZTTASK_H__
+
+#include "zthread/CountedPtr.h"
+#include "zthread/Runnable.h"
+
+namespace ZThread {
+
+ class ThreadImpl;
+
+ /**
+ * @class Task
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-20T05:22:38-0400>
+ * @version 2.3.0
+ *
+ * A Task provides a CountedPtr wrapper for Runnable objects.
+ * This wrapper enables an implicit conversion from a
+ * <i>Runnable*</i> to a <i>Task</i> adding some syntactic sugar
+ * to the interface.
+ */
+ class ZTHREAD_API Task : public CountedPtr<Runnable, AtomicCount> {
+ public:
+
+
+#if !defined(_MSC_VER) || (_MSC_VER > 1200)
+
+ Task(Runnable* raw)
+ : CountedPtr<Runnable, AtomicCount>(raw) { }
+
+#endif
+
+ template <typename U>
+ Task(U* raw)
+ : CountedPtr<Runnable, AtomicCount>(raw) { }
+
+ Task(const CountedPtr<Runnable, AtomicCount>& ptr)
+ : CountedPtr<Runnable, AtomicCount>(ptr) { }
+
+ template <typename U, typename V>
+ Task(const CountedPtr<U, V>& ptr)
+ : CountedPtr<Runnable, AtomicCount>(ptr) { }
+
+ void operator()() {
+ (*this)->run();
+ }
+
+ }; /* Task */
+
+} // namespace ZThread
+
+#endif // __ZTTASK_H__
+
+
+
diff --git a/dep/include/zthread/Thread.h b/dep/include/zthread/Thread.h
new file mode 100644
index 00000000000..e1700c737fa
--- /dev/null
+++ b/dep/include/zthread/Thread.h
@@ -0,0 +1,381 @@
+/*
+ * 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 __ZTTHREAD_H__
+#define __ZTTHREAD_H__
+
+#include "zthread/Cancelable.h"
+#include "zthread/Priority.h"
+#include "zthread/NonCopyable.h"
+#include "zthread/Task.h"
+#include "zthread/Waitable.h"
+
+namespace ZThread {
+
+ class ThreadImpl;
+
+ /**
+ * @class Thread
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-27T11:17:59-0400>
+ * @version 2.3.0
+ *
+ *
+ * @see Task
+ * @see Executor
+ *
+ * <h2>Examples</h2>
+ * - <a href="#ex1">Launching a task</a>
+ * - <a href="#ex2">Waiting for a task</a>
+ * - <a href="#ex3">Sharing a task</a>
+ *
+ * <h2><a name="ex1">Launching a task</a></h2>
+ *
+ * A thread is started simply by constructing a thread object and giving
+ * it a task to perform. The thread will continue to run its task, even
+ * after the Thread object used to launch the thread has gone out of scope.
+ *
+ * @code
+ * #include "zthread/Thread.h"
+ * #include <iostream>
+ *
+ * using namespace ZThread;
+ *
+ * class aRunnable : public Runnable {
+ *
+ * void run() {
+ *
+ * Thread::sleep(1000);
+ * std::cout << "Hello from another thread" << std::endl;
+ *
+ * }
+ *
+ * };
+ *
+ * int main() {
+ *
+ * try {
+ *
+ * // Implictly constructs a Task
+ * Thread t(new aRunnable);
+ *
+ * } catch(Synchronization_Exception& e) {
+ * std::cerr << e.what() << std::endl;
+ * }
+ *
+ * std::cout << "Hello from the main thread" << std::endl;
+ *
+ * // Output:
+ *
+ * // Hello from the main thread
+ * // Hello from another thread
+ *
+ * return 0;
+ *
+ * }
+ *
+ * @endcode
+ *
+ * <h2><a name="ex2">Waiting for a task</a></h2>
+ *
+ * A user can exercise some simple synchronization by waiting for a thread
+ * to complete running its task.
+ *
+ * @code
+ * #include "zthread/Thread.h"
+ * #include <iostream>
+ *
+ * using namespace ZThread;
+ *
+ * class aRunnable : public Runnable {
+ * public:
+ *
+ * void run() {
+ *
+ * Thread::sleep(1000);
+ * std::cout << "Hello from another thread" << std::endl;
+ *
+ * }
+ *
+ * };
+ *
+ * int main() {
+ *
+ * try {
+ *
+ * // Implictly constructs a Task
+ * Thread t(new aRunnable);
+ * t.wait();
+ *
+ * } catch(Synchronization_Exception& e) {
+ * std::cerr << e.what() << std::endl;
+ * }
+ *
+ * std::cout << "Hello from the main thread" << std::endl;
+ *
+ * // Output:
+ *
+ * // Hello from another thread
+ * // Hello from the main thread
+ *
+ * return 0;
+ *
+ * }
+ *
+ * @endcode
+ *
+ * <h2><a name="ex3">Sharing a task</a></h2>
+ *
+ * The same task can be shared by more than one thread. A Task is constructed
+ * from a Runnable, and that Task object is copied by value and handed off to
+ * each thread.
+ *
+ * @code
+ * #include "zthread/Thread.h"
+ * #include <iostream>
+ *
+ * using namespace ZThread;
+ *
+ * class aRunnable : public Runnable {
+ *
+ * void run() {
+ *
+ * Thread::sleep(1000);
+ * std::cout << "Hello from another thread" << std::endl;
+ *
+ * }
+ *
+ * };
+ *
+ * int main() {
+ *
+ * try {
+ *
+ * // Explictly constructs a Task
+ * Task task(new aRunnable);
+ *
+ * // Two threads created to run the same Task
+ * Thread t1(task);
+ * Thread t2(task);
+ *
+ * } catch(Synchronization_Exception& e) {
+ * std::cerr << e.what() << std::endl;
+ * }
+ *
+ * std::cout << "Hello from the main thread" << std::endl;
+ *
+ * // Output:
+ *
+ * // Hello from the main thread
+ * // Hello from another thread
+ * // Hello from another thread
+ *
+ * return 0;
+ *
+ * }
+ *
+ * @endcode
+ */
+ class ZTHREAD_API Thread
+ : public Cancelable, public Waitable, public NonCopyable {
+
+ //! Delegate
+ ThreadImpl* _impl;
+
+ public:
+
+ /**
+ * Create a Thread that represents the current thread.
+ * <em>Using the static members of Thread should be preferred over using this constructor</em>
+ */
+ Thread();
+
+ /**
+ * Create a Thread that spawns a new thread to run the given task.
+ *
+ * @param task Task to be run by a thread managed by this executor
+ * @param autoCancel flag to requestion automatic cancellation
+ *
+ * @post if the <i>autoCancel</i> flag was true, this thread will
+ * automatically be canceled when main() goes out of scope.
+ */
+ Thread(const Task&, bool autoCancel = false);
+
+ //! Destroy the Thread
+ ~Thread();
+
+ //! Comparison operator
+ bool operator==(const Thread& t) const;
+
+ //! Comparison operator
+ inline bool operator!=(const Thread& t) const {
+ return !(*this == t);
+ }
+
+ /**
+ * Wait for the thread represented by this object to complete its task.
+ * The calling thread is blocked until the thread represented by this
+ * object exits.
+ *
+ * @exception Deadlock_Exception thrown if thread attempts to join itself
+ * @exception InvalidOp_Exception thrown if the thread cannot be joined
+ * @exception Interrupted_Exception thrown if the joining thread has been interrupt()ed
+ */
+ void wait();
+
+ /**
+ * Wait for the thread represented by this object to complete its task.
+ * The calling thread is blocked until the thread represented by this
+ * object exits, or until the timeout expires.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method
+ * could block the calling thread.
+ *
+ * @return
+ * - <em>true</em> if the thread task complete before <i>timeout</i>
+ * milliseconds elapse.
+ * - <em>false</em> othewise.
+ *
+ * @exception Deadlock_Exception thrown if thread attempts to join itself
+ * @exception InvalidOp_Exception thrown if the thread cannot be joined
+ * @exception Interrupted_Exception thrown if the joining thread has been interrupt()ed
+ */
+ bool wait(unsigned long timeout);
+
+ /**
+ * Change the priority of this Thread. This will change the actual
+ * priority of the thread when the OS supports it.
+ *
+ * If there is no real priority support, it's simulated.
+ *
+ * @param p - new Priority
+ */
+ void setPriority(Priority p);
+
+ /**
+ * Get the priority of this Thread.
+ *
+ * @return Priority
+ */
+ Priority getPriority();
+
+ /**
+ * Interrupts this thread, setting the <i>interrupted</i> status of the thread.
+ * This status is cleared by one of three methods.
+ *
+ * If this thread is blocked when this method is called, the thread will
+ * abort that blocking operation with an Interrupted_Exception.
+ *
+ * - The first is by attempting an operation on a synchronization object that
+ * would normally block the calling thread; Instead of blocking the calling
+ * the calling thread, the function that would normally block will thrown an
+ * Interrupted_Exception and clear the <i>interrupted</i> status of the thread.
+ *
+ * - The second is by calling Thread::interrupted().
+ *
+ * - The third is by calling Thread::canceled().
+ *
+ * Threads already blocked by an operation on a synchronization object will abort
+ * that operation with an Interrupted_Exception, clearing the threads <i>interrupted</i>
+ * status as in the first case described above.
+ *
+ * Interrupting a thread that is no longer running will have no effect.
+ *
+ * @return
+ * - <em>true</em> if the thread was interrupted while not blocked by a wait
+ * on a synchronization object.
+ * - <em>false</em> othewise.
+ */
+ bool interrupt();
+
+ /**
+ * Tests whether the current Thread has been interrupt()ed, clearing
+ * its interruption status.
+ *
+ * @return
+ * - <em>true</em> if the Thread was interrupted.
+ * - <em>false</em> otherwise.
+ *
+ * @post The <i>interrupted</i> status of the current thread will be cleared,
+ * allowing it to perform a blocking operation on a synchronization
+ * object without throwing an exception.
+ */
+ static bool interrupted();
+
+ /**
+ * Tests whether the current Thread has been canceled, and clears the
+ * interrupted status.
+ *
+ * @return bool true only if the Thread::cancel() has been invoked.
+ */
+ static bool canceled();
+
+ /**
+ * Tests whether this thread has been canceled. If called from the context
+ * of this thread, the interrupted status is cleared.
+ *
+ * @return
+ * - <em>true</em> if the Thread was canceled.
+ * - <em>false</em> otherwise.
+ *
+ * @see Cancelable::isCanceled()
+ */
+ virtual bool isCanceled();
+
+ /**
+ * Interrupt and cancel this thread in a single operation. The thread will
+ * return <em>true</em> whenever its cancelation status is tested in the future.
+ *
+ * @exception InvalidOp_Exception thrown if a thread attempts to cancel itself
+ *
+ * @see Thread::interrupt()
+ * @see Cancelable::cancel()
+ */
+ virtual void cancel();
+
+ /**
+ * Put the currently executing thread to sleep for a given amount of
+ * time.
+ *
+ * @param timeout maximum amount of time (milliseconds) this method could block
+ *
+ * @exception Interrupted_Exception thrown if the threads sleep is interrupted
+ * before <i>timeout</i> milliseconds expire.
+ */
+ static void sleep(unsigned long timeout);
+
+ /**
+ * Cause the currently executing thread to yield, allowing the scheduler
+ * to assign some execution time to another thread.
+ */
+ static void yield();
+
+
+ }; /* Thread */
+
+
+} // namespace ZThread
+
+#endif // __ZTTHREAD_H__
+
+
+
diff --git a/dep/include/zthread/ThreadLocal.h b/dep/include/zthread/ThreadLocal.h
new file mode 100644
index 00000000000..bb83a0fe3ef
--- /dev/null
+++ b/dep/include/zthread/ThreadLocal.h
@@ -0,0 +1,382 @@
+/*
+ * 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 __ZTTHREADLOCAL_H__
+#define __ZTTHREADLOCAL_H__
+
+#include "zthread/ThreadLocalImpl.h"
+
+namespace ZThread {
+
+ /**
+ * @class ThreadLocal
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-27T11:18:21-0400>
+ * @version 2.3.0
+ *
+ * Provides access to store and retrieve value types to and from a thread local
+ * storage context. A thread local storage context consists of the calling thread
+ * a specific ThreadLocal object. Since this context is specific to each thread
+ * whenever a value is stored in a ThreadLocal that is accessible from multiple
+ * threads, it can only be retrieved by the thread that stored it.
+ *
+ * The first time a thread accesses the value associated with a thread local storage
+ * context, a value is created. That value is either an initial value (determined by
+ * InitialValueT) or an inherited value (determined by ChildValueT).
+ *
+ * - If a threads parent had no value associated with a ThreadLocal when the thread was created,
+ * then the InitialValueT functor is used to create an initial value.
+ *
+ * - If a threads parent did have a value associated with a ThreadLocal when the thread was
+ * created, then the childValueT functor is used to create an initial value.
+ *
+ * Not all ThreadLocal's support the inheritance of values from parent threads. The default
+ * behavoir is to create values through the InitialValueT functor for all thread when
+ * they first access a thread local storage context.
+ *
+ * - Inheritance is enabled automatically when a user supplies a ChildValueT functor other
+ * than the default one supplied.
+ *
+ * - Inheritance can be controlled explicitly by the user through a third functor,
+ * InheritableValueT.
+ *
+ * <h2>Examples</h2>
+ *
+ * - <a href="#ex1">Default initial value</a>
+ * - <a href="#ex2">User-specified initial value</a>
+ * - <a href="#ex3">User-specified inherited value</a>
+ *
+ * <h2><a name="ex1">Default initial value</a></h2>
+ * A ThreadLocal that does not inherit, and uses the default value
+ * for an int as its initial value.
+ *
+ * @code
+ *
+ * #include "zthread/ThreadLocal.h"
+ * #include "zthread/Thread.h"
+ * #include <iostream>
+ *
+ * using namespace ZThread;
+ *
+ * class aRunnable : public Runnable {
+ * ThreadLocal<int> localValue;
+ * public:
+ * void run() {
+ * std::cout << localValue.get() << std::endl;
+ * }
+ * };
+ *
+ * int main() {
+ *
+ * // Create a shared task to display ThreadLocal values
+ * Task task(new aRunnable);
+ *
+ * Thread t0(task); t0.wait();
+ * Thread t1(task); t1.wait();
+ * Thread t2(task); t2.wait();
+ *
+ * // Output:
+ *
+ * // 0
+ * // 0
+ * // 0
+ *
+ * return 0;
+ *
+ * }
+ *
+ * @endcode
+ *
+ * <h2><a name="ex2">User-specified initial value</a></h2>
+ * A ThreadLocal that does not inherit, and uses a custom initial value.
+ *
+ * @code
+ *
+ * #include "zthread/ThreadLocal.h"
+ * #include "zthread/Thread.h"
+ * #include <iostream>
+ *
+ * using namespace ZThread;
+ *
+ * struct anInitialValueFn {
+ * int operator()() {
+ * static int next = 100;
+ * int val = next; next += 100;
+ * return val;
+ * }
+ * };
+ *
+ * class aRunnable : public Runnable {
+ * ThreadLocal<int, anInitialValueFn> localValue;
+ * public:
+ * void run() {
+ * std::cout << localValue.get() << std::endl;
+ * }
+ * };
+ *
+ * int main() {
+ *
+ * // Create a shared task to display ThreadLocal values
+ * Task task(new aRunnable);
+ *
+ * Thread t0(task); t0.wait();
+ * Thread t1(task); t1.wait();
+ * Thread t2(task); t2.wait();
+ *
+ * // Output:
+ *
+ * // 100
+ * // 200
+ * // 300
+ *
+ * return 0;
+ *
+ * }
+ *
+ * @endcode
+ *
+ * <h2><a name="ex3">User-specified inherited value</a></h2>
+ * A ThreadLocal that does inherit and modify child values.
+ * (The default initial value functor is used)
+ *
+ * @code
+ *
+ * #include "zthread/ThreadLocal.h"
+ * #include "zthread/Thread.h"
+ * #include <iostream>
+ *
+ * using namespace ZThread;
+ *
+ * struct anInheritedValueFn {
+ * int operator()(int val) {
+ * return val + 100;
+ * }
+ * };
+ *
+ * // This Runnable associates no ThreadLocal value in the main thread; so
+ * // none of the child threads have anything to inherit.
+ * class aRunnable : public Runnable {
+ * ThreadLocal<int, ThreadLocalImpl::InitialValueFn<int>, anInheritedValueFn> localValue;
+ * public:
+ * void run() {
+ * std::cout << localValue.get() << std::endl;
+ * }
+ * };
+ *
+ * // This Runnable associates a ThreadLocal value in the main thread which
+ * // is inherited when the child threads are created.
+ * class anotherRunnable : public Runnable {
+ * ThreadLocal<int, ThreadLocalImpl::InitialValueFn<int>, anInheritedValueFn> localValue;
+ * public:
+ * anotherRunnable() {
+ * localValue.set(100);
+ * }
+ * void run() {
+ * std::cout << localValue.get() << std::endl;
+ * }
+ * };
+ *
+ * int main() {
+ *
+ * // Create a shared task to display ThreadLocal values
+ * Task task(new aRunnable);
+ *
+ * Thread t0(task); t0.wait();
+ * Thread t1(task); t1.wait();
+ * Thread t2(task); t2.wait();
+ *
+ * // Output:
+ *
+ * // 0
+ * // 0
+ * // 0
+ *
+ * task = Task(new anotherRunnable);
+ *
+ * Thread t10(task); t10.wait();
+ * Thread t11(task); t11.wait();
+ * Thread t12(task); t12.wait();
+ *
+ * // Output:
+ *
+ * // 200
+ * // 200
+ * // 200
+ *
+ * return 0;
+ *
+ * }
+ *
+ * @endcode
+ *
+ * <h2>Parameters</h2>
+ *
+ * <em>InitialValueT</em>
+ *
+ * This template parameter should indicate the functor used to set
+ * the initial value. It should support the following operator:
+ *
+ * <code>
+ * // required operator
+ * T operator()
+ *
+ * // supported expression
+ * InitialValueT()()
+ * </code>
+ *
+ *
+ * <em>ChildValueT</em>
+ *
+ * This template parameter should indicate the functor used to set
+ * the value that will be inherited by thread whose parent have associated
+ * a value with the ThreadLocal's context at the time they are created.
+ * It should support the following operator:
+ *
+ * <code>
+ * // required operator
+ * T operator(const T& parentValue)
+ *
+ * // supported expression
+ * ChildValueT()(parentValue)
+ * </code>
+ *
+ *
+ * <em>InheritableValueT</em>
+ *
+ * This template parameter should indicate the functor, used to determine
+ * wheather or not this ThreadLocal will allow values from a parent threads
+ * context to be inherited by child threads when they are created.
+ * It should support the following operator:
+ *
+ * <code>
+ * // required operator
+ * bool operator(const T& childValueFunctor)
+ *
+ * // supported expression
+ * InheritableValueT()( ChildValueT() )
+ * </code>
+ *
+ */
+ template <
+ typename T,
+ typename InitialValueT = ThreadLocalImpl::InitialValueFn<T>,
+ typename ChildValueT = ThreadLocalImpl::UniqueChildValueFn,
+ typename InheritableValueT = ThreadLocalImpl::InheritableValueFn
+ >
+ class ThreadLocal : private ThreadLocalImpl {
+
+ typedef ThreadLocalImpl::ValuePtr ValuePtr;
+
+ class Value : public ThreadLocalImpl::Value {
+
+ T value;
+
+ public:
+
+ Value() : value( InitialValueT()() ) { }
+
+ Value(const Value& v) : value( ChildValueT()(v.value) ) { }
+
+ virtual ~Value() { }
+
+ operator T() { return value; }
+
+ const Value& operator=(const T& v) { value = v; }
+
+ virtual bool isInheritable() const {
+ return InheritableValueT()( ChildValueT() );
+ }
+
+ virtual ValuePtr clone() const {
+ return ValuePtr( new Value(*this) );
+ }
+
+ };
+
+ static ValuePtr createValue() {
+ return ValuePtr( new Value );
+ }
+
+ public:
+
+ /**
+ * Get the value associated with the context (this ThreadLocal and
+ * the calling thread) of the invoker. If no value is currently
+ * associated, then an intial value is created and associated; that value
+ * is returned.
+ *
+ * @return <em>T</em> associated value.
+ *
+ * @post If no value has been associated with the invoking context
+ * then an inital value will be associated. That value is
+ * created by the <em>InitialValueT</em> functor.
+ */
+ T get() const {
+ return (T)reinterpret_cast<Value&>( *value(&createValue) );
+ }
+
+ /**
+ * Replace the value associated with the context (this ThreadLocal and
+ * the calling thread) of the invoker. If no value is currently
+ * associated, then an intial value is first created and subsequently
+ * replaced by the new value.
+ *
+ * @param v value of type <em>T</em> to associate.
+ *
+ * @post If no value has been associated with the invoking context
+ * then an inital value will first be associated. That value is
+ * created by the <em>InitialValueT</em> functor and then
+ * replaced with the new value.
+ */
+ void set(T v) const {
+ reinterpret_cast<Value&>( *value(&createValue) ) = v;
+ }
+
+ /**
+ * Remove any value current associated with this ThreadLocal.
+ *
+ * @post Upon thier next invocation the get() and set() functions will behave as
+ * if no value has been associated with this ThreadLocal and an
+ * initial value will be generated.
+ */
+ void clear() const {
+ ThreadLocalImpl::clear();
+ }
+
+ /**
+ * Remove any value current associated with <em>any</em> ThreadLocal.
+ *
+ * @post Upon thier next invocation the get() and set() functions will behave as
+ * if no value has been associated with <em>any</em> ThreadLocal and new
+ * initial values will be generated.
+ */
+ static void clearAll() {
+ ThreadLocalImpl::clearAll();
+ }
+
+ };
+
+
+} // namespace ZThread
+
+#endif // __ZTTHREADLOCAL_H__
diff --git a/dep/include/zthread/ThreadLocalImpl.h b/dep/include/zthread/ThreadLocalImpl.h
new file mode 100644
index 00000000000..3b4046f8f58
--- /dev/null
+++ b/dep/include/zthread/ThreadLocalImpl.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 __ZTTHREADLOCALIMPL_H__
+#define __ZTTHREADLOCALIMPL_H__
+
+#include "zthread/CountedPtr.h"
+
+namespace ZThread {
+
+ /**
+ * @class ThreadLocalImpl
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-27T10:23:19-0400>
+ * @version 2.3.0
+ *
+ * @see ThreadLocal
+ */
+ class ZTHREAD_API ThreadLocalImpl : private NonCopyable {
+ public:
+
+ class Value;
+ typedef CountedPtr<Value, size_t> ValuePtr;
+
+ //!
+ class Value {
+ Value& operator=(const Value&);
+ public:
+ virtual ~Value() {}
+ virtual bool isInheritable() const = 0;
+ virtual ValuePtr clone() const = 0;
+ };
+
+ //! Create a ThreadLocalImpl
+ ThreadLocalImpl();
+
+ //! Destroy a ThreadLocalImpl
+ ~ThreadLocalImpl();
+
+ /**
+ * @class InitialValueFn
+ */
+ template <typename T>
+ struct InitialValueFn {
+ T operator()() { return T(); }
+ };
+
+ /**
+ * @class ChildValueFn
+ */
+ struct ChildValueFn {
+ template <typename T>
+ T operator()(const T& value) { return T(value); }
+ };
+
+ /**
+ * @class UniqueChildValueFn
+ */
+ struct UniqueChildValueFn : public ChildValueFn { };
+
+ /**
+ * @class InheritableValueFn
+ */
+ struct InheritableValueFn {
+
+ template <typename T>
+ bool operator()(const T&) { return true; }
+
+ bool operator()(const UniqueChildValueFn&) { return false; }
+
+ };
+
+ protected:
+
+ //! Get the Value for the current thread
+ ValuePtr value( ValuePtr (*pfn)() ) const;
+
+ //! Clear any value set for this thread
+ void clear() const;
+
+ //! Clear any value set with any ThreadLocal for this thread
+ static void clearAll();
+
+ };
+
+} // __ZTTHREADLOCALIMPL_H__
+
+#endif
+
diff --git a/dep/include/zthread/ThreadedExecutor.h b/dep/include/zthread/ThreadedExecutor.h
new file mode 100644
index 00000000000..9bc29b3c497
--- /dev/null
+++ b/dep/include/zthread/ThreadedExecutor.h
@@ -0,0 +1,136 @@
+/*
+ * 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 __ZTTHREADEDEXECUTOR_H__
+#define __ZTTHREADEDEXECUTOR_H__
+
+#include "zthread/Executor.h"
+#include "zthread/CountedPtr.h"
+
+namespace ZThread {
+
+ namespace { class ExecutorImpl; }
+
+ /**
+ * @class ThreadedExecutor
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T22:39:13-0400>
+ * @version 2.3.0
+ *
+ * A ThreadedExecutor spawns a new thread to execute each task submitted.
+ * A ThreadedExecutor supports the following optional operations,
+ *
+ * - <em>cancel</em>()ing a ThreadedExecutor will cause it to stop accepting
+ * new tasks.
+ *
+ * - <em>interrupt</em>()ing a ThreadedExecutor will cause the any thread running
+ * a task which was submitted prior to the invocation of this function to
+ * be interrupted during the execution of that task.
+ *
+ * - <em>wait</em>()ing on a ThreadedExecutor will block the calling thread
+ * until all tasks that were submitted prior to the invocation of this function
+ * have completed.
+ *
+ * @see Executor.
+ */
+ class ThreadedExecutor : public Executor {
+
+ CountedPtr< ExecutorImpl > _impl;
+
+ public:
+
+ //! Create a new ThreadedExecutor
+ ThreadedExecutor();
+
+ //! Destroy a ThreadedExecutor
+ virtual ~ThreadedExecutor();
+
+ /**
+ * Interrupting a ThreadedExecutor will cause an interrupt() to be sent
+ * to every Task that has been submitted at the time this function is
+ * called. Tasks that are submitted after this function is called will
+ * not be interrupt()ed; unless this function is invoked again().
+ */
+ virtual void interrupt();
+
+ /**
+ * Submit a task to this Executor. This will not block the current thread
+ * for very long. A new thread will be created and the task will be run()
+ * within the context of that new thread.
+ *
+ * @exception Cancellation_Exception thrown if this Executor has been canceled.
+ * The Task being submitted will not be executed by this Executor.
+ *
+ * @see Executor::execute(const Task&)
+ */
+ virtual void execute(const Task&);
+
+ /**
+ * @see Cancelable::cancel()
+ */
+ virtual void cancel();
+
+ /**
+ * @see Cancelable::isCanceled()
+ */
+ virtual bool isCanceled();
+
+ /**
+ * Waiting on a ThreadedExecutor will block the current thread until all
+ * tasks submitted to the Executor up until the time this function was called
+ * have completed.
+ *
+ * Tasks submitted after this function is called will not delay a thread that
+ * was already waiting on the Executor any longer. In order to wait for
+ * those tasks to complete as well, another wait() would be needed.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupted
+ * before the set of tasks for which it was waiting complete.
+ *
+ * @see Waitable::wait()
+ */
+ virtual void wait();
+
+ /**
+ * Operates the same as ThreadedExecutor::wait() but with a timeout.
+ *
+ * @param timeout maximum amount of time, in milliseconds, to wait for the
+ * currently submitted set of Tasks to complete.
+ *
+ * @exception Interrupted_Exception thrown if the calling thread is interrupt()ed
+ * while waiting for the current set of Tasks to complete.
+ *
+ * @return
+ * - <em>true</em> if the set of tasks running at the time this function is invoked complete
+ * before <i>timeout</i> milliseconds elapse.
+ * - <em>false</em> othewise.
+ *
+ * @see Waitable::wait(unsigned long timeout)
+ */
+ virtual bool wait(unsigned long timeout);
+
+ }; /* ThreadedExecutor */
+
+} // namespace ZThread
+
+#endif // __ZTTHREADEDEXECUTOR_H__
diff --git a/dep/include/zthread/Time.h b/dep/include/zthread/Time.h
new file mode 100644
index 00000000000..374c4fd6bf0
--- /dev/null
+++ b/dep/include/zthread/Time.h
@@ -0,0 +1,225 @@
+/*
+ * 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 __ZTTIME_H__
+#define __ZTTIME_H__
+
+#include "zthread/Config.h"
+
+namespace ZThread {
+
+/**
+ * @class Time
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T17:52:46-0400>
+ * @version 2.2.11
+ *
+ * The Time class provides access to time values relative to when the program
+ * was started. In other words, this class might be thought of as a timer that
+ * starts at 0 and counts upwards. This class offers millisecond resolution.
+ */
+class ZTHREAD_API Time {
+
+ unsigned long _seconds;
+ unsigned long _milliseconds;
+
+ //! Create a new Time object
+ Time(unsigned long secs, unsigned long millis)
+ : _seconds(secs), _milliseconds(millis) { }
+
+ /**
+ * Set the number of milliseconds in this Time object.
+ *
+ * @param millis - new milliseconds value
+ * @return unsigned long old milliseconds value
+ */
+ unsigned long milliseconds(unsigned long millis) {
+
+ unsigned long n = _milliseconds;
+ _milliseconds = millis;
+
+ return n;
+
+ }
+
+ /**
+ * Set the number of seconds in this Time object.
+ *
+ * @param secs - new seconds value
+ * @return unsigned long old seconds value
+ */
+ unsigned long seconds(unsigned long secs) {
+
+ unsigned long n = _seconds;
+ _seconds = secs;
+
+ return n;
+
+ }
+
+ public:
+
+
+ /**
+ * Create a Time object with the current time relative to the
+ * beginning of the program.
+ */
+ Time();
+
+ /**
+ * Create a Time object by copying another.
+ *
+ * @param t - Time object to copy.
+ */
+ Time(const Time& t)
+ : _seconds(t._seconds), _milliseconds(t._milliseconds) { }
+
+
+ /**
+ * Get the number of milliseconds in this Time object.
+ *
+ * @return unsigned long milliseconds value
+ */
+ unsigned long milliseconds() const {
+ return _milliseconds;
+ }
+
+ /**
+ * Get the number of seconds in this Time object.
+ *
+ * @return unsigned long seconds value
+ */
+ unsigned long seconds() const {
+ return _seconds;
+ }
+
+ /**
+ * Add some number of milliseconds to this Time object.
+ *
+ * @param millis - number of milliseconds to add to this Time object
+ * @return const Time& this object
+ */
+ const Time& operator+=(unsigned long millis) {
+
+ _milliseconds += millis;
+ _seconds += (_milliseconds / 1000);
+ _milliseconds %= 1000;
+
+ return *this;
+
+ }
+
+ /**
+ * Subtract some number of milliseconds to this Time object.
+ *
+ * @param millis - number of milliseconds to subtract from this Time object
+ * @return const Time& this object
+ */
+const Time& operator-=(unsigned long millis) {
+
+ if(_milliseconds > millis)
+ _milliseconds -= millis;
+
+ else {
+
+ while(_seconds > 0 && _milliseconds < millis) {
+
+ _milliseconds += 1000;
+ _seconds -= 1;
+
+ }
+
+ _milliseconds = (_milliseconds < millis) ? 0 : (_milliseconds - millis);
+
+ }
+
+ return *this;
+
+}
+
+
+ /**
+ * Add the value of another Time object to this one.
+ *
+ * @param t - Time object whose value should be added to this object
+ * @return const Time& this object
+ */
+ const Time& operator+=(const Time& t) {
+
+ _milliseconds += t.milliseconds();
+ _seconds += (_milliseconds / 1000) + t.seconds();
+ _milliseconds %= 1000;
+
+ return *this;
+
+ }
+
+ /**
+ * Subtract the value of another Time object from this one.
+ * This function has a floor of 0.
+ *
+ * @param t - Time object whose value should be subtracted from this object
+ * @return const Time& this object
+ */
+const Time& operator-=(const Time& t) {
+
+ unsigned long millis = t.milliseconds();
+ unsigned long secs = t.seconds();
+
+ if(_seconds >= secs) {
+
+ if(_milliseconds > millis) {
+ _milliseconds -= millis;
+ _seconds -= secs;
+
+ } else {
+
+ while(_seconds > 0 && _milliseconds < millis) {
+
+ _milliseconds += 1000;
+ _seconds -= 1;
+
+ }
+
+ _milliseconds = (_milliseconds < millis) ? 0 : (_milliseconds - millis);
+ _seconds = (_seconds < secs) ? 0 : (_seconds - secs);
+
+ }
+
+ } else {
+
+ _milliseconds = 0;
+ _seconds = 0;
+
+ }
+
+ return *this;
+
+}
+
+};
+
+
+
+} // namespace ZThread
+
+#endif // __ZTTIME_H__
diff --git a/dep/include/zthread/Waitable.h b/dep/include/zthread/Waitable.h
new file mode 100644
index 00000000000..3d925f2a691
--- /dev/null
+++ b/dep/include/zthread/Waitable.h
@@ -0,0 +1,94 @@
+/*
+ * 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 __ZTWAITABLE_H__
+#define __ZTWAITABLE_H__
+
+#include "zthread/Exceptions.h"
+
+namespace ZThread {
+
+ /**
+ * @class Waitable
+ *
+ * @author Eric Crahen <http://www.code-foo.com>
+ * @date <2003-07-16T22:16:41-0400>
+ * @version 2.3.0
+ *
+ * The Waitable interface defines a common method of adding generic <i>wait</i> semantics
+ * to a class.
+ *
+ * <b>Waiting</b>
+ *
+ * An object implementing the Waitable interface externalizes a mechanism for testing
+ * some internal condition. Another object may <i>wait()</i>s for a Waitable object;
+ * in doing so, it wait()s for that condition to become true by blocking the caller
+ * while the condition is false.
+ *
+ * For example, a Condition is Waitable object that extends <i>wait</i> semantics
+ * so that wait()ing means a thread is blocked until some external stimulus
+ * specifically performs an operation on the Condition to make its internal condition true.
+ * (serialization aside)
+ *
+ * A Barrier extends <i>wait</i> semantics so that wait()ing mean waiting for other
+ * waiters, and may include automatically resetting the condition once a wait is complete.
+ *
+ * @see Condition
+ * @see Barrier
+ * @see Executor
+ */
+ class Waitable {
+ public:
+
+ //! Destroy a Waitable object.
+ virtual ~Waitable() {}
+
+ /**
+ * Waiting on an object will generally cause the calling thread to be blocked
+ * for some indefinite period of time. The thread executing will not proceed
+ * any further until the Waitable object releases it unless or an exception
+ * is thrown.
+ */
+ virtual void wait() = 0;
+
+ /**
+ * Waiting on an object will generally cause the calling thread to be blocked
+ * for some indefinite period of time. The thread executing will not proceed
+ * any further until the Waitable object releases it unless or an exception
+ * is thrown.
+ *
+ * @param timeout maximum amount of time, in milliseconds, to spend waiting.
+ *
+ * @return
+ * - <em>true</em> if the set of tasks being wait for complete before
+ * <i>timeout</i> milliseconds elapse.
+ * - <em>false</em> othewise.
+ */
+ virtual bool wait(unsigned long timeout) = 0;
+
+
+ }; /* Waitable */
+
+
+} // namespace ZThread
+
+#endif // __ZTWAITABLE_H__
diff --git a/dep/include/zthread/ZThread.h b/dep/include/zthread/ZThread.h
new file mode 100644
index 00000000000..1df5bb67a7c
--- /dev/null
+++ b/dep/include/zthread/ZThread.h
@@ -0,0 +1,67 @@
+/*
+ * 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 __ZTLIBRARY_H__
+#define __ZTLIBRARY_H__
+
+
+#include "zthread/Barrier.h"
+#include "zthread/BiasedReadWriteLock.h"
+#include "zthread/BlockingQueue.h"
+#include "zthread/BoundedQueue.h"
+#include "zthread/Cancelable.h"
+#include "zthread/ClassLockable.h"
+#include "zthread/ConcurrentExecutor.h"
+#include "zthread/Condition.h"
+#include "zthread/Config.h"
+#include "zthread/CountedPtr.h"
+#include "zthread/CountingSemaphore.h"
+#include "zthread/Exceptions.h"
+#include "zthread/Executor.h"
+#include "zthread/FairReadWriteLock.h"
+#include "zthread/FastMutex.h"
+#include "zthread/FastRecursiveMutex.h"
+#include "zthread/Guard.h"
+#include "zthread/Lockable.h"
+#include "zthread/LockedQueue.h"
+#include "zthread/MonitoredQueue.h"
+#include "zthread/Mutex.h"
+#include "zthread/NonCopyable.h"
+#include "zthread/PoolExecutor.h"
+#include "zthread/Priority.h"
+#include "zthread/PriorityCondition.h"
+#include "zthread/PriorityInheritanceMutex.h"
+#include "zthread/PriorityMutex.h"
+#include "zthread/PrioritySemaphore.h"
+#include "zthread/Queue.h"
+#include "zthread/ReadWriteLock.h"
+#include "zthread/RecursiveMutex.h"
+#include "zthread/Runnable.h"
+#include "zthread/Semaphore.h"
+#include "zthread/Singleton.h"
+#include "zthread/SynchronousExecutor.h"
+#include "zthread/Thread.h"
+#include "zthread/ThreadLocal.h"
+#include "zthread/Time.h"
+#include "zthread/Waitable.h"
+
+#endif