X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FThread.hh;fp=src%2FMoof%2FThread.hh;h=0000000000000000000000000000000000000000;hp=2987a59b968716b7649c1eb5d180072f3c308e8a;hb=831f04d4bc19a390415ac0bbac4331c7a65509bc;hpb=299af4f2047e767e5d79501c26444473bda64c64 diff --git a/src/Moof/Thread.hh b/src/Moof/Thread.hh deleted file mode 100644 index 2987a59..0000000 --- a/src/Moof/Thread.hh +++ /dev/null @@ -1,622 +0,0 @@ - -/*] Copyright (c) 2009-2010, Charles McGarvey [************************** -**] All rights reserved. -* -* vi:ts=4 sw=4 tw=75 -* -* Distributable under the terms and conditions of the 2-clause BSD license; -* see the file COPYING for a complete text of the license. -* -**************************************************************************/ - -/** - * \file Thread.hh - * Light C++ wrapper around the SDL threads API. - */ - -#ifndef _MOOF_THREAD_HH_ -#define _MOOF_THREAD_HH_ - -#include -#include -#include - -#include - - -namespace Mf { - - -/** - * Represents a thread which may be running. You cannot instantiate a - * thread object directly; new threads are created by detaching functions - * using the detach() method. Once a thread is detached, it will continue - * running until the function returns. You don't need to keep the thread - * object you want to wait() or kill() the thread later. - */ -class Thread -{ -public: - - typedef boost::function Function; - - - /** - * Construct an invalid thread object which has no association with any - * real thread. - */ - Thread() : - mThread(0) {} - - /** - * Execute a function in a new thread. - * \param function The function to execute. - * \return The new thread, or an invalid thread if an error occurred. - */ - static Thread detach(const Function& function) - { - Function* fcopy = new Function(function); - SDL_Thread* thread = SDL_CreateThread(&Thread::run, (void*)fcopy); - if (thread == 0) delete fcopy; - return Thread(thread); - } - - - /** - * Wait for the thread to terminate, getting its return value. The - * thread will be invalidated. - * \return The integer value returned by the detached function. - */ - int wait() - { - int i; - SDL_WaitThread(mThread, &i); - mThread = 0; - return i; - } - - /** - * Forcefully kill the thread without giving it a chance to clean up - * after itself. The thread will be invalidated. Don't use this. - */ - void kill() - { - SDL_KillThread(mThread); - mThread = 0; - } - - /** - * Get whether or not the thread object is associated with a real - * thread. - * \return True if the thread is valid, false otherwise. - */ - bool isValid() const - { - return mThread != 0; - } - - - /** - * Get a unique identifier for this thread, if it is valid. - * \return The identifier. - */ - uint32_t identifier() const - { - return SDL_GetThreadID(mThread); - } - - /** - * Get the unique identifier of the calling thread. - * \return The identifier. - */ - static uint32_t currentIdentifier() - { - return SDL_ThreadID(); - } - - -private: - - Thread(SDL_Thread* thread) : - mThread(thread) {} - - static int run(void* arg) - { - int code = (*(Function*)arg)(); - delete (Function*)arg; - return code; - } - - - SDL_Thread* mThread; -}; - - -/** - * An abstract class representing some task that is to be run - * asynchronously. - */ -class AsyncTask -{ -public: - - /** - * Deconstruct the task. - */ - virtual ~AsyncTask() {} - - /** - * Get whether or not the task is done. - * \return True if the task is done, false otherwise. - */ - virtual bool isDone() const = 0; - - /** - * Begin the task. - */ - virtual void run() = 0; - - /** - * Block the current thread until the task is finished. - * \return A value representing the state of the finished task. - */ - virtual int wait() = 0; -}; - -/** - * An asynchronous task that is run to be executed in a separated thread. - */ -class ThreadedTask -{ -public: - - /** - * Get the thread object the task is executing in. - * \return The thread. - */ - const Thread& thread() const { return mThread; } - - /** - * Block the current thread until the task thread is finished. - * \return The integer value returned by the task function. - */ - int wait() - { - return mThread.wait(); - } - - -protected: - - Thread mThread; -}; - - -/** - * A mutex to protect sensitive sections of code from threads which might - * otherwise cause unpredictable results. - */ -class Mutex -{ -public: - - /** - * Construct a mutex. - */ - Mutex() : - mMutex(SDL_CreateMutex()) {} - - /** - * Deconstruct a mutex. - */ - ~Mutex() - { - SDL_DestroyMutex(mMutex); - } - - - /** - * Block until the calling thread can secure exclusive access to the - * code protected by the mutex. - * \return True if the lock was acquired, false otherwise. - * \see Lock - */ - bool acquireLock() - { - return (SDL_LockMutex(mMutex) == 0); - } - - /** - * Unlock the mutex. Call this after the sensitive block of code to - * allow another thread to acquire the lock. - * \return True if the mutex was unlocked, false otherwise. - * \see Lock - */ - bool releaseLock() - { - return (SDL_UnlockMutex(mMutex) == 0); - } - - - /** - * As an alternative method for locking, objects of this class will - * automagically release the lock if it is still locked at - * deconstruction. Therefore, it's generally safer to use this method - * since it makes it much more difficult to forget to unlock a mutex. - */ - class Lock - { - public: - - /** - * Construct a lock. - * \param mutex The mutex. - */ - explicit Lock(Mutex& mutex) : - mMutex(mutex), - mIsLocked(false) {} - - /** - * Deconstruct a lock. The lock is automagically released if it is - * still locked. - */ - ~Lock() - { - if (mIsLocked) release(); - } - - - /** - * Try to acquire a lock on the mutex. - * \return True if the mutex was locked, false otherwise. - */ - bool acquire() - { - return (mIsLocked = mMutex.acquireLock()); - } - - /** - * Release the lock. - * \return True if the mutex was unlocked, false otherwise. - */ - bool release() - { - bool result = mMutex.releaseLock(); - mIsLocked = false; - return result; - } - - - /** - * Get whether or not the mutex is locked. - * \return True if the mutex is locked, false otherwise. - */ - bool isLocked() const - { - return mIsLocked; - } - - - protected: - - Mutex& mMutex; - bool mIsLocked; - - friend class Condition; - }; - - /** - * This type of lock tries to acquire a lock on the mutex during - * construction and releases the lock on deconstruction. - */ - class ScopedLock : private Lock - { - public: - - /** - * Construct a lock. - * \param mutex The mutex. - */ - explicit ScopedLock(Mutex& mutex) : - Lock(mutex) - { - acquire(); - } - - /** - * Get whether or not the mutex is locked. - * \return True if the mutex is locked, false otherwise. - */ - bool isLocked() const - { - return Lock::isLocked(); - } - }; - - -private: - - SDL_mutex* mMutex; - - friend class Condition; -}; - - -/** - * A class representing a condition variable. - */ -class Condition -{ -public: - - /** - * Construct a condition. - */ - Condition() - { - mCondition = SDL_CreateCond(); - } - - /** - * Deconstruct a condition. - */ - ~Condition() - { - SDL_DestroyCond(mCondition); - } - - - /** - * Unlock the mutex and wait for another thread to notify the thread, - * at which point the mutex will be re-locked and the method will - * return. - * \param mutex The mutex. - * \return True if the thread was notified, false otherwise. - */ - bool wait(Mutex& mutex) - { - return (SDL_CondWait(mCondition, mutex.mMutex) == 0); - } - - /** - * Unlock the mutex associated with a lock and wait for another thread - * to notify the thread, at which point the lock will be re-locked and - * the method will return. - * \param lock The lock. - * \return True if the thread was notified, false otherwise. - */ - bool wait(Mutex::Lock& lock) - { - return (SDL_CondWait(mCondition, lock.mMutex.mMutex) == 0); - } - - /** - * Unlock the mutex and wait for another thread to notify the thread, - * at which point the mutex will be re-locked and the method will - * return. If the thread was not notified before a certain number of - * seconds, the method will return anyway. - * \param mutex The mutex. - * \param timeout Number of seconds to wait. - * \return True if the thread was notified, false otherwise. - */ - bool wait(Mutex& mutex, Scalar timeout) - { - Uint32 ms = timeout * SCALAR(1000.0); - return (SDL_CondWaitTimeout(mCondition, mutex.mMutex, ms) == 0); - } - - /** - * Unlock the mutex associated with a lock and wait for another thread - * to notify the thread, at which point the lock will be re-locked and - * the method will return. If the thread was not notified before a - * certain number of seconds, the method will return anyway. - * \param lock The lock. - * \param timeout Number of seconds to wait. - * \return True if the thread was notified, false otherwise. - */ - bool wait(Mutex::Lock& lock, Scalar timeout) - { - Uint32 ms = timeout * SCALAR(1000.0); - return (SDL_CondWaitTimeout(mCondition, - lock.mMutex.mMutex, ms) == 0); - } - - - /** - * Notify one other thread that is waiting on the condition. - * \return True on success, false otherwise. - */ - bool notify() - { - return (SDL_CondSignal(mCondition) == 0); - } - - /** - * Notify all other threads that are waiting on the condition. - * \return True on success, false otherwise. - */ - bool notifyAll() - { - return (SDL_CondBroadcast(mCondition) == 0); - } - - -private: - - SDL_cond* mCondition; -}; - - -/** - * A semaphore class. - */ -class Semaphore -{ -public: - - /** - * Construct a semaphore. - * \param value The initial value of the semaphore. - */ - explicit Semaphore(uint32_t value) - { - mSemaphore = SDL_CreateSemaphore(value); - } - - /** - * Deconstruct a semaphore. - */ - ~Semaphore() - { - SDL_DestroySemaphore(mSemaphore); - } - - - /** - * Block until the calling thread can secure exclusive access to the - * code protected by the semaphore. - * \return True if the lock was acquired, false otherwise. - * \see Lock - */ - bool acquireLock() - { - return (SDL_SemWait(mSemaphore) == 0); - } - - /** - * Block until the calling thread can secure exclusive access to the - * code protected by the semaphore, or until the timeout expires. - * \param timeout Number of seconds to try. - * \return True if the lock was acquired, false otherwise. - */ - bool acquireLock(Scalar timeout) - { - Uint32 ms = timeout * SCALAR(1000.0); - return (SDL_SemWaitTimeout(mSemaphore, ms) == 0); - } - - /** - * Unlock the semaphore. Call this after the sensitive block of code - * to allow another thread to acquire the lock. - * \return True if the semaphore was unlocked, false otherwise. - * \see Lock - */ - bool releaseLock() - { - return (SDL_SemPost(mSemaphore) == 0); - } - - /** - * Try to lock the semaphore, but don't block if the lock is not - * immediately available. - * \return True if the semaphore was locked, false otherwise. - */ - bool tryLock() - { - return (SDL_SemTryWait(mSemaphore) == 0); - } - - /** - * As an alternative method for locking, objects of this class will - * automagically release the lock if it is still locked at - * deconstruction. Therefore, it's generally safer to use this method - * since it makes it much more difficult to forget to unlock a - * semaphore. - */ - class Lock - { - public: - - /** - * Construct a lock. - * \param semaphore The semaphore. - */ - explicit Lock(Semaphore& semaphore) : - mSemaphore(semaphore), - mIsLocked(false) {} - - /** - * Deconstruct a lock. The lock is automagically released if it is - * still locked. - */ - ~Lock() - { - if (mIsLocked) release(); - } - - - /** - * Try to acquire a lock on the semaphore. - * \return True if the semaphore was locked, false otherwise. - */ - bool acquire() - { - return (mIsLocked = mSemaphore.acquireLock()); - } - - /** - * Release the lock. - * \return True if the semaphore was unlocked, false otherwise. - */ - bool release() - { - bool result = mSemaphore.releaseLock(); - mIsLocked = false; - return result; - } - - /** - * Get whether or not the semaphore is locked. - * \return True if the semaphore is locked, false otherwise. - */ - bool isLocked() const - { - return mIsLocked; - } - - - protected: - - Semaphore& mSemaphore; - bool mIsLocked; - }; - - /** - * This type of lock tries to acquire a lock on the semaphore during - * construction and releases the lock on deconstruction. - */ - class ScopedLock : private Lock - { - public: - - /** - * Construct a lock. - * \param semaphore The semaphore. - */ - explicit ScopedLock(Semaphore& semaphore) : - Lock(semaphore) - { - acquire(); - } - - /** - * Get whether or not the semaphore is locked. - * \return True if the semaphore is locked, false otherwise. - */ - bool isLocked() const - { - return Lock::isLocked(); - } - }; - - -private: - - SDL_sem* mSemaphore; -}; - - -} // namespace Mf - -#endif // _MOOF_THREAD_HH_ -