Scopira  20080306
thread_qtthreads.h
1 
2 /*
3  * Copyright (c) 2009 National Research Council
4  *
5  * All rights reserved.
6  *
7  * This material is confidential and proprietary information of
8  * National Research Council Canada ("Confidential Information").
9  * This Confidential Information may only be used and reproduced
10  * in accordance with the terms of the license agreement.
11  *
12  */
13 
14 #ifndef __INCLUDED_SCOPIRA_TOOL_THREAD_PTHREADS_H__
15 #define __INCLUDED_SCOPIRA_TOOL_THREAD_PTHREADS_H__
16 
17 #include <QThread>
18 #include <QReadWriteLock>
19 #include <QWaitCondition>
20 
21 #include <scopira/tool/platform.h>
22 #include <scopira/tool/export.h>
23 
24 #include <scopira/tool/object.h>
25 
26 
27 namespace scopira
28 {
29  namespace tool
30  {
31  class runnable_i;
32  class job_i;
33 
36  typedef void* (*runfunc_t)(void*);
37  class thread;
38 
39  class condition;
40 
41  class rwlock;
42  class read_locker;
43  class write_locker;
44 
51  SCOPIRA_EXPORT int num_system_cpus(void);
52 
53  template <class T> class shared_area;
54  template <class T> class event_area;
55  template <class T> class rw_area;
56 
57  template <class T> class area_ptr;
58  template <class T> class const_area_ptr;
59  template <class T> class locker_ptr;
60  template <class T> class event_ptr;
61  template <class T> class read_locker_ptr;
62  template <class T> class write_locker_ptr;
63  }
64 }
65 
72 {
73  public:
78  SCOPIRA_EXPORT virtual void run(void) = 0;
79 
80  protected:
81  virtual ~runnable_i() { }
82 };
83 
89 class scopira::tool::job_i : public virtual scopira::tool::object
90 {
91  public:
93  SCOPIRA_EXPORT virtual void start(void) = 0;
94 
96  SCOPIRA_EXPORT virtual void notify_stop(void) = 0;
97 
99  SCOPIRA_EXPORT virtual void wait_stop(void) = 0;
100 
102  SCOPIRA_EXPORT virtual bool is_running(void) const = 0;
103 };
104 
110 class scopira::tool::thread : public virtual scopira::tool::job_i,
111  public virtual scopira::tool::runnable_i
112 {
113  public:
114  typedef int tlskey_t;
115 
116  protected:
117  runnable_i *dm_target;
118  runfunc_t dm_runfunc;
119  void *dm_runfunc_arg;
120 
121  class myQThread : public QThread
122  {
123  public:
124  myQThread(scopira::tool::thread *parent) : dm_parent(parent) { }
125  protected:
126  virtual void run(void) { dm_parent->run(); }
127  private:
128  scopira::tool::thread *dm_parent;
129  } dm_thread;
130 
131  public:
144  SCOPIRA_EXPORT thread(runnable_i* target);
155  SCOPIRA_EXPORT thread(runfunc_t func, void *arg);
156 
158  SCOPIRA_EXPORT virtual ~thread();
159 
161  SCOPIRA_EXPORT virtual void run(void);
162 
164  SCOPIRA_EXPORT virtual void start(void);
167  SCOPIRA_EXPORT virtual void notify_stop(void);
169  SCOPIRA_EXPORT virtual void wait_stop(void);
171  SCOPIRA_EXPORT virtual bool is_running(void) const { return dm_thread.isRunning(); }
172 
179  SCOPIRA_EXPORT static void sleep(int msec);
180 
190  SCOPIRA_EXPORT static void open_tls(tlskey_t &outkey);
196  SCOPIRA_EXPORT static void close_tls(tlskey_t k);
197 
205  SCOPIRA_EXPORT static void set_tls(tlskey_t k, void *val);
213  SCOPIRA_EXPORT static void * get_tls(tlskey_t k);
214 };
215 
227 {
228  protected:
229  QWaitCondition dm_con;
230 
231  public:
235  SCOPIRA_EXPORT condition(void);
237  SCOPIRA_EXPORT ~condition();
238 
244  SCOPIRA_EXPORT void notify(void);
250  SCOPIRA_EXPORT void notify_all(void);
259  SCOPIRA_EXPORT void wait(mutex &mut);
271  SCOPIRA_EXPORT bool wait(mutex &mut, int msec);
272 };
273 
280 {
281  private:
282  QReadWriteLock dm_rw;
283 
284  public:
286  SCOPIRA_EXPORT rwlock(void);
288  SCOPIRA_EXPORT ~rwlock();
289 
291  SCOPIRA_EXPORT void write_lock(void);
293  SCOPIRA_EXPORT bool try_write_lock(void);
295  SCOPIRA_EXPORT void read_lock(void);
297  SCOPIRA_EXPORT bool try_read_lock(void);
299  SCOPIRA_EXPORT void unlock(void);
300 };
301 
308 {
309  private:
310  scopira::tool::rwlock &dm_rw;
311  public:
313  read_locker(rwlock &rw) : dm_rw(rw) { dm_rw.read_lock(); }
315  ~read_locker() { dm_rw.unlock(); }
316 };
317 
324 {
325  private:
326  scopira::tool::rwlock &dm_rw;
327 
328  public:
330  write_locker(rwlock &rw) : dm_rw(rw) { dm_rw.write_lock(); }
332  ~write_locker() { dm_rw.unlock(); }
333 };
334 
342 template <class T> class scopira::tool::shared_area
343 {
344  public:
345  volatile T pm_data;
346  mutable scopira::tool::mutex pm_mutex;
347 };
348 
355 template <class T> class scopira::tool::event_area : public scopira::tool::shared_area<T>
356 {
357  public:
358  mutable scopira::tool::condition pm_condition;
359 };
360 
367 template <class T> class scopira::tool::rw_area
368 {
369  public:
370  volatile T pm_data;
371  mutable scopira::tool::rwlock pm_rwlock;
372 };
373 
387 template <class T> class scopira::tool::area_ptr
388 {
389  protected:
390  T* dm_ptr;
391 
392  public:
397  area_ptr(const shared_area<T>& ref) : dm_ptr(const_cast<T*>(&ref.pm_data)) { }
402  area_ptr(const rw_area<T>& ref) : dm_ptr(const_cast<T*>(&ref.pm_data)) { }
403 
404  protected:
409  area_ptr(const volatile T& ref) : dm_ptr(const_cast<T*>(&ref)) { }
410 
411  public:
413  T* get(void) { return dm_ptr; }
415  T& operator*(void) { return *dm_ptr; }
417  T* operator->(void) { return dm_ptr; }
418 
425  void reset(void) { dm_ptr = const_cast<T*>(const_cast<volatile T*>(dm_ptr)); } // this is whacky :)
426 };
427 
440 template <class T> class scopira::tool::const_area_ptr
441 {
442  protected:
443  const T* dm_ptr;
444 
445  public:
450  const_area_ptr(const shared_area<T>& ref) : dm_ptr(const_cast<const T*>(&ref.pm_data)) { }
455  const_area_ptr(const rw_area<T>& ref) : dm_ptr(const_cast<const T*>(&ref.pm_data)) { }
456 
457  protected:
462  const_area_ptr(const volatile T& ref) : dm_ptr(const_cast<T*>(&ref)) { }
463 
464  public:
466  const T* get(void) { return dm_ptr; }
468  const T& operator*(void) { return *dm_ptr; }
470  const T* operator->(void) { return dm_ptr; }
471 
478  void reset(void) { dm_ptr = const_cast<const T*>(const_cast<volatile T*>(dm_ptr)); } // this is whacky :)
479 };
480 
488 template <class T> class scopira::tool::locker_ptr : public scopira::tool::area_ptr<T>
489 {
490  protected:
491  scopira::tool::mutex & dm_mut;
492 
493  public:
495  locker_ptr(const shared_area<T>& ref) : area_ptr<T>(ref.pm_data), dm_mut(ref.pm_mutex) { dm_mut.lock(); }
496 
498  ~locker_ptr() { dm_mut.unlock(); }
499  private:
500 };
501 
507 template <class T> class scopira::tool::event_ptr : public scopira::tool::locker_ptr<T>
508 {
509  protected:
510  scopira::tool::condition & dm_cond;
511 
512  public:
514  event_ptr(const event_area<T>& ref) : locker_ptr<T>(ref), dm_cond(ref.pm_condition) { }
515 
523  void notify(void) { dm_cond.notify(); }
531  void notify_all(void) { dm_cond.notify_all(); }
540  void wait(void) { dm_cond.wait(locker_ptr<T>::dm_mut); }
550  bool wait(int msec) { return dm_cond.wait(locker_ptr<T>::dm_mut, msec); }
551 };
552 
558 template <class T> class scopira::tool::read_locker_ptr : public scopira::tool::const_area_ptr<T>
559 {
560  protected:
561  scopira::tool::rwlock & dm_rw;
562 
563  public:
565  read_locker_ptr(const rw_area<T>& ref) : const_area_ptr<T>(ref.pm_data), dm_rw(ref.pm_rwlock) { dm_rw.read_lock(); }
566 
568  ~read_locker_ptr() { dm_rw.unlock(); }
569 };
570 
576 template <class T> class scopira::tool::write_locker_ptr : public scopira::tool::area_ptr<T>
577 {
578  protected:
579  scopira::tool::rwlock & dm_rw;
580 
581  public:
583  write_locker_ptr(const rw_area<T>& ref) : area_ptr<T>(ref.pm_data), dm_rw(ref.pm_rwlock) { dm_rw.write_lock(); }
584 
586  ~write_locker_ptr() { dm_rw.unlock(); }
587 };
588 
589 #endif
590 
591 
virtual bool is_running(void) const
is this thread currently running?
Definition: thread_qtthreads.h:171
Definition: thread_pthreads.h:220
Definition: thread_pthreads.h:56
event_ptr(const event_area< T > &ref)
ctor
Definition: thread_qtthreads.h:514
const_area_ptr(const volatile T &ref)
Definition: thread_qtthreads.h:462
Definition: mutex_pthreads.h:40
area_ptr(const shared_area< T > &ref)
Definition: thread_qtthreads.h:397
Definition: thread_pthreads.h:57
write_locker_ptr(const rw_area< T > &ref)
ctor
Definition: thread_qtthreads.h:583
Definition: archiveflow.h:20
write_locker(rwlock &rw)
read locks the given rwlock
Definition: thread_qtthreads.h:330
void unlock(void)
unlocks the rwlock (unclocks both WRITE and READ locks)
Definition: thread_pthreads.h:60
T * operator->(void)
pointer behaviour
Definition: thread_qtthreads.h:417
~read_locker()
unlocks the given rwlock
Definition: thread_qtthreads.h:315
~write_locker()
unlocks the given rwlock
Definition: thread_qtthreads.h:332
const_area_ptr(const shared_area< T > &ref)
Definition: thread_qtthreads.h:450
~read_locker_ptr()
dtor
Definition: thread_qtthreads.h:568
Definition: object.h:71
Definition: thread_pthreads.h:317
virtual void run(void)=0
void notify(void)
Definition: thread_qtthreads.h:523
int num_system_cpus(void)
read_locker(rwlock &rw)
read locks the given rwlock
Definition: thread_qtthreads.h:313
Definition: thread_pthreads.h:69
void lock(void)
Definition: mutex_pthreads.h:55
void wait(mutex &mut)
area_ptr(const rw_area< T > &ref)
Definition: thread_qtthreads.h:402
Definition: thread_pthreads.h:87
const_area_ptr(const rw_area< T > &ref)
Definition: thread_qtthreads.h:455
void read_lock(void)
locks the rwlock in READ mode
Definition: thread_pthreads.h:108
Definition: thread_pthreads.h:58
const T & operator*(void)
pointer behaviour
Definition: thread_qtthreads.h:468
~locker_ptr()
dtor
Definition: thread_qtthreads.h:498
void unlock(void)
Definition: mutex_pthreads.h:63
void reset(void)
Definition: thread_qtthreads.h:478
void write_lock(void)
locks the rwlock in WRITE mode
read_locker_ptr(const rw_area< T > &ref)
ctor
Definition: thread_qtthreads.h:565
T & operator*(void)
pointer behaviour
Definition: thread_qtthreads.h:415
Definition: thread_pthreads.h:51
Definition: thread_pthreads.h:53
Definition: thread_qtthreads.h:121
void notify_all(void)
Definition: thread_qtthreads.h:531
~write_locker_ptr()
dtor
Definition: thread_qtthreads.h:586
void *(* runfunc_t)(void *)
Definition: thread_pthreads.h:34
Definition: thread_pthreads.h:273
locker_ptr(const shared_area< T > &ref)
ctor
Definition: thread_qtthreads.h:495
area_ptr(const volatile T &ref)
Definition: thread_qtthreads.h:409
Definition: thread_pthreads.h:52
bool wait(int msec)
Definition: thread_qtthreads.h:550
Definition: thread_pthreads.h:55
void reset(void)
Definition: thread_qtthreads.h:425
Definition: thread_pthreads.h:59
const T * operator->(void)
pointer behaviour
Definition: thread_qtthreads.h:470
Definition: thread_pthreads.h:301
void wait(void)
Definition: thread_qtthreads.h:540