DCL 4.0
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#if __DCL_WINDOWS
9 #ifndef _WINDOWS_
10 #error "Required windows.h, See dcl/_windows.h"
11 #endif
12 #if __DCL_PTHREAD
13 #include <pthread.h>
14 #endif
15#else
16 #include <bits/pthreadtypes.h>
17 #define INFINITE -1
18#endif
19
20#ifndef __DCL_OBJECT_H__
21#include <dcl/Object.h>
22#endif
23#ifndef __DCL_STRING_H__
24#include <dcl/String.h>
25#endif
26
27__DCL_BEGIN_NAMESPACE
28
32class SysError;
33class DCLCAPI Thread : public Object
34{
35 DECLARE_CLASSINFO(Thread)
36public:
40 virtual String toString() const;
41
47 Thread(const char_t* _name = NULL);
48
53 void start() __DCL_THROWS1(SysError*);
54
60 int join();
61
67 bool started() const { return __threadId != 0; }
68
72 unsigned long id() const { return __threadId; }
73
77 const String& name() const { return __name; }
78
79protected:
91 virtual bool init();
92
96 virtual int run() = 0;
97
98private:
99 unsigned long __threadId;
100 String __name;
101
102#if __DCL_PTHREAD
103 static void* startRoutine(void* _pThread);
104#elif __DCL_WINDOWS
105 HANDLE __hThread;
106 static DWORD WINAPI startRoutine(void* _pThread);
107#endif
108
109public:
113 static void sleep(unsigned int _mills);
114
118 static void yield();
119
123 static unsigned long getCurrentThreadId();
124
130 static Thread* getCurrentThread();
131
135#if __DCL_PTHREAD
136 typedef pthread_once_t OnceType;
137 enum { ONCE_INIT = 0 /* PTHREAD_ONCE_INIT */ };
138#elif __DCL_WINDOWS
139 typedef long OnceType;
140 enum { ONCE_INIT = (long)0 };
141#endif
142 typedef void (* initRoutine)();
155 static void once(OnceType& _onceControl, initRoutine _initRoutine);
156
157#if __DCL_PTHREAD
158 typedef pthread_key_t KeyType;
159#elif __DCL_WINDOWS
160 typedef DWORD KeyType;
161#endif
162
173 static KeyType keyCreate() __DCL_THROWS1(SysError*);
174
183 static void keyDelete(KeyType _key) __DCL_THROWS1(SysError*);
184
193 static void keySetValue(KeyType _key, void* _value) __DCL_THROWS1(SysError*);
194
205 static void* keyGetValue(KeyType _key) __DCL_THROWS1(SysError*);
206
220 static void crtLock(const void* _p);
221 static void crtUnlock(const void* _p);
222
223 static long incrementAndGet(volatile long& _n);
224 static long long incrementAndGet(volatile long long& _n);
225 static long decrementAndGet(volatile long& _n);
226 static long long decrementAndGet(volatile long long& _n);
227
228public:
230 {
231 private:
232#if __DCL_PTHREAD
233 enum { READ_FD_INDEX = 0 };
234 int __fds[2];
235#elif __DCL_WINDOWS
236 HANDLE __hEvent;
237#endif
238
240#if __DCL_PTHREAD
241 int handle() { return __fds[READ_FD_INDEX]; }
242#elif __DCL_WINDOWS
243 HANDLE handle() { return __hEvent; }
244#endif
245
246 public:
247 Event();
248 ~Event();
249 void set();
250 void reset();
251
257 bool wait(unsigned int _milliseconds = INFINITE);
258 bool isWaiting() { return __bWaiting; }
259 private:
260 volatile bool __bWaiting;
261 };
262
264 {
265 private:
266#if __DCL_PTHREAD
267 pthread_mutex_t __mutex;
268#elif __DCL_WINDOWS
269 CRITICAL_SECTION __cs;
270#endif
271
272#if __DCL_WINDOWS
273 protected:
274 Mutex(DWORD _dwSpinCount);
275#endif
276 public:
277 Mutex();
278 ~Mutex();
279 void lock();
280 bool tryLock();
281 void unlock();
282 };
283
284#if __DCL_PTHREAD
285 class DCLCAPI SpinLock
286 {
287 private:
288 pthread_spinlock_t __spinLock;
289
290 public:
291 SpinLock(bool _pshared = false);
292 ~SpinLock();
293 void lock();
294 bool tryLock();
295 void unlock();
296 };
297#elif __DCL_WINDOWS
298 class DCLCAPI SpinLock : public Mutex
299 {
300 public:
301 SpinLock() : Mutex(INFINITE) { }
302 };
303#endif
304
305
306#if __DCL_PTHREAD || (__DCL_WINDOWS && _WIN32_WINNT >= 0x0600)
307 class DCLCAPI ReadWriteLock
308 {
309 private:
310#if __DCL_PTHREAD
311 pthread_rwlock_t __rwlock;
312#else
313 SRWLOCK __srwlock;
314#endif
315
316 public:
317 ReadWriteLock();
318 ~ReadWriteLock();
319 void readLock(); // WINNT AcquireSRWLockShared
320 void writeLock(); // WINNT AcquireSRWLockExclusive
321#if __DCL_PTHREAD
322 bool tryReadLock();
323 bool tryWriteLock();
324 void unlock();
325#else
326 void readUnlock(); // WINNT ReleaseSRWLockShared
327 void writeUnlock(); // WINNT ReleaseSRWLockExclusive
328#endif
329 };
330#endif
331
338 {
339 private:
340#if __DCL_PTHREAD
341 pthread_cond_t __cond;
342#elif __DCL_WINDOWS
343 #if _WIN32_WINNT >= 0x0600
344 CONDITION_VARIABLE __cond;
345 #else
346 Event __cond;
347 #endif
348#endif
349
350 public:
351 CondVar();
352 ~CondVar();
353 void signal();
354#if __DCL_PTHREAD || (__DCL_WINDOWS && _WIN32_WINNT >= 0x0600)
355 void broadcast();
356#endif
357
363 bool wait(Mutex& _mutex, unsigned int _milliseconds = INFINITE);
364#if __DCL_WINDOWS && _WIN32_WINNT >= 0x0600
365 bool wait(ReadWriteLock& _lock, bool shared, unsigned int _milliseconds = INFINITE);
366#endif
367 bool isWaiting() { return __bWaiting; }
368 private:
369 volatile bool __bWaiting;
370 };
371
372#if __DCL_PTHREAD
373 class DCLCAPI Barrier
374 {
375 private:
376 pthread_barrier_t __barrier;
377
378 public:
379 Barrier(unsigned int _count);
380 ~Barrier();
381 void wait();
382 };
383#endif
384
385 template<typename TYPE>
387 {
388 private:
389 TYPE& __lock; // Mutex or SpinLock
390
391 public:
392 SingleLock(TYPE& _lock) : __lock(_lock)
393 {
394 __lock.lock();
395 }
396
398 {
399 __lock.unlock();
400 }
401 };
402
405
406 template<typename TYPE>
408 {
409 private:
410 TYPE& __lock; // Mutex or SpinLock
411 bool __locked;
412 public:
413 SingleTryLock(TYPE& _lock) : __lock(_lock)
414 {
415 __locked = __lock.tryLock();
416 }
418 {
419 if (__locked)
420 __lock.unlock();
421 }
422 };
423
426
427};
428
429
430#if __DCL_WINDOWS
431inline long Thread::incrementAndGet(volatile long& _n)
432{
433 return InterlockedIncrement(&_n);
434}
435
436inline long Thread::decrementAndGet(volatile long& _n)
437{
438 return InterlockedDecrement(&_n);
439}
440
441#if _WIN32_WINNT >= 0x0600
442inline long long Thread::decrementAndGet(volatile long long& _n)
443{
444 return InterlockedDecrement64(&_n);
445}
446
447inline long long Thread::incrementAndGet(volatile long long& _n)
448{
449 return InterlockedIncrement64(&_n);
450}
451#endif
452#endif
453
454__DCL_END_NAMESPACE
455
456#endif // __DCL_THREAD_H__
#define NULL
Definition Config.h:340
#define DCLCAPI
Definition Config.h:100
wchar_t char_t
Definition Config.h:275
#define __protected
Definition Config.h:357
#define __DCL_THROWS1(e)
Definition Config.h:167
#define DECLARE_CLASSINFO(class_name)
Definition Object.h:210
#define INFINITE
Definition Thread.h:17
Object()
Definition Object.cpp:183
virtual String toString() const
Definition Object.cpp:187
bool isWaiting()
Definition Thread.h:367
bool wait(Mutex &_mutex, unsigned int _milliseconds=INFINITE)
Definition Thread.cpp:623
void unlock()
Definition Thread.cpp:469
void lock()
Definition Thread.cpp:447
bool tryLock()
Definition Thread.cpp:456
SingleLock(TYPE &_lock)
Definition Thread.h:392
SingleTryLock(TYPE &_lock)
Definition Thread.h:413
void(* initRoutine)()
Definition Thread.h:142
static void crtLock(const void *_p)
Definition Thread.cpp:262
SingleTryLock< Mutex > SingleTryLockMutex
Definition Thread.h:424
static long incrementAndGet(volatile long &_n)
static void crtUnlock(const void *_p)
Definition Thread.cpp:268
SingleTryLock< SpinLock > SingleTryLockSpin
Definition Thread.h:425
static void yield()
Definition Thread.cpp:163
static void sleep(unsigned int _mills)
Definition Thread.cpp:150
virtual bool init()
Definition Thread.cpp:97
static unsigned long getCurrentThreadId()
Definition Thread.cpp:173
static Thread * getCurrentThread()
Definition Thread.cpp:102
static long decrementAndGet(volatile long &_n)
virtual int run()=0
SingleLock< SpinLock > SingleLockSpin
Definition Thread.h:404
SingleLock< Mutex > SingleLockMutex
Definition Thread.h:403