ucommon
thread.h
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2014 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 Lesser General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free software
18 // library without restriction. Specifically, if other files instantiate
19 // templates or use macros or inline functions from this file, or you compile
20 // this file and link it with other files to produce an executable, this
21 // file does not by itself cause the resulting executable to be covered by
22 // the GNU General Public License. This exception does not however
23 // invalidate any other reasons why the executable file might be covered by
24 // the GNU General Public License.
25 //
26 // This exception applies only to the code released under the name GNU
27 // Common C++. If you copy code from other releases into a copy of GNU
28 // Common C++, as the General Public License permits, the exception does
29 // not apply to the code that you add in this way. To avoid misleading
30 // anyone as to the status of such modified files, you must delete
31 // this exception notice from them.
32 //
33 // If you write modifications of your own for GNU Common C++, it is your choice
34 // whether to permit this exception to apply to your modifications.
35 // If you do not wish that, delete this exception notice.
36 //
37 
43 #ifndef COMMONCPP_THREAD_H_
44 #define COMMONCPP_THREAD_H_
45 
46 #ifndef COMMONCPP_CONFIG_H_
47 #include <commoncpp/config.h>
48 #endif
49 
50 #ifndef COMMONCPP_STRING_H_
51 #include <commoncpp/string.h>
52 #endif
53 
54 #define ENTER_CRITICAL enterMutex();
55 #define LEAVE_CRITICAL leaveMutex();
56 
57 NAMESPACE_COMMONCPP
58 
59 class __EXPORT Mutex : protected ucommon::RecursiveMutex
60 {
61 public:
62  inline Mutex() : RecursiveMutex() {};
63 
64  inline void enterMutex(void)
66 
67  inline void leaveMutex(void)
69 
70  inline bool tryEnterMutex(void)
71  {return RecursiveMutex::lock(0l);};
72 
73  inline void enter(void)
75 
76  inline void leave(void)
78 
79  inline bool test(void)
80  {return RecursiveMutex::lock(0l);};
81 
82 };
83 
93 class __EXPORT MutexCounter : public Mutex
94 {
95 protected:
96  volatile int counter;
97 
98 public:
102  MutexCounter();
103 
110  MutexCounter(int initial);
111 
112  int operator++();
113  int operator--();
114 };
115 
139 class __EXPORT MutexLock
140 {
141 private:
142  Mutex& mutex;
143 
144 public:
150  inline MutexLock( Mutex& _mutex ) : mutex( _mutex )
151  { mutex.enterMutex(); }
152 
156  // this should be not-virtual
157  inline ~MutexLock()
158  { mutex.leaveMutex(); }
159 };
160 
161 class __EXPORT ThreadLock : protected ucommon::ThreadLock
162 {
163 public:
164  inline ThreadLock() : ucommon::ThreadLock() {};
165 
166  inline void readLock(void)
168 
169  inline void writeLock(void)
171 
172  inline void tryReadLock(void)
174 
175  inline void tryWriteLock(void)
177 
178  inline void unlock(void)
180 };
181 
202 class __EXPORT ReadLock
203 {
204 private:
205  ThreadLock& tl;
206 
207 public:
213  inline ReadLock( ThreadLock& _tl ) : tl( _tl )
214  { tl.readLock(); }
218  // this should be not-virtual
219  inline ~ReadLock()
220  { tl.unlock(); }
221 };
222 
243 class __EXPORT WriteLock
244 {
245 private:
246  ThreadLock& tl;
247 
248 public:
254  inline WriteLock( ThreadLock& _tl ) : tl( _tl )
255  { tl.writeLock(); }
259  // this should be not-virtual
260  inline ~WriteLock()
261  { tl.unlock(); }
262 };
263 
264 class __EXPORT Conditional : private ucommon::Conditional
265 {
266 public:
267  inline Conditional() : ucommon::Conditional() {};
268 
269  bool wait(timeout_t timeout, bool locked = false);
270 
271  void signal(bool broadcast);
272 
273  inline void enterMutex(void)
275 
276  inline void leaveMutex(void)
278 };
279 
280 class __EXPORT Semaphore : private ucommon::Semaphore
281 {
282 public:
283  inline Semaphore(unsigned size = 0) : ucommon::Semaphore(size) {};
284 
285  inline bool wait(timeout_t timeout)
286  {return ucommon::Semaphore::wait(timeout);}
287 
288  inline void wait(void)
290 
291  inline void post(void)
293 };
294 
314 class __EXPORT SemaphoreLock
315 {
316 private:
317  Semaphore& sem;
318 
319 public:
323  inline SemaphoreLock( Semaphore& _sem ) : sem( _sem )
324  { sem.wait(); }
328  // this should be not-virtual
329  inline ~SemaphoreLock()
330  { sem.post(); }
331 };
332 
333 class __EXPORT Event : private ucommon::TimedEvent
334 {
335 public:
336  inline Event() : ucommon::TimedEvent() {};
337 
338  inline void wait(void)
340 
341  inline bool wait(timeout_t timeout)
342  {return ucommon::TimedEvent::wait(timeout);}
343 
344  inline void signal(void)
346 
347  inline void reset(void)
349 
350  inline void set(timeout_t timeout = 0)
351  {ucommon::TimedEvent::set(timeout);}
352 };
353 
354 class __EXPORT Thread : protected ucommon::JoinableThread
355 {
356 public:
360  typedef enum Throw {
361  throwNothing,
362  throwObject,
363  throwException
364  } Throw;
365 
366 private:
367  friend class Slog;
368 
369  Throw exceptions;
370  bool detached, terminated;
371  Thread *parent;
372  size_t msgpos;
373  char msgbuf[128];
374 
375 public:
376  Thread(int pri = 0, size_t stack = 0);
377 
378  virtual ~Thread();
379 
380  inline void map(void)
381  {JoinableThread::map();};
382 
383  virtual void initial(void);
384  virtual void notify(Thread *thread);
385  virtual void final(void);
386  virtual void run(void) = 0;
387 
388  void terminate(void);
389  void finalize(void);
390 
391  void detach(void);
392  void start(void);
393  void exit(void);
394 
395  inline void join(void)
397 
398  inline void sync(void)
399  {Thread::exit();};
400 
401  static inline Thread *get(void)
402  {return (Thread *)JoinableThread::get();};
403 
404  inline static void yield(void)
406 
407  inline static void sleep(timeout_t msec = TIMEOUT_INF)
408  {ucommon::Thread::sleep(msec);};
409 
410  bool isRunning(void);
411 
412  bool isThread(void);
413 
419  static Throw getException(void);
420 
426  static void setException(Throw mode);
427 
431  inline pthread_t getId(void)
432  {return tid;};
433 };
434 
464 class __EXPORT SysTime
465 {
466 public:
467  static time_t getTime(time_t *tloc = NULL);
468  static time_t time(time_t *tloc)
469  { return getTime(tloc); };
470 
471  static int getTimeOfDay(struct timeval *tp);
472  static int gettimeofday(struct timeval *tp, struct timezone *)
473  { return getTimeOfDay(tp); };
474 
475  static struct tm *getLocalTime(const time_t *clock, struct tm *result);
476  static struct tm *locatime(const time_t *clock, struct tm *result)
477  { return getLocalTime(clock, result); };
478 
479  static struct tm *getGMTTime(const time_t *clock, struct tm *result);
480  static struct tm *gmtime(const time_t *clock, struct tm *result)
481  { return getGMTTime(clock, result);};
482 };
483 
494 class __EXPORT TimerPort
495 {
496 #ifndef _MSWINDOWS_
497  struct timeval timer;
498 #else
499  DWORD timer;
500 #endif
501  bool active;
502 
503 public:
510  TimerPort();
511 
520  void setTimer(timeout_t timeout = 0);
521 
531  void incTimer(timeout_t timeout);
532 
542  void decTimer(timeout_t timeout);
543 
548  void sleepTimer(void);
549 
555  void endTimer(void);
556 
568  timeout_t getTimer(void) const;
569 
579  timeout_t getElapsed(void) const;
580 };
581 
582 #ifndef _MSWINDOWS_
583 struct timespec *getTimeout(struct timespec *spec, timeout_t timeout);
584 #endif
585 
586 inline struct tm *localtime_r(const time_t *t, struct tm *b)
587  {return SysTime::getLocalTime(t, b);}
588 
589 inline char *ctime_r(const time_t *t, char *buf)
590  {return ctime(t);}
591 
592 inline struct tm *gmtime_r(const time_t *t, struct tm *b)
593  {return SysTime::getGMTTime(t, b);}
594 
595 inline char *asctime_r(const struct tm *tm, char *b)
596  {return asctime(tm);}
597 
598 inline Thread *getThread(void)
599  {return Thread::get();}
600 
622 #ifdef _MSWINDOWS_
623 class __EXPORT Buffer : public Mutex
624 #else
625 class __EXPORT Buffer : public Conditional
626 #endif
627 {
628 private:
629 #ifdef _MSWINDOWS_
630  HANDLE sem_head, sem_tail;
631 #endif
632  size_t _size;
633  size_t _used;
634 
635 protected:
641  virtual size_t onPeek(void *buf) = 0;
642 
648  virtual size_t onWait(void *buf) = 0;
649 
655  virtual size_t onPost(void *buf) = 0;
656 
657 public:
662  static const size_t timeout;
663 
668  Buffer(size_t capacity);
673  virtual ~Buffer();
674 
679  inline size_t getSize(void)
680  {return _size;};
681 
688  inline size_t getUsed(void)
689  {return _used;};
690 
700  size_t wait(void *buf, timeout_t timeout = 0);
701 
710  size_t post(void *buf, timeout_t timeout = 0);
711 
718  size_t peek(void *buf);
719 
724  virtual bool isValid(void);
725 };
726 
734 class __EXPORT FixedBuffer : public Buffer
735 {
736 private:
737  char *buf, *head, *tail;
738  size_t objsize;
739 
740 protected:
746  size_t onPeek(void *buf);
747 
753  size_t onWait(void *buf);
754 
760  size_t onPost(void *buf);
761 
762 public:
770  FixedBuffer(size_t capacity, size_t objsize);
771 
778  FixedBuffer(const FixedBuffer &fb);
779 
783  virtual ~FixedBuffer();
784 
785  FixedBuffer &operator=(const FixedBuffer &fb);
786 
787  bool isValid(void);
788 };
789 
805 class __EXPORT ThreadQueue : public Mutex, public Thread, public Semaphore
806 {
807 private:
808  void run(void); // private run method
809 
810 protected:
811  typedef struct _data {
812  struct _data *next;
813  unsigned len;
814  char data[1];
815  } data_t;
816 
817  timeout_t timeout;
818  bool started;
819 
820  data_t *first, *last; // head/tail of list
821 
822  String name;
823 
824  /*
825  * Overloading of final(). It demarks Semaphore to avoid deadlock.
826  */
827  virtual void final();
828 
833  virtual void startQueue(void);
834 
840  virtual void stopQueue(void);
841 
845  virtual void onTimer(void);
846 
855  virtual void runQueue(void *data) = 0;
856 
857 public:
865  ThreadQueue(const char *id, int pri, size_t stack = 0);
866 
870  virtual ~ThreadQueue();
871 
879  void setTimer(timeout_t timeout);
880 
889  void post(const void *data, unsigned len);
890 };
891 
892 
894 inline size_t get(Buffer &b, void *o, timeout_t t = 0)
895  {return b.wait(o, t);}
896 
898 inline size_t put(Buffer &b, void *o, timeout_t t = 0)
899  {return b.post(o, t);}
900 
902 inline size_t peek(Buffer &b, void *o)
903  {return b.peek(o);}
904 
905 END_NAMESPACE
906 
907 #endif
size_t put(Buffer &b, void *o, timeout_t t=0)
Definition: thread.h:898
void wait(void)
Wait until the semphore usage count is less than the thread limit.
Timer ports are used to provide synchronized timing events when managed under a &quot;service thread&quot; such...
Definition: thread.h:494
void wait(void)
Wait (block) until signalled.
Definition: thread.h:160
static void sleep(timeout_t timeout)
Sleep current thread for a specified time period.
size_t getUsed(void)
Return the current capacity in use for the buffer.
Definition: thread.h:688
void set(void)
Set (update) the timer with current time.
void access(void)
Access mode shared thread scheduling.
A child thread object that may be joined by parent.
Definition: thread.h:1380
A buffer class that holds a known capacity of fixed sized objects defined during creation.
Definition: thread.h:734
virtual ~Buffer()
In derived functions, may be used to free the actual memory used to hold buffered data...
A copy-on-write string class that operates by reference count.
Definition: string.h:82
void unlock(void)
Unlock the conditional&#39;s supporting mutex.
Definition: thread.h:154
void release(void)
Release or decrease locking.
void signal(void)
Signal pending event.
size_t post(void *buf, timeout_t timeout=0)
Post an object into the buffer and enable a waiting thread to receive it.
This class is used to access non-reentrant date and time functions in the standard C library...
Definition: thread.h:464
~ReadLock()
Post the semaphore automatically.
Definition: thread.h:219
~MutexLock()
Release the mutex automatically.
Definition: thread.h:157
void lock(void)
Lock the conditional&#39;s supporting mutex.
Definition: thread.h:148
The ReadLock class is used to protect a section of code through a ThreadLock for &quot;read&quot; access to the...
Definition: thread.h:202
void start(int priority=0)
Start execution of child context.
static void yield(void)
Yield execution context of the current thread.
ReadLock(ThreadLock &_tl)
Wait for read access.
Definition: thread.h:213
void join(void)
Join thread with parent.
virtual ~Thread()
Destroy thread object, thread-specific data, and execution context.
WriteLock(ThreadLock &_tl)
Wait for write access.
Definition: thread.h:254
void release(void)
Release the semaphore after waiting for it.
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
The WriteLock class is used to protect a section of code through a ThreadLock for &quot;write&quot; access to t...
Definition: thread.h:243
The buffer class represents an IPC service that is built upon a buffer of fixed capacity that can be ...
Definition: thread.h:625
A portable counting semaphore class.
Definition: thread.h:853
virtual void run(void)=0
Abstract interface for thread context run method.
void lock(void)
Acquire or increase locking.
size_t peek(void *buf)
Peek at the current content (first object) in the buffer.
void modify(void)
Exclusive mode write thread scheduling.
size_t peek(Buffer &b, void *o)
Definition: thread.h:902
Event notification to manage scheduled realtime threads.
Definition: thread.h:365
virtual size_t onWait(void *buf)=0
Invoke derived class object request from 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:139
The conditional is a common base for other thread synchronizing classes.
Definition: thread.h:86
virtual void exit(void)
Exit the thread context.
Common C++ generic string class.
static Thread * get(void)
Get mapped thread object.
Buffer(size_t capacity)
Create a buffer object of known capacity.
Portable recursive exclusive lock.
Definition: thread.h:454
void map(void)
Map thread for get method.
MutexLock(Mutex &_mutex)
Acquire the mutex.
Definition: thread.h:150
void wait(void)
A simple wait until triggered.
size_t getSize(void)
Return the capacity of the buffer as specified at creation.
Definition: thread.h:679
void unlock(void)
Unlock the conditional&#39;s supporting mutex.
Definition: thread.h:289
void release(void)
Release the lock.
A generic and portable implimentation of Read/Write locking.
Definition: thread.h:498
Thread(size_t stack=0)
Create a thread object that will have a preset stack size.
Conditional()
Initialize and construct conditional.
Somewhat generic queue processing class to establish a producer consumer queue.
Definition: thread.h:805
Semaphore(unsigned count=0)
Construct a semaphore with an initial count of threads to permit.
The Mutex Counter is a counter variable which can safely be incremented or decremented by multiple th...
Definition: thread.h:93
virtual size_t onPost(void *buf)=0
Invoke derived class posting of object to buffer.
ThreadLock()
Create an instance of a rwlock.
~SemaphoreLock()
Post the semaphore automatically.
Definition: thread.h:329
void reset(void)
Reset triggered conditional.
unsigned long timeout_t
Typedef for millisecond timer values.
Definition: platform.h:326
~WriteLock()
Post the semaphore automatically.
Definition: thread.h:260
SemaphoreLock(Semaphore &_sem)
Wait for the semaphore.
Definition: thread.h:323
virtual bool isValid(void)
New virtual to test if buffer is a valid object.
The SemaphoreLock class is used to protect a section of code through a semaphore so that only x insta...
Definition: thread.h:314
static const size_t timeout
value to return when a timed operation returned with a timeout.
Definition: thread.h:662