X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fcore%2Fthread.cpp;h=6c542e6a6712d4e19323fbd779c401abd7ea4215;hp=0fc86cf07c7cf18b23289438b9ecb84c5847dd2d;hb=a23176e6d3399bbeb75cf6a173543bf5d5f85187;hpb=47a232c3c19e718a30281d3ada8acc1b6212ea8c diff --git a/source/core/thread.cpp b/source/core/thread.cpp index 0fc86cf..6c542e6 100644 --- a/source/core/thread.cpp +++ b/source/core/thread.cpp @@ -1,77 +1,91 @@ -/* $Id$ - -This file is part of libmspcore -Copyright © 2006 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - -#ifndef WIN32 +#ifdef WIN32 +#include +#else +#include #include #endif +#include #include "thread.h" +using namespace std; + namespace Msp { -/** -Waits for the thread to exit. Calling this from the thread will cause a -deadlock. -*/ -void Thread::join() +struct Thread::Private { - if(!launched_) - return; +#ifdef WIN32 + HANDLE handle; +#else + pthread_t handle; +#endif + + Private(): handle(0) { } #ifdef WIN32 - WaitForSingleObject(thread_, INFINITE); + static DWORD WINAPI #else - pthread_join(thread_, 0); + static void * #endif - launched_=false; -} + main_wrapper(void *a) + { + Thread *t = reinterpret_cast(a); + t->main(); + t->state_ = FINISHED; + return 0; + } +}; + + +Thread::Thread(): + priv_(new Private), + state_(PENDING) +{ } -/** -Requests the thread to terminate gracefully. Currently unimplemented on win32. -*/ -void Thread::cancel() +Thread::~Thread() { -#ifndef WIN32 //XXX - pthread_cancel(thread_); -#endif + kill(); + join(); + delete priv_; } -/** -Violently terminates the thread. -*/ -void Thread::kill() +void Thread::join() { + if(state_>=JOINED) + return; + #ifdef WIN32 - TerminateThread(thread_, 0); + WaitForSingleObject(priv_->handle, INFINITE); #else - pthread_kill(thread_, SIGKILL); + pthread_join(priv_->handle, 0); #endif + state_ = JOINED; } -Thread::~Thread() +void Thread::kill() { - if(launched_) - { - kill(); - join(); - } + 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 - thread_=CreateThread(0, 0, &main_, this, 0, &dummy); + priv_->handle = CreateThread(0, 0, &Private::main_wrapper, this, 0, &dummy); #else - pthread_create(&thread_, 0, &main_, this); + pthread_create(&priv_->handle, 0, &Private::main_wrapper, this); #endif - launched_=true; + state_ = RUNNING; } } // namespace Msp