]> git.tdb.fi Git - libs/core.git/blob - source/core/thread.cpp
6c542e6a6712d4e19323fbd779c401abd7ea4215
[libs/core.git] / source / core / thread.cpp
1 #ifdef WIN32
2 #include <windows.h>
3 #else
4 #include <pthread.h>
5 #include <signal.h>
6 #endif
7 #include <stdexcept>
8 #include "thread.h"
9
10 using namespace std;
11
12 namespace Msp {
13
14 struct Thread::Private
15 {
16 #ifdef WIN32
17         HANDLE handle;
18 #else
19         pthread_t handle;
20 #endif
21
22         Private(): handle(0) { }
23
24 #ifdef WIN32
25         static DWORD WINAPI
26 #else
27         static void *
28 #endif
29         main_wrapper(void *a)
30         {
31                 Thread *t = reinterpret_cast<Thread *>(a);
32                 t->main();
33                 t->state_ = FINISHED;
34                 return 0;
35         }
36 };
37
38
39 Thread::Thread():
40         priv_(new Private),
41         state_(PENDING)
42 { }
43
44 Thread::~Thread()
45 {
46         kill();
47         join();
48         delete priv_;
49 }
50
51 void Thread::join()
52 {
53         if(state_>=JOINED)
54                 return;
55
56 #ifdef WIN32
57         WaitForSingleObject(priv_->handle, INFINITE);
58 #else
59         pthread_join(priv_->handle, 0);
60 #endif
61         state_ = JOINED;
62 }
63
64 void Thread::kill()
65 {
66         if(state_!=RUNNING)
67                 return;
68
69 #ifdef WIN32
70         TerminateThread(priv_->handle, 0);
71 #else
72         pthread_kill(priv_->handle, SIGKILL);
73 #endif
74         state_ = KILLED;
75 }
76
77 void Thread::launch()
78 {
79         if(state_>=RUNNING)
80                 throw logic_error("already launched");
81
82 #ifdef WIN32
83         DWORD dummy;  // Win9x needs the lpTthreadId parameter
84         priv_->handle = CreateThread(0, 0, &Private::main_wrapper, this, 0, &dummy);
85 #else
86         pthread_create(&priv_->handle, 0, &Private::main_wrapper, this);
87 #endif
88         state_ = RUNNING;
89 }
90
91 } // namespace Msp