]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Thread.hh
extreme refactoring
[chaz/yoink] / src / Moof / Thread.hh
diff --git a/src/Moof/Thread.hh b/src/Moof/Thread.hh
new file mode 100644 (file)
index 0000000..a5e0225
--- /dev/null
@@ -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 <boost/function.hpp>
+
+#include <SDL/SDL.h>
+
+
+namespace Mf {
+
+//
+// The detach function detaches a separate thread by calling 'func' with
+// the 'arg' parameter.
+//
+
+typedef SDL_Thread* Thread;
+
+typedef boost::function<int(void)> 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: *************************************************/
+
This page took 0.021298 seconds and 4 git commands to generate.