-#ifdef WIN32
-#include <windows.h>
-#else
-#include <pthread.h>
-#include <signal.h>
-#endif
+#include <stdexcept>
#include "thread.h"
+#include "thread_private.h"
-namespace Msp {
-
-struct Thread::Private
-{
-#ifdef WIN32
- HANDLE handle;
-#else
- pthread_t handle;
-#endif
-
- Private(): handle(0) { }
-
-#ifdef WIN32
- static DWORD WINAPI main_wrapper(void *t)
- { reinterpret_cast<Thread *>(t)->main(); return 0; }
-#else
- static void *main_wrapper(void *t)
- { reinterpret_cast<Thread *>(t)->main(); return 0; }
-#endif
-};
+using namespace std;
+namespace Msp {
Thread::Thread():
priv_(new Private),
- launched_(false)
+ state_(PENDING)
{ }
Thread::~Thread()
{
- if(launched_)
- {
- kill();
- join();
- }
+ kill();
+ join();
delete priv_;
}
-/**
-Waits for the thread to exit. Calling this from the thread will cause a
-deadlock.
-*/
void Thread::join()
{
- if(!launched_)
+ if(state_>=JOINED)
return;
-#ifdef WIN32
- WaitForSingleObject(priv_->handle, INFINITE);
-#else
- pthread_join(priv_->handle, 0);
-#endif
- launched_ = false;
+ platform_join();
+ state_ = JOINED;
}
-/**
-Violently terminates the thread.
-*/
void Thread::kill()
{
-#ifdef WIN32
- TerminateThread(priv_->handle, 0);
-#else
- pthread_kill(priv_->handle, SIGKILL);
-#endif
+ if(state_!=RUNNING)
+ return;
+
+ platform_kill();
+ state_ = KILLED;
}
void Thread::launch()
{
- if(launched_)
- return;
+ if(state_>=RUNNING)
+ throw logic_error("already launched");
-#ifdef WIN32
- DWORD dummy; // Win9x needs the lpTthreadId parameter
- priv_->handle = CreateThread(0, 0, &Private::main_wrapper, this, 0, &dummy);
-#else
- pthread_create(&priv_->handle, 0, &Private::main_wrapper, this);
-#endif
- launched_ = true;
+ platform_launch();
+ state_ = RUNNING;
+}
+
+ThreadReturn THREAD_CALL Thread::Private::main_wrapper(void *arg)
+{
+ Thread *thread = reinterpret_cast<Thread *>(arg);
+ thread->main();
+ thread->state_ = FINISHED;
+ return 0;
}
} // namespace Msp