ucommon
thread.h
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
23 #ifndef COMMONCPP_THREAD_H_
24 #define COMMONCPP_THREAD_H_
25 
26 #ifndef COMMONCPP_CONFIG_H_
27 #include <commoncpp/config.h>
28 #endif
29 
30 #ifndef COMMONCPP_STRING_H_
31 #include <commoncpp/string.h>
32 #endif
33 
34 #define ENTER_CRITICAL enterMutex();
35 #define LEAVE_CRITICAL leaveMutex();
36 
37 NAMESPACE_COMMONCPP
38 
39 class __EXPORT Mutex : protected ucommon::RecursiveMutex
40 {
41 public:
42  inline Mutex() : RecursiveMutex() {};
43 
44  inline void enterMutex(void)
46 
47  inline void leaveMutex(void)
49 
50  inline bool tryEnterMutex(void)
51  {return RecursiveMutex::lock(0l);};
52 
53  inline void enter(void)
55 
56  inline void leave(void)
58 
59  inline bool test(void)
60  {return RecursiveMutex::lock(0l);};
61 
62 };
63 
73 class __EXPORT MutexCounter : public Mutex
74 {
75 protected:
76  volatile int counter;
77 
78 public:
82  MutexCounter();
83 
90  MutexCounter(int initial);
91 
92  int operator++();
93  int operator--();
94 };
95 
119 class __EXPORT MutexLock
120 {
121 private:
122  Mutex& mutex;
123 
124 public:
130  inline MutexLock( Mutex& _mutex ) : mutex( _mutex )
131  { mutex.enterMutex(); }
132 
136  // this should be not-virtual
137  inline ~MutexLock()
138  { mutex.leaveMutex(); }
139 };
140 
141 class __EXPORT ThreadLock : protected ucommon::ThreadLock
142 {
143 public:
144  inline ThreadLock() : ucommon::ThreadLock() {};
145 
146  inline void readLock(void)
148 
149  inline void writeLock(void)
151 
152  inline void tryReadLock(void)
154 
155  inline void tryWriteLock(void)
157 
158  inline void unlock(void)
160 };
161 
182 class __EXPORT ReadLock
183 {
184 private:
185  ThreadLock& tl;
186 
187 public:
193  inline ReadLock( ThreadLock& _tl ) : tl( _tl )
194  { tl.readLock(); }
198  // this should be not-virtual
199  inline ~ReadLock()
200  { tl.unlock(); }
201 };
202 
223 class __EXPORT WriteLock
224 {
225 private:
226  ThreadLock& tl;
227 
228 public:
234  inline WriteLock( ThreadLock& _tl ) : tl( _tl )
235  { tl.writeLock(); }
239  // this should be not-virtual
240  inline ~WriteLock()
241  { tl.unlock(); }
242 };
243 
244 class __EXPORT Conditional : private ucommon::Conditional
245 {
246 public:
247  inline Conditional() : ucommon::Conditional() {};
248 
249  bool wait(timeout_t timeout, bool locked = false);
250 
251  void signal(bool broadcast);
252 
253  inline void enterMutex(void)
255 
256  inline void leaveMutex(void)
258 };
259 
260 class __EXPORT Semaphore : private ucommon::Semaphore
261 {
262 public:
263  inline Semaphore(unsigned size=0) : ucommon::Semaphore(size) {};
264 
265  inline bool wait(timeout_t timeout = 0)
266  {return ucommon::Semaphore::wait(timeout);};
267 
268  inline void post(void)
270 };
271 
291 class __EXPORT SemaphoreLock
292 {
293 private:
294  Semaphore& sem;
295 
296 public:
300  inline SemaphoreLock( Semaphore& _sem ) : sem( _sem )
301  { sem.wait(); }
305  // this should be not-virtual
306  inline ~SemaphoreLock()
307  { sem.post(); }
308 };
309 
310 class __EXPORT Event : private ucommon::TimedEvent
311 {
312 public:
313  inline Event() : TimedEvent() {};
314 
315  inline void wait(void)
316  {ucommon::TimedEvent::wait(Timer::inf);};
317 
318  inline bool wait(timeout_t timeout)
319  {return ucommon::TimedEvent::wait(timeout);};
320 
321  inline void signal(void)
323 
324  inline void reset(void)
326 };
327 
328 class __EXPORT Thread : protected ucommon::JoinableThread
329 {
330 public:
334  typedef enum Throw {
335  throwNothing,
336  throwObject,
337  throwException
338  } Throw;
339 
340 private:
341  friend class Slog;
342 
343  Throw exceptions;
344  bool detached, terminated;
345  Thread *parent;
346  size_t msgpos;
347  char msgbuf[128];
348 
349 public:
350  Thread(int pri = 0, size_t stack = 0);
351 
352  virtual ~Thread();
353 
354  inline void map(void)
355  {JoinableThread::map();};
356 
357  virtual void initial(void);
358  virtual void notify(Thread *thread);
359  virtual void final(void);
360  virtual void run(void) = 0;
361 
362  void terminate(void);
363  void finalize(void);
364 
365  void detach(void);
366  void start(void);
367  void exit(void);
368 
369  inline void join(void)
371 
372  inline void sync(void)
373  {Thread::exit();};
374 
375  static inline Thread *get(void)
376  {return (Thread *)JoinableThread::get();};
377 
378  inline static void yield(void)
380 
381  inline static void sleep(timeout_t msec = TIMEOUT_INF)
382  {ucommon::Thread::sleep(msec);};
383 
384  bool isRunning(void);
385 
386  bool isThread(void);
387 
393  static Throw getException(void);
394 
400  static void setException(Throw mode);
401 
405  inline pthread_t getId(void)
406  {return tid;};
407 };
408 
438 class __EXPORT SysTime
439 {
440 public:
441  static time_t getTime(time_t *tloc = NULL);
442  static time_t time(time_t *tloc)
443  { return getTime(tloc); };
444 
445  static int getTimeOfDay(struct timeval *tp);
446  static int gettimeofday(struct timeval *tp, struct timezone *)
447  { return getTimeOfDay(tp); };
448 
449  static struct tm *getLocalTime(const time_t *clock, struct tm *result);
450  static struct tm *locatime(const time_t *clock, struct tm *result)
451  { return getLocalTime(clock, result); };
452 
453  static struct tm *getGMTTime(const time_t *clock, struct tm *result);
454  static struct tm *gmtime(const time_t *clock, struct tm *result)
455  { return getGMTTime(clock, result);};
456 };
457 
468 class __EXPORT TimerPort
469 {
470 #ifndef _MSWINDOWS_
471  struct timeval timer;
472 #else
473  DWORD timer;
474 #endif
475  bool active;
476 
477 public:
484  TimerPort();
485 
494  void setTimer(timeout_t timeout = 0);
495 
505  void incTimer(timeout_t timeout);
506 
516  void decTimer(timeout_t timeout);
517 
522  void sleepTimer(void);
523 
529  void endTimer(void);
530 
542  timeout_t getTimer(void) const;
543 
553  timeout_t getElapsed(void) const;
554 };
555 
556 #ifndef _MSWINDOWS_
557 struct timespec *getTimeout(struct timespec *spec, timeout_t timeout);
558 #endif
559 
560 inline struct tm *localtime_r(const time_t *t, struct tm *b)
561  {return SysTime::getLocalTime(t, b);}
562 
563 inline char *ctime_r(const time_t *t, char *buf)
564  {return ctime(t);}
565 
566 inline struct tm *gmtime_r(const time_t *t, struct tm *b)
567  {return SysTime::getGMTTime(t, b);}
568 
569 inline char *asctime_r(const struct tm *tm, char *b)
570  {return asctime(tm);}
571 
572 inline Thread *getThread(void)
573  {return Thread::get();}
574 
596 #ifdef _MSWINDOWS_
597 class __EXPORT Buffer : public Mutex
598 #else
599 class __EXPORT Buffer : public Conditional
600 #endif
601 {
602 private:
603 #ifdef _MSWINDOWS_
604  HANDLE sem_head, sem_tail;
605 #endif
606  size_t _size;
607  size_t _used;
608 
609 protected:
615  virtual size_t onPeek(void *buf) = 0;
616 
622  virtual size_t onWait(void *buf) = 0;
623 
629  virtual size_t onPost(void *buf) = 0;
630 
631 public:
636  static const size_t timeout;
637 
642  Buffer(size_t capacity);
647  virtual ~Buffer();
648 
653  inline size_t getSize(void)
654  {return _size;};
655 
662  inline size_t getUsed(void)
663  {return _used;};
664 
674  size_t wait(void *buf, timeout_t timeout = 0);
675 
684  size_t post(void *buf, timeout_t timeout = 0);
685 
692  size_t peek(void *buf);
693 
698  virtual bool isValid(void);
699 };
700 
708 class __EXPORT FixedBuffer : public Buffer
709 {
710 private:
711  char *buf, *head, *tail;
712  size_t objsize;
713 
714 protected:
720  size_t onPeek(void *buf);
721 
727  size_t onWait(void *buf);
728 
734  size_t onPost(void *buf);
735 
736 public:
744  FixedBuffer(size_t capacity, size_t objsize);
745 
752  FixedBuffer(const FixedBuffer &fb);
753 
757  virtual ~FixedBuffer();
758 
759  FixedBuffer &operator=(const FixedBuffer &fb);
760 
761  bool isValid(void);
762 };
763 
779 class __EXPORT ThreadQueue : public Mutex, public Thread, public Semaphore
780 {
781 private:
782  void run(void); // private run method
783 
784 protected:
785  typedef struct _data {
786  struct _data *next;
787  unsigned len;
788  char data[1];
789  } data_t;
790 
791  timeout_t timeout;
792  bool started;
793 
794  data_t *first, *last; // head/tail of list
795 
796  String name;
797 
798  /*
799  * Overloading of final(). It demarks Semaphore to avoid deadlock.
800  */
801  virtual void final();
802 
807  virtual void startQueue(void);
808 
814  virtual void stopQueue(void);
815 
819  virtual void onTimer(void);
820 
829  virtual void runQueue(void *data) = 0;
830 
831 public:
839  ThreadQueue(const char *id, int pri, size_t stack = 0);
840 
844  virtual ~ThreadQueue();
845 
853  void setTimer(timeout_t timeout);
854 
863  void post(const void *data, unsigned len);
864 };
865 
866 
868 inline size_t get(Buffer &b, void *o, timeout_t t = 0)
869  {return b.wait(o, t);}
870 
872 inline size_t put(Buffer &b, void *o, timeout_t t = 0)
873  {return b.post(o, t);}
874 
876 inline size_t peek(Buffer &b, void *o)
877  {return b.peek(o);}
878 
879 END_NAMESPACE
880 
881 #endif
virtual bool isValid(void)
New virtual to test if buffer is a valid object.
Semaphore(unsigned count=0)
Construct a semaphore with an initial count of threads to permit.
void release(void)
Release the semaphore after waiting for it.
virtual void run(void)=0
Abstract interface for thread context run method.
void unlock(void)
Unlock the conditional&#39;s supporting mutex.
Definition: thread.h:154
Common C++ generic string class.
virtual size_t onPost(void *buf)=0
Invoke derived class posting of object to buffer.
void reset(void)
Reset triggered conditional.
A portable counting semaphore class.
Definition: thread.h:853
static void yield(void)
Yield execution context of the current thread.
void modify(void)
Exclusive mode write thread scheduling.
void lock(void)
Lock the conditional&#39;s supporting mutex.
Definition: thread.h:148
Event notification to manage scheduled realtime threads.
Definition: thread.h:365
The Mutex Counter is a counter variable which can safely be incremented or decremented by multiple th...
Definition: thread.h:73
void join(void)
Join thread with parent.
The conditional is a common base for other thread synchronizing classes.
Definition: thread.h:86
void wait(void)
Wait (block) until signalled.
Definition: thread.h:160
virtual size_t onPeek(void *buf)=0
Invoke derived class buffer peeking method.
void signal(void)
Signal the conditional to release one waiting thread.
Definition: thread.h:166
void access(void)
Access mode shared thread scheduling.
This class is used to access non-reentrant date and time functions in the standard C library...
Definition: thread.h:438
A generic and portable implimentation of Read/Write locking.
Definition: thread.h:498
size_t getUsed(void)
Return the current capacity in use for the buffer.
Definition: thread.h:662
ReadLock(ThreadLock &_tl)
Wait for read access.
Definition: thread.h:193
Somewhat generic queue processing class to establish a producer consumer queue.
Definition: thread.h:779
void signal(void)
Signal pending event.
Portable recursive exclusive lock.
Definition: thread.h:454
Buffer(size_t capacity)
Create a buffer object of known capacity.
size_t post(void *buf, timeout_t timeout=0)
Post an object into the buffer and enable a waiting thread to receive it.
MutexLock(Mutex &_mutex)
Acquire the mutex.
Definition: thread.h:130
void unlock(void)
Unlock the conditional&#39;s supporting mutex.
Definition: thread.h:289
Thread(size_t stack=0)
Create a thread object that will have a preset stack size.
A buffer class that holds a known capacity of fixed sized objects defined during creation.
Definition: thread.h:708
void release(void)
Release the lock.
virtual size_t onWait(void *buf)=0
Invoke derived class object request from buffer.
~SemaphoreLock()
Post the semaphore automatically.
Definition: thread.h:306
size_t peek(Buffer &b, void *o)
Definition: thread.h:876
unsigned long timeout_t
Typedef for millisecond timer values.
Definition: platform.h:326
WriteLock(ThreadLock &_tl)
Wait for write access.
Definition: thread.h:234
The WriteLock class is used to protect a section of code through a ThreadLock for &quot;write&quot; access to t...
Definition: thread.h:223
The ReadLock class is used to protect a section of code through a ThreadLock for &quot;read&quot; access to the...
Definition: thread.h:182
virtual void exit(void)
Exit the thread context.
ThreadLock()
Create an instance of a rwlock.
~MutexLock()
Release the mutex automatically.
Definition: thread.h:137
virtual ~Thread()
Destroy thread object, thread-specific data, and execution context.
static const size_t timeout
value to return when a timed operation returned with a timeout.
Definition: thread.h:636
A child thread object that may be joined by parent.
Definition: thread.h:1372
The SemaphoreLock class is used to protect a section of code through a semaphore so that only x insta...
Definition: thread.h:291
size_t getSize(void)
Return the capacity of the buffer as specified at creation.
Definition: thread.h:653
A copy-on-write string class that operates by reference count.
Definition: string.h:82
void start(int priority=0)
Start execution of child context.
Timer ports are used to provide synchronized timing events when managed under a &quot;service thread&quot; such...
Definition: thread.h:468
size_t peek(void *buf)
Peek at the current content (first object) in the buffer.
The MutexLock class is used to protect a section of code so that at any given time only a single thre...
Definition: thread.h:119
void wait(void)
Wait until the semphore usage count is less than the thread limit.
void release(void)
Release or decrease locking.
The buffer class represents an IPC service that is built upon a buffer of fixed capacity that can be ...
Definition: thread.h:599
static Thread * get(void)
Get mapped thread object.
~ReadLock()
Post the semaphore automatically.
Definition: thread.h:199
~WriteLock()
Post the semaphore automatically.
Definition: thread.h:240
void wait(void)
A simple wait until triggered.
void map(void)
Map thread for get method.
static void sleep(timeout_t timeout)
Sleep current thread for a specified time period.
void lock(void)
Acquire or increase locking.
virtual ~Buffer()
In derived functions, may be used to free the actual memory used to hold buffered data...
size_t put(Buffer &b, void *o, timeout_t t=0)
Definition: thread.h:872
Conditional()
Initialize and construct conditional.
SemaphoreLock(Semaphore &_sem)
Wait for the semaphore.
Definition: thread.h:300