*
**************************************************************************/
+#ifndef _MOOF_THREAD_HH_
+#define _MOOF_THREAD_HH_
+
/**
* \file thread.hh
* Light C++ wrapper around the SDL threads API.
*/
-#ifndef _MOOF_THREAD_HH_
-#define _MOOF_THREAD_HH_
-
#include <boost/bind.hpp>
#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
#include <SDL/SDL.h>
#include <moof/math.hh>
+#include <moof/timer.hh>
namespace moof {
+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
{
public:
- typedef boost::function<int(void)> function;
+ typedef boost::function<int(thread&)> function;
/**
* Construct an invalid thread object which has no association with any
* real thread.
*/
- thread() :
- thread_(0) {}
+ thread();
+
/**
* 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)
- {
- thread::function* fcopy = new thread::function(function);
- SDL_Thread* thread = SDL_CreateThread(&thread::run, (void*)fcopy);
- if (thread == 0) delete fcopy;
- return moof::thread(thread);
- }
+ static thread detach(const function& function);
+
+ /**
+ * Detach a new thread and run its runloop with an initial timer.
+ * \param timer The timer to schedule on the thread.
+ * \return The new thread, or an invalid thread if an error occurred.
+ */
+ static thread detach(timer& timer);
/**
*/
int wait()
{
- int i;
- SDL_WaitThread(thread_, &i);
- thread_ = 0;
- return i;
+ if (thread_)
+ {
+ int i;
+ SDL_WaitThread(thread_, &i);
+ thread_ = 0;
+ return i;
+ }
+ return 1;
}
/**
* 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(thread_);
- thread_ = 0;
- }
+ void kill();
/**
* Get whether or not the thread object is associated with a real
}
-private:
+ /**
+ * Get the thread's runloop.
+ * \return The thread's runloop.
+ */
+ moof::runloop& runloop() const;
- thread(SDL_Thread* thread) :
- thread_(thread) {}
+ /**
+ * Get the runloop for the main thread.
+ * \return The runloop.
+ */
+ static moof::runloop& main_runloop();
- static int run(void* arg)
- {
- int code = (*(function*)arg)();
- delete (function*)arg;
- return code;
- }
+private:
+
+ static void spawn(thread* thread);
+ static int run(void* arg);
- SDL_Thread* thread_;
+
+ function function_;
+ SDL_Thread* thread_;
+ runloop_ptr runloop_;
};
* Construct a lock.
* \param mutex The mutex.
*/
- explicit lock(mutex& mutex) :
+ explicit lock(mutex& mutex, bool lock = true) :
mutex_(mutex),
- is_locked_(false) {}
+ is_locked_(false)
+ {
+ if (lock) if (!acquire()) throw "mutex lock not acquired";
+ }
/**
* Deconstruct a lock. The lock is automagically released if it is
friend class condition;
};
- /**
- * This type of lock tries to acquire a lock on the mutex during
- * construction and releases the lock on deconstruction.
- */
- class scoped_lock : private lock
- {
- public:
-
- /**
- * Construct a lock.
- * \param mutex The mutex.
- */
- explicit scoped_lock(mutex& mutex) :
- lock(mutex)
- {
- acquire();
- }
-
- /**
- * Get whether or not the mutex is locked.
- * \return True if the mutex is locked, false otherwise.
- */
- bool is_locked() const
- {
- return lock::is_locked();
- }
- };
-
private:
* Construct a lock.
* \param semaphore The semaphore.
*/
- explicit lock(semaphore& semaphore) :
+ explicit lock(semaphore& semaphore, bool lock = true) :
semaphore_(semaphore),
- is_locked_(false) {}
+ is_locked_(false)
+ {
+ if (lock) if (!acquire()) throw "semaphore lock not acquired";
+ }
/**
* Deconstruct a lock. The lock is automagically released if it is
semaphore& semaphore_;
bool is_locked_;
};
-
- /**
- * This type of lock tries to acquire a lock on the semaphore during
- * construction and releases the lock on deconstruction.
- */
- class scoped_lock : private lock
- {
- public:
-
- /**
- * Construct a lock.
- * \param semaphore The semaphore.
- */
- explicit scoped_lock(semaphore& semaphore) :
- lock(semaphore)
- {
- acquire();
- }
-
- /**
- * Get whether or not the semaphore is locked.
- * \return True if the semaphore is locked, false otherwise.
- */
- bool is_locked() const
- {
- return lock::is_locked();
- }
- };
private:
};
+#if ENABLE_THREADS
+#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)
+#else
+#define MOOF_DECLARE_MUTEX(M)
+#define MOOF_DECLARE_STATIC_MUTEX(M)
+#define MOOF_MUTEX_LOCK(M)
+#endif
+
+
} // namespace moof
#endif // _MOOF_THREAD_HH_