#include <pthread.h>
#include <signal.h>
#endif
+#include <stdexcept>
#include "thread.h"
+using namespace std;
+
namespace Msp {
struct Thread::Private
Private(): handle(0) { }
#ifdef WIN32
- static DWORD WINAPI main_wrapper(void *t)
- { reinterpret_cast<Thread *>(t)->main(); return 0; }
+ static DWORD WINAPI
#else
- static void *main_wrapper(void *t)
- { reinterpret_cast<Thread *>(t)->main(); return 0; }
+ static void *
#endif
+ main_wrapper(void *a)
+ {
+ Thread *t = reinterpret_cast<Thread *>(a);
+ t->main();
+ t->state_ = FINISHED;
+ return 0;
+ }
};
Thread::Thread():
priv_(new Private),
- launched_(false)
+ state_(PENDING)
{ }
Thread::~Thread()
{
- if(launched_)
- {
- kill();
- join();
- }
+ kill();
+ join();
delete priv_;
}
void Thread::join()
{
- if(!launched_)
+ if(state_>=JOINED)
return;
#ifdef WIN32
#else
pthread_join(priv_->handle, 0);
#endif
- launched_ = false;
+ state_ = JOINED;
}
void Thread::kill()
{
+ if(state_!=RUNNING)
+ return;
+
#ifdef WIN32
TerminateThread(priv_->handle, 0);
#else
pthread_kill(priv_->handle, SIGKILL);
#endif
+ 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
#else
pthread_create(&priv_->handle, 0, &Private::main_wrapper, this);
#endif
- launched_ = true;
+ state_ = RUNNING;
}
} // namespace Msp