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=a5e02254fe4a43b0de769e5b14a4c2eca125beba;hp=0000000000000000000000000000000000000000;hb=c2321281bf12a7efaedde930422c7ddbc92080d4;hpb=87bc17e55b0c1dc73ecc66df856d3f08fd7a7724 diff --git a/src/Moof/Thread.hh b/src/Moof/Thread.hh new file mode 100644 index 0000000..a5e0225 --- /dev/null +++ b/src/Moof/Thread.hh @@ -0,0 +1,297 @@ + +/******************************************************************************* + + Copyright (c) 2009, Charles McGarvey + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#ifndef _MOOF_THREAD_HH_ +#define _MOOF_THREAD_HH_ + +/** + * @file Thread.hh + * Light C++ wrapper around SDL threads. + */ + +#include + +#include + + +namespace Mf { + +// +// The detach function detaches a separate thread by calling 'func' with +// the 'arg' parameter. +// + +typedef SDL_Thread* Thread; + +typedef boost::function Function; + + +int detach_(void* arg) +{ + Function function = *(Function*)arg; + int ret = function(); + + delete (Function*)arg; + return ret; +} + +Thread detachFunction(const Function& function) +{ + Thread thread; + Function* fcopy = new Function(function); + + thread = SDL_CreateThread(detach_, (void*)fcopy); + if (thread == 0) delete fcopy; + return thread; +} + + +int waitOnThread(Thread thread) +{ + int i; + SDL_WaitThread(thread, &i); + return i; +} + +void killThread(Thread thread) +{ + SDL_KillThread(thread); +} + + +// +// The identifier function returns a unique integer for the calling thread. +// + +unsigned int getThreadIdentifier() +{ + return SDL_ThreadID(); +} + +unsigned int getThreadIdentifier(Thread thread) +{ + return SDL_GetThreadID(thread); +} + + +// ============================================================================= + +class Mutex +{ + friend class Condition; + +public: + Mutex() + { + mutex_ = SDL_CreateMutex(); + } + ~Mutex() + { + SDL_DestroyMutex(mutex_); + } + + bool acquireLock() + { + return (SDL_LockMutex(mutex_) == 0); + } + bool releaseLock() + { + return (SDL_UnlockMutex(mutex_) == 0); + } + + class Lock + { + friend class Condition; + + public: + Lock(Mutex& mutex) + { + mutex_ = &mutex; + isLocked_ = false; + } + ~Lock() + { + if (isLocked_) release(); + } + + bool acquire() + { + return (isLocked_ = mutex_->acquireLock()); + } + bool release() + { + return mutex_->releaseLock(); + isLocked_ = false; + } + + bool isLocked() const + { + return isLocked_; + } + + protected: + Mutex* mutex_; + bool isLocked_; + }; + + class ScopedLock : public Lock + { + public: + ScopedLock(Mutex& mutex) : + Lock(mutex) + { + acquire(); + } + }; + +private: + SDL_mutex* mutex_; +}; + + +class Condition +{ +public: + Condition() + { + condition_ = SDL_CreateCond(); + } + ~Condition() + { + SDL_DestroyCond(condition_); + } + + bool wait(Mutex::Lock& lock) + { + return (SDL_CondWait(condition_, lock.mutex_->mutex_) == 0); + } + bool wait(Mutex::Lock& lock, unsigned ms) + { + // TODO for consistency, this function should take seconds + return (SDL_CondWaitTimeout(condition_, lock.mutex_->mutex_, ms) == 0); + } + + bool notify() + { + return (SDL_CondSignal(condition_) == 0); + } + bool notifyAll() + { + return (SDL_CondBroadcast(condition_) == 0); + } + +private: + SDL_cond* condition_; +}; + + +class Semaphore +{ +public: + Semaphore(unsigned int value) + { + semaphore_ = SDL_CreateSemaphore(value); + } + ~Semaphore() + { + SDL_DestroySemaphore(semaphore_); + } + + bool acquireLock() + { + return (SDL_SemWait(semaphore_) == 0); + } + bool releaseLock() + { + return (SDL_SemPost(semaphore_) == 0); + } + + bool tryLock() + { + return (SDL_SemTryWait(semaphore_) == 0); + } + bool tryLock(unsigned ms) + { + // TODO for consistency, this function should take seconds + return (SDL_SemWaitTimeout(semaphore_, ms) == 0); + } + + class Lock + { + public: + Lock(Semaphore& semaphore) + { + semaphore_ = &semaphore; + isLocked_ = false; + } + ~Lock() + { + if (isLocked_) release(); + } + + bool acquire() + { + return (isLocked_ = semaphore_->acquireLock()); + } + bool release() + { + return semaphore_->releaseLock(); isLocked_ = false; + } + + bool isLocked() const + { + return isLocked_; + } + + protected: + Semaphore* semaphore_; + bool isLocked_; + }; + + class ScopedLock : public Lock + { + public: + ScopedLock(Semaphore& semaphore) : + Lock(semaphore) + { + acquire(); + } + }; + +private: + SDL_sem* semaphore_; +}; + + +} // namespace Mf + + +#endif // _MOOF_THREAD_HH_ + +/** vim: set ts=4 sw=4 tw=80: *************************************************/ +