]> git.tdb.fi Git - libs/core.git/blob - source/core/thread.cpp
Refactor Thread class with pimpl to avoid exposing platform-specific parts
[libs/core.git] / source / core / thread.cpp
1 /* $Id$
2
3 This file is part of libmspcore
4 Copyright © 2006 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #ifdef WIN32
9 #include <windows.h>
10 #else
11 #include <pthread.h>
12 #include <signal.h>
13 #endif
14 #include "thread.h"
15
16 namespace Msp {
17
18 struct Thread::Private
19 {
20 #ifdef WIN32
21         HANDLE handle;
22 #else
23         pthread_t handle;
24 #endif
25
26         Private(): handle(0) { }
27
28 #ifdef WIN32
29         static DWORD WINAPI main_wrapper(void *t)
30         { reinterpret_cast<Thread *>(t)->main(); return 0; }
31 #else
32         static void *main_wrapper(void *t)
33         { reinterpret_cast<Thread *>(t)->main(); return 0; }
34 #endif
35 };
36
37
38 Thread::Thread():
39         priv_(new Private),
40         launched_(false)
41 { }
42
43 Thread::~Thread()
44 {
45         if(launched_)
46         {
47                 kill();
48                 join();
49         }
50         delete priv_;
51 }
52
53 /**
54 Waits for the thread to exit.  Calling this from the thread will cause a
55 deadlock.
56 */
57 void Thread::join()
58 {
59         if(!launched_)
60                 return;
61
62 #ifdef WIN32
63         WaitForSingleObject(priv_->handle, INFINITE);
64 #else
65         pthread_join(priv_->handle, 0);
66 #endif
67         launched_ = false;
68 }
69
70 /**
71 Violently terminates the thread.
72 */
73 void Thread::kill()
74 {
75 #ifdef WIN32
76         TerminateThread(priv_->handle, 0);
77 #else
78         pthread_kill(priv_->handle, SIGKILL);
79 #endif
80 }
81
82 void Thread::launch()
83 {
84         if(launched_)
85                 return;
86
87 #ifdef WIN32
88         DWORD dummy;  // Win9x needs the lpTthreadId parameter
89         priv_->handle = CreateThread(0, 0, &Private::main_wrapper, this, 0, &dummy);
90 #else
91         pthread_create(&priv_->handle, 0, &Private::main_wrapper, this);
92 #endif
93         launched_ = true;
94 }
95
96 } // namespace Msp