-/* $Id$
-
-This file is part of libmspcore
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-#ifndef WIN32
-#include <signal.h>
-#endif
+#include <stdexcept>
#include "thread.h"
+#include "thread_private.h"
+
+using namespace std;
namespace Msp {
-/**
-Waits for the thread to exit. Calling this from the thread will cause a
-deadlock.
-*/
-void Thread::join()
-{
- if(!launched_)
- return;
+Thread::Thread():
+ priv_(new Private),
+ state_(PENDING)
+{ }
-#ifdef WIN32
- WaitForSingleObject(thread_, INFINITE);
-#else
- pthread_join(thread_, 0);
-#endif
- launched_=false;
+Thread::~Thread()
+{
+ kill();
+ join();
+ delete priv_;
}
-/**
-Requests the thread to terminate gracefully. Currently unimplemented on win32.
-*/
-void Thread::cancel()
+void Thread::join()
{
-#ifndef WIN32 //XXX
- pthread_cancel(thread_);
-#endif
+ if(state_>=JOINED)
+ return;
+
+ platform_join();
+ state_ = JOINED;
}
-/**
-Violently terminates the thread.
-*/
void Thread::kill()
{
-#ifdef WIN32
- TerminateThread(thread_, 0);
-#else
- pthread_kill(thread_, SIGKILL);
-#endif
-}
+ if(state_!=RUNNING)
+ return;
-Thread::~Thread()
-{
- if(launched_)
- kill();
+ platform_kill();
+ state_ = KILLED;
}
void Thread::launch()
{
- if(launched_)
- return;
+ if(state_>=RUNNING)
+ throw logic_error("already launched");
+
+ platform_launch();
+ state_ = RUNNING;
+}
-#ifdef WIN32
- DWORD dummy; // Win9x needs the lpTthreadId parameter
- thread_=CreateThread(0, 0, &main_, this, 0, &dummy);
-#else
- pthread_create(&thread_, 0, &main_, this);
-#endif
- launched_=true;
+ThreadReturn THREAD_CALL Thread::Private::main_wrapper(void *arg)
+{
+ Thread *thread = reinterpret_cast<Thread *>(arg);
+ thread->main();
+ thread->state_ = FINISHED;
+ return 0;
}
} // namespace Msp