-/*] Copyright (c) 2009-2010, Charles McGarvey [**************************
+/*] Copyright (c) 2009-2011, 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.
*
-**************************************************************************/
+*****************************************************************************/
#ifndef _MOOF_THREAD_HH_
#define _MOOF_THREAD_HH_
namespace moof {
+// forward declarations
class runloop;
typedef boost::shared_ptr<runloop> runloop_ptr;
-
/**
* Represents a thread which may be running. You cannot instantiate a
* thread object directly; new threads are created by detaching functions
typedef boost::function<int(thread&)> function;
-
/**
* Construct an invalid thread object which has no association with any
* real thread.
*/
thread();
-
/**
* Execute a function in a new thread.
* \param function The function to execute.
*/
static thread detach(timer& timer);
-
/**
* Wait for the thread to terminate, getting its return value. The
* thread will be invalidated.
return thread_ != 0;
}
-
/**
* Get a unique identifier for this thread, if it is valid.
* \return The identifier.
return SDL_ThreadID();
}
-
/**
* Get the thread's runloop.
* \return The thread's runloop.
*/
static moof::runloop& main_runloop();
-
private:
static void spawn(thread* thread);
static int run(void* arg);
-
- function function_;
- SDL_Thread* thread_;
- runloop_ptr runloop_;
+ function function_;
+ SDL_Thread* thread_;
+ runloop_ptr runloop_;
};
virtual int wait() = 0;
};
+
/**
* An asynchronous task that is run to be executed in a separated thread.
*/
* Get the thread object the task is executing in.
* \return The thread.
*/
- const class thread& thread() const { return thread_; }
+ const class thread& thread() const
+ {
+ return thread_;
+ }
/**
* Block the current thread until the task thread is finished.
return thread_.wait();
}
-
protected:
class thread thread_;
/**
* Construct a mutex.
*/
- mutex() :
+ mutex() :
mutex_(SDL_CreateMutex()) {}
/**
* Deconstruct a mutex.
*/
- ~mutex()
+ ~mutex()
{
SDL_DestroyMutex(mutex_);
}
-
/**
* 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 acquire_lock()
+ bool acquire_lock()
{
- return (SDL_LockMutex(mutex_) == 0);
+ return SDL_LockMutex(mutex_) == 0;
}
/**
* \return True if the mutex was unlocked, false otherwise.
* \see lock
*/
- bool release_lock()
+ bool release_lock()
{
- return (SDL_UnlockMutex(mutex_) == 0);
+ return SDL_UnlockMutex(mutex_) == 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:
+ class lock
+ {
+ public:
/**
* Construct a lock.
* \param mutex The mutex.
*/
- explicit lock(mutex& mutex, bool lock = true) :
+ explicit lock(mutex& mutex, bool lock = true) :
mutex_(mutex),
is_locked_(false)
{
- if (lock) if (!acquire()) throw "mutex lock not acquired";
+ if (lock && !acquire()) throw "mutex lock not acquired";
}
/**
* Deconstruct a lock. The lock is automagically released if it is
* still locked.
*/
- ~lock()
+ ~lock()
{
if (is_locked_) release();
}
-
/**
* Try to acquire a lock on the mutex.
* \return True if the mutex was locked, false otherwise.
*/
- bool acquire()
+ bool acquire()
{
return (is_locked_ = mutex_.acquire_lock());
}
* Release the lock.
* \return True if the mutex was unlocked, false otherwise.
*/
- bool release()
+ bool release()
{
bool result = mutex_.release_lock();
is_locked_ = false;
return result;
}
-
/**
* Get whether or not the mutex is locked.
* \return True if the mutex is locked, false otherwise.
*/
- bool is_locked() const
+ bool is_locked() const
{
return is_locked_;
}
+ protected:
- protected:
-
- mutex& mutex_;
- bool is_locked_;
-
- friend class condition;
- };
+ mutex& mutex_;
+ bool is_locked_;
+ friend class condition;
+ };
private:
/**
* Construct a condition.
*/
- condition()
+ condition()
{
condition_ = SDL_CreateCond();
}
/**
* Deconstruct a condition.
*/
- ~condition()
+ ~condition()
{
SDL_DestroyCond(condition_);
}
-
/**
* 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
*/
bool wait(mutex& mutex)
{
- return (SDL_CondWait(condition_, mutex.mutex_) == 0);
+ return SDL_CondWait(condition_, mutex.mutex_) == 0;
}
/**
* \param lock The lock.
* \return True if the thread was notified, false otherwise.
*/
- bool wait(mutex::lock& lock)
+ bool wait(mutex::lock& lock)
{
- return (SDL_CondWait(condition_, lock.mutex_.mutex_) == 0);
- }
+ return SDL_CondWait(condition_, lock.mutex_.mutex_) == 0;
+ }
/**
* Unlock the mutex and wait for another thread to notify the thread,
* \param timeout Number of seconds to wait.
* \return True if the thread was notified, false otherwise.
*/
- bool wait(mutex& mutex, scalar timeout)
+ bool wait(mutex& mutex, scalar timeout)
{
Uint32 ms = timeout * SCALAR(1000.0);
- return (SDL_CondWaitTimeout(condition_, mutex.mutex_, ms) == 0);
+ return SDL_CondWaitTimeout(condition_, mutex.mutex_, ms) == 0;
}
/**
* \param timeout Number of seconds to wait.
* \return True if the thread was notified, false otherwise.
*/
- bool wait(mutex::lock& lock, scalar timeout)
+ bool wait(mutex::lock& lock, scalar timeout)
{
Uint32 ms = timeout * SCALAR(1000.0);
- return (SDL_CondWaitTimeout(condition_,
- lock.mutex_.mutex_, ms) == 0);
+ return SDL_CondWaitTimeout(condition_,
+ lock.mutex_.mutex_, ms) == 0;
}
-
/**
* Notify one other thread that is waiting on the condition.
* \return True on success, false otherwise.
*/
- bool notify()
+ bool notify()
{
- return (SDL_CondSignal(condition_) == 0);
+ return SDL_CondSignal(condition_) == 0;
}
/**
* Notify all other threads that are waiting on the condition.
* \return True on success, false otherwise.
*/
- bool notify_all()
+ bool notify_all()
{
- return (SDL_CondBroadcast(condition_) == 0);
+ return SDL_CondBroadcast(condition_) == 0;
}
-
private:
SDL_cond* condition_;
* Construct a semaphore.
* \param value The initial value of the semaphore.
*/
- explicit semaphore(uint32_t value)
+ explicit semaphore(uint32_t value)
{
semaphore_ = SDL_CreateSemaphore(value);
}
/**
* Deconstruct a semaphore.
*/
- ~semaphore()
+ ~semaphore()
{
SDL_DestroySemaphore(semaphore_);
}
-
/**
* 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 acquire_lock()
+ bool acquire_lock()
{
- return (SDL_SemWait(semaphore_) == 0);
+ return SDL_SemWait(semaphore_) == 0;
}
/**
bool acquire_lock(scalar timeout)
{
Uint32 ms = timeout * SCALAR(1000.0);
- return (SDL_SemWaitTimeout(semaphore_, ms) == 0);
+ return SDL_SemWaitTimeout(semaphore_, ms) == 0;
}
/**
* \return True if the semaphore was unlocked, false otherwise.
* \see lock
*/
- bool release_lock()
+ bool release_lock()
{
- return (SDL_SemPost(semaphore_) == 0);
+ return SDL_SemPost(semaphore_) == 0;
}
/**
* immediately available.
* \return True if the semaphore was locked, false otherwise.
*/
- bool try_lock()
+ bool try_lock()
{
- return (SDL_SemTryWait(semaphore_) == 0);
+ return SDL_SemTryWait(semaphore_) == 0;
}
/**
* since it makes it much more difficult to forget to unlock a
* semaphore.
*/
- class lock
- {
- public:
+ class lock
+ {
+ public:
/**
* Construct a lock.
* \param semaphore The semaphore.
*/
- explicit lock(semaphore& semaphore, bool lock = true) :
+ explicit lock(semaphore& semaphore, bool lock = true) :
semaphore_(semaphore),
is_locked_(false)
{
- if (lock) if (!acquire()) throw "semaphore lock not acquired";
+ if (lock && !acquire()) throw "semaphore lock not acquired";
}
/**
* Deconstruct a lock. The lock is automagically released if it is
* still locked.
*/
- ~lock()
+ ~lock()
{
if (is_locked_) release();
}
-
/**
* Try to acquire a lock on the semaphore.
* \return True if the semaphore was locked, false otherwise.
*/
- bool acquire()
+ bool acquire()
{
return (is_locked_ = semaphore_.acquire_lock());
}
* Release the lock.
* \return True if the semaphore was unlocked, false otherwise.
*/
- bool release()
+ bool release()
{
bool result = semaphore_.release_lock();
is_locked_ = false;
* Get whether or not the semaphore is locked.
* \return True if the semaphore is locked, false otherwise.
*/
- bool is_locked() const
+ bool is_locked() const
{
return is_locked_;
}
-
-
- protected:
- semaphore& semaphore_;
- bool is_locked_;
- };
+ protected:
+ semaphore& semaphore_;
+ bool is_locked_;
+ };
private:
#if ENABLE_THREADS
-#define MOOF_DECLARE_MUTEX(M) moof::mutex M
+#define MOOF_DECLARE_MUTEX(M) moof::mutex M
#define MOOF_DECLARE_STATIC_MUTEX(M) static moof::mutex M
-#define MOOF_MUTEX_LOCK(M) moof::mutex::lock lock_##M(M)
+#define MOOF_MUTEX_LOCK(M) moof::mutex::lock lock_##M(M)
#else
#define MOOF_DECLARE_MUTEX(M)
#define MOOF_DECLARE_STATIC_MUTEX(M)