DCL 3.7.4
Loading...
Searching...
No Matches
Thread.h
Go to the documentation of this file.
1#ifndef __DCL_THREAD_H__
2#define __DCL_THREAD_H__ 20110109
3
4#ifndef __DCL_CONFIG_H__
5#include <dcl/Config.h>
6#endif
7
8#ifdef __WINNT__
9 #if __DCL_PTHREAD
10 #include <pthread.h>
11 #define INFINITE (-1)
12 #define THREAD_ONCE_INIT PTHREAD_ONCE_INIT
13 typedef pthread_once_t thread_once_t;
14 typedef pthread_key_t thread_key_t;
15 #else
16 #ifndef _WINDOWS_
17 #error "Required windows.h, See dcl/_windows.h"
18 #endif
19 #if 0
20 #include <synchapi.h>
21 #endif
22 #define THREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
23 typedef INIT_ONCE thread_once_t;
24 typedef DWORD thread_key_t;
25 #endif
26#else
27 #if defined(__linux__)
28 #include <bits/pthreadtypes.h>
29 #elif defined(__APPLE__)
30 #include <sys/_pthread/_pthread_types.h>
31 #else
32 #include <pthread.h>
33 #endif
34 #define INFINITE (-1)
35 #define THREAD_ONCE_INIT PTHREAD_ONCE_INIT
36 typedef pthread_once_t thread_once_t;
37 typedef pthread_key_t thread_key_t;
38#endif
39
40#ifndef __DCL_OBJECT_H__
41#include <dcl/Object.h>
42#endif
43#ifndef __DCL_STRING_H__
44#include <dcl/String.h>
45#endif
46
47__DCL_BEGIN_NAMESPACE
48
52class SysError;
53
54class DCLCAPI Thread : public Object
55{
56 DECLARE_CLASSINFO(Thread)
57public:
61 virtual String toString() const;
62
68 Thread(const char_t* _name = NULL);
69
74 void start() __DCL_THROWS1(SysError*);
75
81 int join();
82
88 bool started() const { return __threadId != 0; }
89
93 thread_t thread() const { return __threadId; }
94
98 const String& name() const { return __name; }
99
100protected:
112 virtual bool init();
113
117 virtual int run() = 0;
118
119private:
120 thread_t __threadId;
121 String __name;
122
123#if __DCL_PTHREAD
124 static void* startRoutine(void* _pThread);
125#elif defined(__WINNT__)
126 HANDLE __hThread;
127 static DWORD WINAPI startRoutine(void* _pThread);
128#endif
129
130public:
134 static void sleep(unsigned int _mills);
135
139 static void yield();
140
144 static thread_t self();
145
151 static Thread* getSelfThread();
152
156 typedef void (* initRoutine)();
169 static void once(thread_once_t& _onceControl, initRoutine _initRoutine);
170
181 static thread_key_t keyCreate() __DCL_THROWS1(SysError*);
182
191 static void keyDelete(thread_key_t _key) __DCL_THROWS1(SysError*);
192
201 static void keySetValue(thread_key_t _key, void* _value) __DCL_THROWS1(SysError*);
202
213 static void* keyGetValue(thread_key_t _key) __DCL_THROWS1(SysError*);
214
228 static void crtLock(const void* _p);
229 static void crtUnlock(const void* _p);
230
231 static long incrementAndGet(volatile long& _n);
232 static long long incrementAndGet(volatile long long& _n);
233 static long decrementAndGet(volatile long& _n);
234 static long long decrementAndGet(volatile long long& _n);
235
236public:
238 {
239 private:
240#if __DCL_PTHREAD
241 enum { READ_FD_INDEX = 0 };
242 int __fds[2];
243#elif defined(__WINNT__)
244 HANDLE __hEvent;
245#endif
246
248#if __DCL_PTHREAD
249 int handle() { return __fds[READ_FD_INDEX]; }
250#elif defined(__WINNT__)
251 HANDLE handle() { return __hEvent; }
252#endif
253
254 public:
255 Event();
256 ~Event();
257 void set();
258 void reset();
259
265 bool wait(unsigned int _milliseconds = INFINITE);
266 bool isWaiting() { return __bWaiting; }
267 private:
268 volatile bool __bWaiting;
269 };
270
272 {
273 private:
274#if __DCL_PTHREAD
275 pthread_mutex_t __mutex;
276#elif defined(__WINNT__)
277 CRITICAL_SECTION __cs;
278#endif
279 volatile thread_t __locker;
280
281#ifdef __WINNT__
282 protected:
283 Mutex(DWORD _dwSpinCount);
284#endif
285 public:
286 Mutex();
287 ~Mutex();
288 void lock();
289 bool tryLock();
290 void unlock();
291 thread_t locker() const {
292 return __locker;
293 }
294 };
295
296#if __DCL_PTHREAD && !defined(__APPLE__)
297 class DCLCAPI SpinLock
298 {
299 private:
300 pthread_spinlock_t __spinLock;
301 volatile pthread_t __locker;
302
303 public:
304 SpinLock(bool _pshared = false);
305 ~SpinLock();
306 void lock();
307 bool tryLock();
308 void unlock();
309 pthread_t locker() const {
310 return __locker;
311 }
312 };
313#elif defined(__WINNT__)
314 class DCLCAPI SpinLock : public Mutex
315 {
316 public:
317 SpinLock() : Mutex(INFINITE) { }
318 };
319#endif
320
321#if __DCL_PTHREAD || (defined(__WINNT__) && _WIN32_WINNT >= 0x0600)
322 class DCLCAPI ReadWriteLock
323 {
324 private:
325#if __DCL_PTHREAD
326 pthread_rwlock_t __rwlock;
327#else
328 SRWLOCK __srwlock;
329#endif
330
331 public:
332 ReadWriteLock();
333 ~ReadWriteLock();
334 void readLock(); // WINNT AcquireSRWLockShared
335 void writeLock(); // WINNT AcquireSRWLockExclusive
336#if __DCL_PTHREAD
337 bool tryReadLock();
338 bool tryWriteLock();
339 void unlock();
340#else
341 void readUnlock(); // WINNT ReleaseSRWLockShared
342 void writeUnlock(); // WINNT ReleaseSRWLockExclusive
343#endif
344 };
345#endif
346
353 {
354 private:
355#if __DCL_PTHREAD
356 pthread_cond_t __cond;
357#elif defined(__WINNT__)
358 #if _WIN32_WINNT >= 0x0600
359 CONDITION_VARIABLE __cond;
360 #else
361 Event __cond;
362 #endif
363#endif
364
365 public:
366 CondVar();
367 ~CondVar();
368 void signal();
369#if __DCL_PTHREAD || (defined(__WINNT__) && _WIN32_WINNT >= 0x0600)
370 void broadcast();
371#endif
372
378 bool wait(Mutex& _mutex, unsigned int _milliseconds = INFINITE);
379#if defined(__WINNT__) && _WIN32_WINNT >= 0x0600
380 bool wait(ReadWriteLock& _lock, bool shared, unsigned int _milliseconds = INFINITE);
381#endif
382 bool isWaiting() { return __bWaiting; }
383 private:
384 volatile bool __bWaiting;
385 };
386
387#if __DCL_PTHREAD && !defined(__APPLE__)
388 class DCLCAPI Barrier
389 {
390 private:
391 pthread_barrier_t __barrier;
392
393 public:
394 Barrier(unsigned int _count);
395 ~Barrier();
396 void wait();
397 };
398#endif
399
400 template<typename TYPE>
402 {
403 private:
404 TYPE* __lock; // Mutex or SpinLock
405
406 public:
407 SingleLock(TYPE& _lock);
409 };
410
412 #ifndef __APPLE__
414 #endif
415};
416
417template<typename TYPE>
419{
420 if (_lock.locker() != Thread::self()) {
421 __lock = &_lock;
422 __lock->lock();
423 }
424 else {
425 __lock = NULL;
426 }
427}
428
429template<typename TYPE>
431{
432 if (__lock) {
433 __lock->unlock();
434 }
435}
436
437__DCL_END_NAMESPACE
438
439#endif // __DCL_THREAD_H__
#define NULL
Definition Config.h:312
#define DCLCAPI
Definition Config.h:95
wchar_t char_t
Definition Config.h:247
#define _PROTECTED
Definition Config.h:327
#define __DCL_THROWS1(e)
Definition Config.h:152
#define DECLARE_CLASSINFO(class_name)
Definition Object.h:227
pthread_t thread_t
Definition Object.h:27
pthread_key_t thread_key_t
Definition Thread.h:37
#define INFINITE
Definition Thread.h:34
pthread_once_t thread_once_t
Definition Thread.h:36
Object()
Definition Object.cpp:183
virtual String toString() const
Definition Object.cpp:187
bool isWaiting()
Definition Thread.h:382
bool wait(Mutex &_mutex, unsigned int _milliseconds=INFINITE)
Definition Thread.cpp:662
void unlock()
Definition Thread.cpp:499
void lock()
Definition Thread.cpp:472
thread_t locker() const
Definition Thread.h:291
bool tryLock()
Definition Thread.cpp:482
SingleLock(TYPE &_lock)
Definition Thread.h:418
void(* initRoutine)()
Definition Thread.h:156
static void crtLock(const void *_p)
Definition Thread.cpp:269
static long incrementAndGet(volatile long &_n)
static void crtUnlock(const void *_p)
Definition Thread.cpp:275
static void yield()
Definition Thread.cpp:165
static void sleep(unsigned int _mills)
Definition Thread.cpp:152
static thread_t self()
Definition Thread.cpp:175
virtual bool init()
Definition Thread.cpp:99
static long decrementAndGet(volatile long &_n)
static Thread * getSelfThread()
Definition Thread.cpp:104
virtual int run()=0
SingleLock< SpinLock > SingleLockSpin
Definition Thread.h:413
SingleLock< Mutex > SingleLockMutex
Definition Thread.h:411