blob: ba76aa8f9e1739ff3cb3e60ac12944cc5fe943f8 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// 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 2 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//
18// As a special exception, you may use this file as part of a free software
19// library without restriction. Specifically, if other files instantiate
20// templates or use macros or inline functions from this file, or you compile
21// this file and link it with other files to produce an executable, this
22// file does not by itself cause the resulting executable to be covered by
23// the GNU General Public License. This exception does not however
24// invalidate any other reasons why the executable file might be covered by
25// the GNU General Public License.
26//
27// This exception applies only to the code released under the name GNU
28// Common C++. If you copy code from other releases into a copy of GNU
29// Common C++, as the General Public License permits, the exception does
30// not apply to the code that you add in this way. To avoid misleading
31// anyone as to the status of such modified files, you must delete
32// this exception notice from them.
33//
34// If you write modifications of your own for GNU Common C++, it is your choice
35// whether to permit this exception to apply to your modifications.
36// If you do not wish that, delete this exception notice.
37//
38
39/**
40 * @file thread.h
41 * @short Synchronization and threading services.
42 **/
43
44#ifndef CCXX_THREAD_H_
45#define CCXX_THREAD_H_
46
47#include <cc++/config.h>
48
49#ifndef CCXX_STRING_H_
50#include <cc++/string.h>
51#endif
52
53#ifndef WIN32
54#define CCXX_POSIX
55#endif // !WIN32
56
57#include <ctime>
58
59#ifndef WIN32
60#include <pthread.h>
61#endif // !WIN32
62
63#undef CCXX_USE_WIN32_ATOMIC
64#ifndef WIN32
65#include <time.h>
66#include <signal.h>
67#include <unistd.h>
68
69#ifdef _THR_UNIXWARE
70#undef PTHREAD_MUTEXTYPE_RECURSIVE
71#endif
72
73typedef pthread_t cctid_t;
74typedef unsigned long timeout_t;
75
76/*
77#if defined(__CYGWIN32__)
78__declspec(dllimport) long __stdcall InterlockedIncrement(long *);
79__declspec(dllimport) long __stdcall InterlockedDecrement(long *);
80__declspec(dllimport) long __stdcall InterlockedExchange(long *, long);
81#define CCXX_USE_WIN32_ATOMIC 1
82#endif
83*/
84
85#else // WIN32
86typedef DWORD cctid_t;
87typedef DWORD timeout_t;
88
89#define MAX_SEM_VALUE 1000000
90#define CCXX_USE_WIN32_ATOMIC 1
91
92#endif // !WIN32
93
94#ifdef HAVE_GCC_CXX_BITS_ATOMIC
95#include <ios>
96#endif
97
98#ifdef CCXX_NAMESPACES
99namespace ost {
100#ifdef __BORLANDC__
101# if __BORLANDC__ >= 0x0560
102using std::time_t;
103using std::tm;
104# endif
105#endif
106#endif
107
108#ifdef HAVE_GCC_CXX_BITS_ATOMIC
109using namespace __gnu_cxx;
110#endif
111
112class __EXPORT Thread;
113class __EXPORT ThreadKey;
114
115#define TIMEOUT_INF ~((timeout_t) 0)
116
117#define ENTER_CRITICAL enterMutex();
118#define LEAVE_CRITICAL leaveMutex();
119#define ENTER_DEFERRED setCancel(cancelDeferred);
120#define LEAVE_DEFERRED setCancel(cancelImmediate);
121
122#ifndef WIN32
123// These macros override common functions with thread-safe versions. In
124// particular the common "libc" sleep() has problems since it normally
125// uses SIGARLM (as actually defined by "posix"). The pthread_delay and
126// usleep found in libpthread are gaurenteed not to use SIGALRM and offer
127// higher resolution. psleep() is defined to call the old process sleep.
128
129#undef sleep
130#define psleep(x) (sleep)(x)
131
132#ifdef signal
133#undef signal
134#endif
135
136#endif // !WIN32
137
138#undef Yield
139
140class __EXPORT Conditional;
141class __EXPORT Event;
142
143/**
144 * The Mutex class is used to protect a section of code so that at any
145 * given time only a single thread can perform the protected operation.
146 *
147 * The Mutex can be used as a base class to protect access in a derived
148 * class. When used in this manner, the ENTER_CRITICAL and LEAVE_CRITICAL
149 * macros can be used to specify when code written for the derived class
150 * needs to be protected by the default Mutex of the derived class, and
151 * hence is presumed to be 'thread safe' from multiple instance execution.
152 * One of the most basic Common C++ synchronization object is the Mutex
153 * class. A Mutex only allows one thread to continue execution at a given
154 * time over a specific section of code. Mutex's have a enter and leave
155 * method; only one thread can continue from the Enter until the Leave is
156 * called. The next thread waiting can then get through. Mutex's are also
157 * known as "CRITICAL SECTIONS" in win32-speak.
158 *
159 * The Mutex is always recursive in that if the same thread invokes
160 * the same mutex lock multiple times, it must release it multiple times.
161 * This allows a function to call another function which also happens to
162 * use the same mutex lock when called directly. This was
163 * deemed essential because a mutex might be used to block individual file
164 * requests in say, a database, but the same mutex might be needed to block a
165 * whole series of database updates that compose a "transaction" for one
166 * thread to complete together without having to write alternate non-locking
167 * member functions to invoke for each part of a transaction.
168 *
169 * Strangely enough, the original pthread draft standard does not directly
170 * support recursive mutexes. In fact this is the most common "NP" extension
171 * for most pthread implementations. Common C++ emulates recursive mutex
172 * behavior when the target platform does not directly support it.
173 *
174 * In addition to the Mutex, Common C++ supports a rwlock class. This
175 * implements the X/Open recommended "rwlock". On systems which do not
176 * support rwlock's, the behavior is emulated with a Mutex; however, the
177 * advantage of a rwlock over a mutex is then entirely lost. There has been
178 * some suggested clever hacks for "emulating" the behavior of a rwlock with
179 * a pair of mutexes and a semaphore, and one of these will be adapted for
180 * Common C++ in the future for platforms that do not support rwlock's
181 * directly.
182 *
183 * @author David Sugar <dyfet@ostel.com>
184 * @short Mutex lock for protected access.
185 */
186class __EXPORT Mutex
187{
188private:
189 static bool _debug;
190 String _name;
191#ifndef WIN32
192#ifndef PTHREAD_MUTEXTYPE_RECURSIVE
193 int volatile _level;
194 Thread *volatile _tid;
195#endif
196 /*
197 * Pthread mutex object. This is protected rather than private
198 * because some mixed mode pthread operations require a mutex as
199 * well as their primary pthread object. A good example of this
200 * is the Event class, as waiting on a conditional object must be
201 * associated with an accessable mutex. An alternative would be
202 * to make such classes "friend" classes of the Mutex.
203 */
204 pthread_mutex_t _mutex;
205#else // WIN32
206
207# if defined(MUTEX_UNDERGROUND_WIN32_MUTEX) && defined(MUTEX_UNDERGROUND_WIN32_CRITICALSECTION)
208# error "Can't determine underground for Mutex"
209# endif
210
211#ifdef MUTEX_UNDERGROUND_WIN32_MUTEX
212 HANDLE _mutex;
213#endif
214#ifdef MUTEX_UNDERGROUND_WIN32_CRITICALSECTION
215 CRITICAL_SECTION _criticalSection;
216#endif
217
218#endif // WIN32
219
220public:
221 /**
222 * The mutex is always initialized as a recursive entity.
223 *
224 * @param name of mutex for optional deadlock detection
225 */
226 Mutex(const char *name = NULL);
227
228 /**
229 * Destroying the mutex removes any system resources associated
230 * with it. If a mutex lock is currently in place, it is presumed
231 * to terminate when the Mutex is destroyed.
232 */
233 virtual ~Mutex();
234
235 /**
236 * Enable or disable deadlock debugging.
237 *
238 * @param mode debug mode.
239 */
240 static void setDebug(bool mode)
241 {_debug = mode;};
242
243 /**
244 * Enable setting of mutex name for deadlock debug.
245 *
246 * @param name for mutex.
247 */
248 inline void nameMutex(const char *name)
249 {_name = name;};
250
251 /**
252 * Entering a Mutex locks the mutex for the current thread. This
253 * also can be done using the ENTER_CRITICAL macro or by using the
254 * ++ operator on a mutex.
255 *
256 * @see #leaveMutex
257 */
258 void enterMutex(void);
259
260 /**
261 * Future abi will use enter/leave/test members.
262 */
263 inline void enter(void)
264 {enterMutex();};
265
266 /**
267 * Future abi will use enter/leave/test members.
268 */
269 inline void leave(void)
270 {leaveMutex();};
271
272 /**
273 * Future abi will use enter/leave/test members.
274 *
275 * @return true if entered.
276 */
277 inline bool test(void)
278 {return tryEnterMutex();};
279
280 /**
281 * Tries to lock the mutex for the current thread. Behaves like
282 * #enterMutex , except that it doesn't block the calling thread
283 * if the mutex is already locked by another thread.
284 *
285 * @return true if locking the mutex was succesful otherwise false
286 *
287 * @see enterMutex
288 * @see leaveMutex
289 */
290 bool tryEnterMutex(void);
291
292 /**
293 * Leaving a mutex frees that mutex for use by another thread. If
294 * the mutex has been entered (invoked) multiple times (recursivily)
295 * by the same thread, then it will need to be exited the same number
296 * of instances before it is free for re-use. This operation can
297 * also be done using the LEAVE_CRITICAL macro or by the -- operator
298 * on a mutex.
299 *
300 * @see #enterMutex
301 */
302 void leaveMutex(void);
303};
304
305/**
306 * The MutexLock class is used to protect a section of code so that at any
307 * given time only a single thread can perform the protected operation.
308 *
309 * It use Mutex to protect operation. Using this class is usefull and
310 * exception safe. The mutex that has been locked is automatically
311 * released when the function call stack falls out of scope, so one doesnt
312 * have to remember to unlock the mutex at each function return.
313 *
314 * A common use is
315 *
316 * void func_to_protect()
317 * {
318 * MutexLock lock(mutex);
319 * ... operation ...
320 * }
321 *
322 * NOTE: do not declare variable as "MutexLock (mutex)", the mutex will be
323 * released at statement end.
324 *
325 * @author Frediano Ziglio <freddy77@angelfire.com>
326 * @short Mutex automatic locker for protected access.
327 */
328class __EXPORT MutexLock
329{
330private:
331 Mutex& mutex;
332public:
333 /**
334 * Acquire the mutex
335 *
336 * @param _mutex reference to mutex to aquire.
337 */
338 MutexLock( Mutex& _mutex ) : mutex( _mutex )
339 { mutex.enterMutex(); }
340
341 /**
342 * Release the mutex automatically
343 */
344 // this should be not-virtual
345 ~MutexLock()
346 { mutex.leaveMutex(); }
347};
348
349/**
350 * The ThreadLock class impliments a thread rwlock for optimal reader performance
351 * on systems which have rwlock support, and reverts to a simple mutex for those
352 * that do not.
353 *
354 * @author David Sugar <dyfet@ostel.com>
355 * @short Posix rwlock extension for protected access.
356 */
357class __EXPORT ThreadLock
358{
359private:
360#ifdef HAVE_PTHREAD_RWLOCK
361 pthread_rwlock_t _lock;
362#else
363 Mutex mutex;
364#endif
365
366public:
367 /**
368 * Create a process shared thread lock object.
369 */
370 ThreadLock();
371
372 /**
373 * Destroy a process shared thread lock object.
374 */
375 virtual ~ThreadLock();
376
377 /**
378 * Aquire a read lock for the current object.
379 */
380 void readLock(void);
381
382 /**
383 * Aquire a write lock for the current object.
384 */
385 void writeLock(void);
386
387 /**
388 * Attempt read lock for current object.
389 *
390 * @return true on success.
391 */
392 bool tryReadLock(void);
393
394 /**
395 * Attempt write lock for current object.
396 *
397 * @return true on success.
398 */
399 bool tryWriteLock(void);
400
401 /**
402 * Release any held locks.
403 */
404 void unlock(void);
405};
406
407/**
408 * The ReadLock class is used to protect a section of code through
409 * a ThreadLock for "read" access to the member function. The
410 * ThreadLock is automatically released when the object falls out of
411 * scope.
412 *
413 * A common use is
414 *
415 * void func_to_protect()
416 * {
417 * ReadLock lock(threadlock);
418 * ... operation ...
419 * }
420 *
421 * NOTE: do not declare variable as "ReadLock (threadlock)", the
422 * mutex will be released at statement end.
423 *
424 * @author David Sugar <dyfet@gnu.org>
425 * @short Read mode automatic locker for protected access.
426 */
427class __EXPORT ReadLock
428{
429private:
430 ThreadLock& tl;
431
432public:
433 /**
434 * Wait for read access
435 *
436 * @param _tl reference to lock to aquire.
437 */
438 ReadLock( ThreadLock& _tl ) : tl( _tl )
439 { tl.readLock(); }
440 /**
441 * Post the semaphore automatically
442 */
443 // this should be not-virtual
444 ~ReadLock()
445 { tl.unlock(); }
446};
447
448/**
449 * The WriteLock class is used to protect a section of code through
450 * a ThreadLock for "write" access to the member function. The
451 * ThreadLock is automatically released when the object falls out of
452 * scope.
453 *
454 * A common use is
455 *
456 * void func_to_protect()
457 * {
458 * WriteLock lock(threadlock);
459 * ... operation ...
460 * }
461 *
462 * NOTE: do not declare variable as "WriteLock (threadlock)", the
463 * mutex will be released at statement end.
464 *
465 * @author David Sugar <dyfet@gnu.org>
466 * @short Read mode automatic locker for protected access.
467 */
468class __EXPORT WriteLock
469{
470private:
471 ThreadLock& tl;
472
473public:
474 /**
475 * Wait for write access
476 *
477 * @param _tl reference to threadlock to aquire.
478 */
479 WriteLock( ThreadLock& _tl ) : tl( _tl )
480 { tl.writeLock(); }
481 /**
482 * Post the semaphore automatically
483 */
484 // this should be not-virtual
485 ~WriteLock()
486 { tl.unlock(); }
487};
488
489
490/**
491 * The Mutex Counter is a counter variable which can safely be incremented
492 * or decremented by multiple threads. A Mutex is used to protect access
493 * to the counter variable (an integer). An initial value can be specified
494 * for the counter, and it can be manipulated with the ++ and -- operators.
495 *
496 * @author David Sugar <dyfet@ostel.com>
497 * @short Thread protected integer counter.
498 */
499class __EXPORT MutexCounter : public Mutex
500{
501private:
502 volatile int counter;
503
504public:
505 /**
506 * Create and optionally name a mutex protected counter.
507 *
508 * @param id name for mutex counter, optional for deadlock testing.
509 */
510 MutexCounter(const char *id = NULL);
511
512 /**
513 * Create and optionally name a mutex protected counter with
514 * an initial value.
515 *
516 * @param initial value of counter.
517 * @param id name of counter, optional for deadlock testing.
518 */
519 MutexCounter(int initial, const char *id = NULL);
520
521 friend __EXPORT int operator++(MutexCounter &mc);
522 friend __EXPORT int operator--(MutexCounter &mc);
523};
524
525/**
526 * The AtomicCounter class offers thread-safe manipulation of an integer
527 * counter. These are commonly used for building thread-safe "reference"
528 * counters for C++ classes. The AtomicCounter depends on the platforms
529 * support for "atomic" integer operations, and can alternately substitute
530 * a "mutex" if no atomic support exists.
531 *
532 * @author Sean Cavanaugh <sean@dimensionalrift.com>
533 * @short atomic counter operation.
534 */
535class __EXPORT AtomicCounter
536{
537#ifndef CCXX_USE_WIN32_ATOMIC
538private:
539#if defined(HAVE_ATOMIC_AIX)
540 volatile int counter;
541#elif defined(HAVE_GCC_BITS_ATOMIC)
542 volatile _Atomic_word counter;
543#elif defined(HAVE_GCC_CXX_BITS_ATOMIC)
544 volatile _Atomic_word counter;
545// __gnu_cxx::_Atomic_word counter;
546#elif defined(HAVE_ATOMIC)
547 atomic_t atomic;
548#else
549 volatile int counter;
550 pthread_mutex_t _mutex;
551#endif
552
553public:
554 /**
555 * Initialize an atomic counter to 0.
556 */
557 AtomicCounter();
558
559 /**
560 * Initialize an atomic counter to a known value.
561 *
562 * @param value initial value.
563 */
564 AtomicCounter(int value);
565
566 ~AtomicCounter();
567
568 int operator++(void);
569 int operator--(void);
570 int operator+=(int change);
571 int operator-=(int change);
572 int operator+(int change);
573 int operator-(int change);
574 int operator=(int value);
575 bool operator!(void);
576 operator int();
577#else
578private:
579 long atomic;
580
581public:
582 inline AtomicCounter()
583 {atomic = 0;};
584
585 inline AtomicCounter(int value)
586 {atomic = value;};
587
588 inline int operator++(void)
589 {return InterlockedIncrement(&atomic);};
590
591 inline int operator--(void)
592 {return InterlockedDecrement(&atomic);};
593
594 int operator+=(int change);
595
596 int operator-=(int change);
597
598 inline int operator+(int change)
599 {return atomic + change;};
600
601 inline int operator-(int change)
602 {return atomic - change;};
603
604 inline int operator=(int value)
605 {return InterlockedExchange(&atomic, value);};
606
607 inline bool operator!(void)
608 {return (atomic == 0) ? true : false;};
609
610 inline operator int()
611 {return atomic;};
612#endif
613};
614
615#ifndef WIN32
616/**
617 * A conditional variable synchcronization object for one to one and
618 * one to many signal and control events between processes.
619 * Conditional variables may wait for and receive signals to notify
620 * when to resume or perform operations. Multiple waiting threads may
621 * be woken with a broadcast signal.
622 *
623 * @warning While this class inherits from Mutex, the methods of the
624 * class Conditional just handle the system conditional variable, so
625 * the user is responsible for calling enterMutex and leaveMutex so as
626 * to avoid race conditions. Another thing to note is that if you have
627 * several threads waiting on one condition, not uncommon in thread
628 * pools, each thread must take care to manually unlock the mutex if
629 * cancellation occurs. Otherwise the first thread cancelled will
630 * deadlock the rest of the thread.
631 *
632 * @author David Sugar
633 * @short conditional.
634 * @todo implement in win32
635 */
636class __EXPORT Conditional
637{
638private:
639 pthread_cond_t _cond;
640 pthread_mutex_t _mutex;
641
642public:
643 /**
644 * Create an instance of a conditional.
645 *
646 * @param id name of conditional, optional for deadlock testing.
647 */
648 Conditional(const char *id = NULL);
649
650 /**
651 * Destroy the conditional.
652 */
653 virtual ~Conditional();
654
655 /**
656 * Signal a conditional object and a waiting threads.
657 *
658 * @param broadcast this signal to all waiting threads if true.
659 */
660 void signal(bool broadcast);
661
662 /**
663 * Wait to be signaled from another thread.
664 *
665 * @param timer time period to wait.
666 * @param locked flag if already locked the mutex.
667 */
668 bool wait(timeout_t timer = 0, bool locked = false);
669
670 /**
671 * Locks the conditional's mutex for this thread. Remember
672 * that Conditional's mutex is NOT a recursive mutex!
673 *
674 * @see #leaveMutex
675 */
676 void enterMutex(void);
677
678 /**
679 * In the future we will use lock in place of enterMutex since
680 * the conditional composite is not a recursive mutex, and hence
681 * using enterMutex may cause confusion in expectation with the
682 * behavior of the Mutex class.
683 *
684 * @see #enterMutex
685 */
686 inline void lock(void)
687 {enterMutex();};
688
689 /**
690 * Tries to lock the conditional for the current thread.
691 * Behaves like #enterMutex , except that it doesn't block the
692 * calling thread.
693 *
694 * @return true if locking the mutex was succesful otherwise false
695 *
696 * @see enterMutex
697 * @see leaveMutex
698 */
699 bool tryEnterMutex(void);
700
701 inline bool test(void)
702 {return tryEnterMutex();};
703
704 /**
705 * Leaving a mutex frees that mutex for use by another thread.
706 *
707 * @see #enterMutex
708 */
709 void leaveMutex(void);
710
711 inline void unlock(void)
712 {return leaveMutex();};
713};
714#endif
715
716/**
717 * A semaphore is generally used as a synchronization object between multiple
718 * threads or to protect a limited and finite resource such as a memory or
719 * thread pool. The semaphore has a counter which only permits access by
720 * one or more threads when the value of the semaphore is non-zero. Each
721 * access reduces the current value of the semaphore by 1. One or more
722 * threads can wait on a semaphore until it is no longer 0, and hence the
723 * semaphore can be used as a simple thread synchronization object to enable
724 * one thread to pause others until the thread is ready or has provided data
725 * for them. Semaphores are typically used as a
726 * counter for protecting or limiting concurrent access to a given
727 * resource, such as to permitting at most "x" number of threads to use
728 * resource "y", for example.
729 *
730 * @author David Sugar <dyfet@ostel.com>
731 * @short Semaphore counter for thread synchronization.
732 */
733class __EXPORT Semaphore
734{
735private:
736#ifndef WIN32
737 unsigned _count, _waiters;
738 pthread_mutex_t _mutex;
739 pthread_cond_t _cond;
740#else
741 HANDLE semObject;
742#endif // !WIN32
743
744public:
745 /**
746 * The initial value of the semaphore can be specified. An initial
747 * value is often used When used to lock a finite resource or to
748 * specify the maximum number of thread instances that can access a
749 * specified resource.
750 *
751 * @param resource specify initial resource count or 0 default.
752 */
753 Semaphore(unsigned resource = 0);
754
755 /**
756 * Destroying a semaphore also removes any system resources
757 * associated with it. If a semaphore has threads currently waiting
758 * on it, those threads will all continue when a semaphore is
759 * destroyed.
760 */
761 virtual ~Semaphore();
762
763 /**
764 * Wait is used to keep a thread held until the semaphore counter
765 * is greater than 0. If the current thread is held, then another
766 * thread must increment the semaphore. Once the thread is accepted,
767 * the semaphore is automatically decremented, and the thread
768 * continues execution.
769 *
770 * The pthread semaphore object does not support a timed "wait", and
771 * hence to maintain consistancy, neither the posix nor win32 source
772 * trees support "timed" semaphore objects.
773 *
774 * @return false if timed out
775 * @param timeout period in milliseconds to wait
776 * @see #post
777 */
778 bool wait(timeout_t timeout = 0);
779
780 /**
781 * Posting to a semaphore increments its current value and releases
782 * the first thread waiting for the semaphore if it is currently at
783 * 0. Interestingly, there is no support to increment a semaphore by
784 * any value greater than 1 to release multiple waiting threads in
785 * either pthread or the win32 API. Hence, if one wants to release
786 * a semaphore to enable multiple threads to execute, one must perform
787 * multiple post operations.
788 *
789 * @see #wait
790 */
791 void post(void);
792
793#ifndef WIN32
794 /**
795 * Call it after a deferred cancellation to avoid deadlocks.
796 * From PTHREAD_COND_TIMEDWAIT(3P): A condition wait (whether timed or not)
797 * is a cancellation point. When the cancelability enable state of a thread
798 * is set to PTHREAD_CANCEL_DEFERRED, a side effect of acting upon a
799 * cancellation request while in a condition wait is that the mutex is
800 * (in effect) re-acquired before calling the first cancellation cleanup handler.
801 */
802 void force_unlock_after_cancellation();
803
804#endif // WIN32
805
806 // FIXME: how implement getValue for posix compatibility ?
807 // not portable...
808#if 0
809 /**
810 * Get the current value of a semaphore.
811 *
812 * @return current value.
813 */
814 int getValue(void);
815#endif
816};
817
818/**
819 * The SemaphoreLock class is used to protect a section of code through
820 * a semaphore so that only x instances of the member function may
821 * execute concurrently.
822 *
823 * A common use is
824 *
825 * void func_to_protect()
826 * {
827 * SemaphoreLock lock(semaphore);
828 * ... operation ...
829 * }
830 *
831 * NOTE: do not declare variable as "SemaohoreLock (semaphore)", the
832 * mutex will be released at statement end.
833 *
834 * @author David Sugar <dyfet@gnu.org>
835 * @short Semaphore automatic locker for protected access.
836 */
837class __EXPORT SemaphoreLock
838{
839private:
840 Semaphore& sem;
841
842public:
843 /**
844 * Wait for the semaphore
845 */
846 SemaphoreLock( Semaphore& _sem ) : sem( _sem )
847 { sem.wait(); }
848 /**
849 * Post the semaphore automatically
850 */
851 // this should be not-virtual
852 ~SemaphoreLock()
853 { sem.post(); }
854};
855
856/**
857 * The Event class implements a feature originally found in the WIN32 API;
858 * event notification. A target thread waits on a resetable Event, and one
859 * or more other threads can then signal the waiting thread to resume
860 * execution. A timeout can be used to specify a wait duration in
861 * milliseconds. The Event class must be reset before it can be used again
862 * as a trigger. These event objects
863 * use a trigger/reset mechanism and are related to low level conditional
864 * variables.
865 *
866 * @author: David Sugar <dyfet@ostel.com>
867 * @short Thread synchornization on event notification.
868 */
869class __EXPORT Event
870{
871private:
872#ifndef WIN32
873 pthread_mutex_t _mutex;
874 pthread_cond_t _cond;
875 bool _signaled;
876 int _count;
877#else
878 HANDLE cond;
879#endif
880
881public:
882 Event();
883
884 virtual ~Event();
885
886 /**
887 * Once signaled, the Event class must be "reset" before responding
888 * to a new signal.
889 *
890 * @see #signal
891 */
892 void reset(void);
893
894 /**
895 * Signal the event for the waiting thread.
896 */
897 void signal(void);
898
899 /**
900 * Wait either for the event to be signaled by another thread or
901 * for the specified timeout duration.
902 *
903 * @see #signal
904 * @return true if signaled, false if timed out.
905 * @param timer timeout in milliseconds to wait for a signal.
906 */
907 bool wait(timeout_t timer);
908 bool wait(void);
909};
910
911
912/**
913 * Every thread of execution in an application is created by
914 * instantiating an object of a class derived from the Thread
915 * class. Classes derived from Thread must implement the run() method,
916 * which specifies the code of the thread. The base Thread class
917 * supports encapsulation of the generic threading methods implemented
918 * on various target operating systems. This includes the ability to
919 * start and stop threads in a synchronized and controllable manner,
920 * the ability to specify thread execution priority, and thread
921 * specific "system call" wrappers, such as for sleep and yield. A
922 * thread exception is thrown if the thread cannot be created.
923 * Threading was the first part of Common C++ I wrote, back when it
924 * was still the APE library. My goal for Common C++ threading has
925 * been to make threading as natural and easy to use in C++
926 * application development as threading is in Java. With this said,
927 * one does not need to use threading at all to take advantage of
928 * Common C++. However, all Common C++ classes are designed at least
929 * to be thread-aware/thread-safe as appropriate and necessary.
930 *
931 * Common C++ threading is currently built either from the Posix "pthread"
932 * library or using the win32 SDK. In that the Posix "pthread" draft
933 * has gone through many revisions, and many system implementations are
934 * only marginally compliant, and even then usually in different ways, I
935 * wrote a large series of autoconf macros found in ost_pthread.m4 which
936 * handle the task of identifying which pthread features and capabilities
937 * your target platform supports. In the process I learned much about what
938 * autoconf can and cannot do for you..
939 *
940 * Currently the GNU Portable Thread library (GNU pth) is not directly
941 * supported in Common C++. While GNU "Pth" doesn't offer direct
942 * native threading support or benefit from SMP hardware, many of the design
943 * advantages of threading can be gained from it's use, and the Pth pthread
944 * "emulation" library should be usable with Common C++. In the future,
945 * Common C++ will directly support Pth, as well as OS/2 and BeOS native
946 * threading API's.
947 *
948 * Common C++ itself defines a fairly "neutral" threading model that is
949 * not tied to any specific API such as pthread, win32, etc. This neutral
950 * thread model is contained in a series of classes which handle threading
951 * and synchronization and which may be used together to build reliable
952 * threaded applications.
953 *
954 * Common C++ defines application specific threads as objects which are
955 * derived from the Common C++ "Thread" base class. At minimum the "Run"
956 * method must be implemented, and this method essentially is the "thread",
957 * for it is executed within the execution context of the thread, and when
958 * the Run method terminates the thread is assumed to have terminated.
959 *
960 * Common C++ allows one to specify the running priority of a newly created
961 * thread relative to the "parent" thread which is the thread that is
962 * executing when the constructor is called. Since most newer C++
963 * implementations do not allow one to call virtual constructors or virtual
964 * methods from constructors, the thread must be "started" after the
965 * constructor returns. This is done either by defining a "starting"
966 * semaphore object that one or more newly created thread objects can wait
967 * upon, or by invoking an explicit "start" member function.
968 *
969 * Threads can be "suspended" and "resumed". As this behavior is not defined
970 * in the Posix "pthread" specification, it is often emulated through
971 * signals. Typically SIGUSR1 will be used for this purpose in Common C++
972 * applications, depending in the target platform. On Linux, since threads
973 * are indeed processes, SIGSTP and SIGCONT can be used. On solaris, the
974 * Solaris thread library supports suspend and resume directly.
975 *
976 * Threads can be canceled. Not all platforms support the concept of
977 * externally cancelable threads. On those platforms and API
978 * implementations that do not, threads are typically canceled through the
979 * action of a signal handler.
980 *
981 * As noted earlier, threads are considered running until the "Run" method
982 * returns, or until a cancellation request is made. Common C++ threads can
983 * control how they respond to cancellation, using setCancellation().
984 * Cancellation requests can be ignored, set to occur only when a
985 * cancellation "point" has been reached in the code, or occur immediately.
986 * Threads can also exit by returning from Run() or by invoking the Exit()
987 * method.
988 *
989 * Generally it is a good practice to initialize any resources the thread may
990 * require within the constructor of your derived thread class, and to purge
991 * or restore any allocated resources in the destructor. In most cases, the
992 * destructor will be executed after the thread has terminated, and hence
993 * will execute within the context of the thread that requested a join rather
994 * than in the context of the thread that is being terminated. Most
995 * destructors in derived thread classes should first call Terminate() to
996 * make sure the thread has stopped running before releasing resources.
997 *
998 * A Common C++ thread is normally canceled by deleting the thread object.
999 * The process of deletion invokes the thread's destructor, and the
1000 * destructor will then perform a "join" against the thread using the
1001 * Terminate() function. This behavior is not always desirable since the
1002 * thread may block itself from cancellation and block the current "delete"
1003 * operation from completing. One can alternately invoke Terminate()
1004 * directly before deleting a thread object.
1005 *
1006 * When a given Common C++ thread exits on it's own through it's Run()
1007 * method, a "Final" method will be called. This Final method will be called
1008 * while the thread is "detached". If a thread object is constructed through
1009 * a "new" operator, it's final method can be used to "self delete" when
1010 * done, and allows an independent thread to construct and remove itself
1011 * autonomously.
1012 *
1013 * A special global function, getThread(), is provided to identify the thread
1014 * object that represents the current execution context you are running
1015 * under. This is sometimes needed to deliver signals to the correct thread.
1016 * Since all thread manipulation should be done through the Common C++ (base)
1017 * thread class itself, this provides the same functionality as things like
1018 * "pthread_self" for Common C++.
1019 *
1020 * All Common C++ threads have an exception "mode" which determines
1021 * their behavior when an exception is thrown by another Common C++
1022 * class. Extensions to Common C++ should respect the current
1023 * exception mode and use getException() to determine what to do when
1024 * they are about to throw an object. The default exception mode
1025 * (defined in the Thread() constructor) is throwObject, which causes
1026 * a pointer to an instance of the class where the error occured to be
1027 * thrown. Other exception modes are throwException, which causes a
1028 * class-specific exception class to be thrown, and throwNothing,
1029 * which causes errors to be ignored.
1030 *
1031 * As an example, you could try to call the Socket class with an
1032 * invalid address that the system could not bind to. This would
1033 * cause an object of type Socket * to be thrown by default, as the
1034 * default exception mode is throwObject. If you call
1035 * setException(throwException) before the bad call to the Socket
1036 * constructor, an object of type SockException (the exception class
1037 * for class Socket) will be thrown instead.
1038 *
1039 * To determine what exception class is thrown by a given Common C++
1040 * class when the exception mode is set to throwException, search the
1041 * source files for the class you are interested in for a class which
1042 * inherits directly or indirectly from class Exception. This is the
1043 * exception class which would be thrown when the exception mode is
1044 * set to throwException.
1045 *
1046 * The advantage of using throwException versus throwObject is that
1047 * more information is available to the programmer from the thrown
1048 * object. All class-specific exceptions inherit from class
1049 * Exception, which provides a getString() method which can be called
1050 * to get a human-readable error string.
1051 *
1052 * Common C++ threads are often aggregated into other classes to provide
1053 * services that are "managed" from or operate within the context of a
1054 * thread, even within the Common C++ framework itself. A good example of
1055 * this is the TCPSession class, which essentially is a combination of a TCP
1056 * client connection and a separate thread the user can define by deriving a
1057 * class with a Run() method to handle the connected service. This
1058 * aggregation logically connects the successful allocation of a given
1059 * resource with the construction of a thread to manage and perform
1060 * operations for said resource.
1061 *
1062 * Threads are also used in "service pools". In Common C++, a service pool
1063 * is one or more threads that are used to manage a set of resources. While
1064 * Common C++ does not provide a direct "pool" class, it does provide a model
1065 * for their implementation, usually by constructing an array of thread
1066 * "service" objects, each of which can then be assigned the next new
1067 * instance of a given resource in turn or algorithmically.
1068 *
1069 * Threads have signal handlers associated with them. Several signal types
1070 * are "predefined" and have special meaning. All signal handlers are
1071 * defined as virtual member functions of the Thread class which are called
1072 * when a specific signal is received for a given thread. The "SIGPIPE"
1073 * event is defined as a "Disconnect" event since it's normally associated
1074 * with a socket disconnecting or broken fifo. The Hangup() method is
1075 * associated with the SIGHUP signal. All other signals are handled through
1076 * the more generic Signal().
1077 *
1078 * Incidently, unlike Posix, the win32 API has no concept of signals, and
1079 * certainly no means to define or deliver signals on a per-thread basis.
1080 * For this reason, no signal handling is supported or emulated in the win32
1081 * implementation of Common C++ at this time.
1082 *
1083 * In addition to TCPStream, there is a TCPSession class which combines a
1084 * thread with a TCPStream object. The assumption made by TCPSession is that
1085 * one will service each TCP connection with a separate thread, and this
1086 * makes sense for systems where extended connections may be maintained and
1087 * complex protocols are being used over TCP.
1088 *
1089 *
1090 * @author David Sugar <dyfet@ostel.com>
1091 * @short base class used to derive all threads of execution.
1092 */
1093class __EXPORT Thread
1094{
1095public:
1096 /**
1097 * How to raise error
1098 */
1099 typedef enum Throw {
1100 throwNothing, /**< continue without throwing error */
1101 throwObject, /**< throw object that cause error (throw this) */
1102 throwException /**< throw an object relative to error */
1103 } Throw;
1104
1105 /**
1106 * How work cancellation
1107 */
1108 typedef enum Cancel {
1109 cancelInitial=0, /**< used internally, do not use */
1110 cancelDeferred=1, /**< exit thread on cancellation pointsuch as yield */
1111 cancelImmediate, /**< exit befor cancellation */
1112 cancelDisabled, /**< ignore cancellation */
1113 cancelManual, /**< unimplemented (working in progress)
1114 @todo implement */
1115 cancelDefault=cancelDeferred
1116 /**< default you should use this for compatibility instead of deferred */
1117 } Cancel;
1118
1119 /**
1120 * How work suspend
1121 */
1122 typedef enum Suspend {
1123 suspendEnable, /**< suspend enabled */
1124 suspendDisable /**< suspend disabled, Suspend do nothing */
1125 } Suspend;
1126
1127#ifndef WIN32
1128/** @internal */
1129friend class PosixThread;
1130#endif
1131/** @internal */
1132friend class DummyThread;
1133private:
1134 friend class Cancellation;
1135 friend class postream_type;
1136 friend class Slog;
1137
1138 Semaphore joinSem;
1139 static Thread* _main;
1140
1141 Thread *_parent;
1142 Cancel _cancel;
1143 Semaphore *_start;
1144
1145 // private data
1146 friend class ThreadImpl;
1147 class ThreadImpl* priv;
1148
1149public:
1150 static Thread *get(void);
1151
1152private:
1153#ifdef WIN32
1154 static unsigned __stdcall Execute(Thread *th);
1155#endif
1156
1157 // close current thread, free all and call Notify
1158 void close();
1159
1160private:
1161 char _name[32];
1162 static size_t _autostack;
1163
1164#ifdef WIN32
1165 DWORD waitHandle(HANDLE obj, timeout_t timeout);
1166#endif
1167
1168protected:
1169 /**
1170 * Set the name of the current thread. If the name is passed
1171 * as NULL, then the default name is set (usually object
1172 * pointer).
1173 *
1174 * @param text name to use.
1175 */
1176 void setName(const char *text);
1177
1178 /**
1179 * All threads execute by deriving the Run method of Thread.
1180 * This method is called after Initial to begin normal operation
1181 * of the thread. If the method terminates, then the thread will
1182 * also terminate after notifying it's parent and calling it's
1183 * Final() method.
1184 *
1185 * @see #Initial
1186 */
1187 virtual void run(void) = 0;
1188
1189 /**
1190 * A thread that is self terminating, either by invoking exit() or
1191 * leaving it's run(), will have this method called. It can be used
1192 * to self delete the current object assuming the object was created
1193 * with new on the heap rather than stack local, hence one may often
1194 * see final defined as "delete this" in a derived thread class. A
1195 * final method, while running, cannot be terminated or cancelled by
1196 * another thread. Final is called for all cancellation type (even
1197 * immediate).
1198 *
1199 * You can safe delete thread ("delete this") class on final, but
1200 * you should exit ASAP (or do not try to call CommonC++ methods...)
1201 *
1202 * @note A thread cannot delete its own context or join
1203 * itself. To make a thread that is a self running object
1204 * that self-deletes, one has to detach the thread by using
1205 * detach() instead of start().
1206 *
1207 * @see #exit
1208 * @see #run
1209 */
1210 virtual void final(void);
1211
1212 /**
1213 * The initial method is called by a newly created thread when it
1214 * starts execution. This method is ran with deferred cancellation
1215 * disabled by default. The Initial method is given a separate
1216 * handler so that it can create temporary objects on it's own
1217 * stack frame, rather than having objects created on run() that
1218 * are only needed by startup and yet continue to consume stack space.
1219 *
1220 * @see #run
1221 * @see #final
1222 */
1223 virtual void initial(void);
1224
1225 /**
1226 * Since getParent() and getThread() only refer to an object of the
1227 * Thread "base" type, this virtual method can be replaced in a
1228 * derived class with something that returns data specific to the
1229 * derived class that can still be accessed through the pointer
1230 * returned by getParent() and getThread().
1231 *
1232 * @return pointer to derived class specific data.
1233 */
1234 virtual void* getExtended(void);
1235
1236 /**
1237 * When a thread terminates, it now sends a notification message
1238 * to the parent thread which created it. The actual use of this
1239 * notification is left to be defined in a derived class.
1240 *
1241 * @param - the thread that has terminated.
1242 */
1243 virtual void notify(Thread*);
1244
1245 /**
1246 * Used to properly exit from a Thread derived run() or initial()
1247 * method. Terminates execution of the current thread and calls
1248 * the derived classes final() method.
1249 */
1250 void exit(void);
1251
1252 /**
1253 * Used to wait for a join or cancel, in place of explicit exit.
1254 */
1255 void sync(void);
1256
1257 /**
1258 * test a cancellation point for deferred thread cancellation.
1259 */
1260 bool testCancel(void);
1261
1262 /**
1263 * Sets thread cancellation mode. Threads can either be set immune to
1264 * termination (cancelDisabled), can be set to terminate when
1265 * reaching specific "thread cancellation points"
1266 * (cancelDeferred)
1267 * or immediately when Terminate is requested (cancelImmediate).
1268 *
1269 * @param mode for cancellation of the current thread.
1270 */
1271 void setCancel(Cancel mode);
1272
1273 /**
1274 * Sets the thread's ability to be suspended from execution. The
1275 * thread may either have suspend enabled (suspendEnable) or
1276 * disabled (suspendDisable).
1277 *
1278 * @param mode for suspend.
1279 */
1280 void setSuspend(Suspend mode);
1281
1282 /**
1283 * Used by another thread to terminate the current thread. Termination
1284 * actually occurs based on the current setCancel() mode. When the
1285 * current thread does terminate, control is returned to the requesting
1286 * thread. terminate() should always be called at the start of any
1287 * destructor of a class derived from Thread to assure the remaining
1288 * part of the destructor is called without the thread still executing.
1289 */
1290 void terminate(void);
1291
1292 /**
1293 * clear parent thread relationship.
1294 */
1295 inline void clrParent(void)
1296 {_parent = NULL;};
1297
1298public:
1299 /**
1300 * This is actually a special constructor that is used to create a
1301 * thread "object" for the current execution context when that context
1302 * is not created via an instance of a derived Thread object itself.
1303 * This constructor does not support First.
1304 *
1305 * @param isMain bool used if the main "thread" of the application.
1306 */
1307 Thread(bool isMain);
1308
1309 /**
1310 * When a thread object is contructed, a new thread of execution
1311 * context is created. This constructor allows basic properties
1312 * of that context (thread priority, stack space, etc) to be defined.
1313 * The starting condition is also specified for whether the thread
1314 * is to wait on a semaphore before begining execution or wait until
1315 * it's start method is called.
1316 *
1317 * @param pri thread base priority relative to it's parent.
1318 * @param stack space as needed in some implementations.
1319 */
1320 Thread(int pri = 0, size_t stack = 0);
1321
1322#ifndef WIN32
1323 /**
1324 * A thread of execution can also be specified by cloning an existing
1325 * thread. The existing thread's properties (cancel mode, priority,
1326 * etc), are also duplicated.
1327 *
1328 * @param th currently executing thread object to clone.
1329 * @todo implement in win32
1330 */
1331 Thread(const Thread &th);
1332#endif
1333
1334 /**
1335 * The thread destructor should clear up any resources that have
1336 * been allocated by the thread. The desctructor of a derived
1337 * thread should begin with Terminate() and is presumed to then
1338 * execute within the context of the thread causing terminaton.
1339 */
1340 virtual ~Thread();
1341
1342 /**
1343 * Set base stack limit before manual stack sizes have effect.
1344 *
1345 * @param size stack size to set, or use 0 to clear autostack.
1346 */
1347 static void setStack(size_t size = 0)
1348 {_autostack = size;};
1349
1350 /**
1351 * A thread-safe sleep call. On most Posix systems, "sleep()"
1352 * is implimented with SIGALRM making it unusable from multipe
1353 * threads. Pthread libraries often define an alternate "sleep"
1354 * handler such as usleep(), nanosleep(), or nap(), that is thread
1355 * safe, and also offers a higher timer resolution.
1356 *
1357 * @param msec timeout in milliseconds.
1358 */
1359 static void sleep(timeout_t msec);
1360
1361 /**
1362 * Yields the current thread's CPU time slice to allow another thread to
1363 * begin immediate execution.
1364 */
1365 static void yield(void);
1366
1367 /**
1368 * When a new thread is created, it does not begin immediate
1369 * execution. This is because the derived class virtual tables
1370 * are not properly loaded at the time the C++ object is created
1371 * within the constructor itself, at least in some compiler/system
1372 * combinations. The thread can either be told to wait for an
1373 * external semaphore, or it can be started directly after the
1374 * constructor completes by calling the start() method.
1375 *
1376 * @return error code if execution fails.
1377 * @param start optional starting semaphore to alternately use.
1378 */
1379 int start(Semaphore *start = 0);
1380
1381 /**
1382 * Start a new thread as "detached". This is an alternative
1383 * start() method that resolves some issues with later glibc
1384 * implimentations which incorrectly impliment self-detach.
1385 *
1386 * @return error code if execution fails.
1387 * @param start optional starting semaphore to alternately use.
1388 */
1389 int detach(Semaphore *start = 0);
1390
1391 /**
1392 * Gets the pointer to the Thread class which created the current
1393 * thread object.
1394 *
1395 * @return a Thread *, or "(Thread *)this" if no parent.
1396 */
1397 inline Thread *getParent(void)
1398 {return _parent;};
1399
1400 /**
1401 * Suspends execution of the selected thread. Pthreads do not
1402 * normally support suspendable threads, so the behavior is
1403 * simulated with signals. On systems such as Linux that
1404 * define threads as processes, SIGSTOP and SIGCONT may be used.
1405 */
1406 void suspend(void);
1407
1408 /**
1409 * Resumes execution of the selected thread.
1410 */
1411 void resume(void);
1412
1413 /**
1414 * Used to retrieve the cancellation mode in effect for the
1415 * selected thread.
1416 *
1417 * @return cancellation mode constant.
1418 */
1419 inline Cancel getCancel(void)
1420 {return _cancel;};
1421
1422 /**
1423 * Verifies if the thread is still running or has already been
1424 * terminated but not yet deleted.
1425 *
1426 * @return true if the thread is still executing.
1427 */
1428 bool isRunning(void) const;
1429
1430 /**
1431 * Check if this thread is detached.
1432 *
1433 * @return true if the thread is detached.
1434 */
1435 bool isDetached(void) const;
1436
1437 /**
1438 * Blocking call which unlocks when thread terminates.
1439 */
1440 void join(void);
1441
1442 /**
1443 * Tests to see if the current execution context is the same as
1444 * the specified thread object.
1445 *
1446 * @return true if the current context is this object.
1447 */
1448 bool isThread(void) const;
1449
1450 /**
1451 * Get system thread numeric identifier.
1452 *
1453 * @return numeric identifier of this thread.
1454 */
1455 cctid_t getId(void) const;
1456
1457 /**
1458 * Get the name string for this thread, to use in
1459 * debug messages.
1460 *
1461 * @return debug name.
1462 */
1463 const char *getName(void) const
1464 {return _name;};
1465
1466 /**
1467 * Get exception mode of the current thread.
1468 *
1469 * @return exception mode.
1470 */
1471 static Throw getException(void);
1472
1473 /**
1474 * Set exception mode of the current thread.
1475 *
1476 * @return exception mode.
1477 */
1478 static void setException(Throw mode);
1479
1480 /**
1481 * Signal the semaphore that the specified thread is waiting for
1482 * before beginning execution.
1483 *
1484 * @param th specified thread.
1485 */
1486 friend inline void operator++(Thread &th)
1487 {if (th._start) th._start->post();};
1488
1489 friend inline void operator--(Thread &th)
1490 {if (th._start) th._start->wait();};
1491
1492#ifdef WIN32
1493 bool isCancelled() const;
1494
1495 static DWORD waitThread(HANDLE hRef, timeout_t timeout);
1496#endif
1497
1498 /**
1499 * This is used to help build wrapper functions in libraries
1500 * around system calls that should behave as cancellation
1501 * points but don't.
1502 *
1503 * @return saved cancel type.
1504 */
1505 static Cancel enterCancel(void);
1506
1507 /**
1508 * This is used to restore a cancel block.
1509 *
1510 * @param cancel type that was saved.
1511 */
1512 static void exitCancel(Cancel cancel);
1513};
1514
1515/**
1516 * A class to automatically set the thread cancellation mode of a
1517 * member function. When the member function returns and the automatic
1518 * variable falls out of scope, the previous thread cancellation mode
1519 * is restored.
1520 *
1521 * @author David Sugar <dyfet@gnu.org>
1522 * @short Automatic cancellation mode setting.
1523 */
1524class __EXPORT Cancellation
1525{
1526private:
1527 Thread::Cancel prior;
1528
1529public:
1530 Cancellation(Thread::Cancel cancel);
1531 ~Cancellation();
1532};
1533
1534#if !defined(WIN32) && !defined(__MINGW32__)
1535typedef int signo_t;
1536
1537class PosixThread: public Thread
1538{
1539private:
1540#ifndef WIN32
1541 /** @internal */
1542 friend class ThreadImpl;
1543 friend class Thread;
1544#endif
1545#ifndef CCXX_SIG_THREAD_ALARM
1546 static PosixThread *_timer;
1547 static Mutex _arm;
1548#endif
1549
1550 time_t _alarm;
1551 static void signalThread(Thread* th,signo_t signo);
1552protected:
1553
1554 /**
1555 * In the Posix version of Common C++, this can be used to send a
1556 * signal into the parent thread of the current object.
1557 *
1558 * @param signo a posix signal id.
1559 */
1560 inline void signalParent(signo_t signo)
1561 { signalThread(_parent,signo); };
1562
1563 /**
1564 * In the Posix version of Common C++, this can be used to send a
1565 * signal into the main application thread.
1566 *
1567 * @param signo a posix signal id.
1568 */
1569 inline void signalMain(signo_t signo)
1570 { signalThread(_main,signo);};
1571
1572 /**
1573 * A derivable method to call when a SIGALRM is being delivered
1574 * to a specific thread.
1575 */
1576 virtual void onTimer(void);
1577
1578 /**
1579 * A derived method to handle hangup events being delivered
1580 * to a specific thread.
1581 */
1582 virtual void onHangup(void);
1583
1584 /**
1585 * A derived method to call when a SIGABRT is being delivered
1586 * to a specific thread.
1587 */
1588 virtual void onException(void);
1589
1590 /**
1591 * A derived method to call when a SIGPIPE is being delivered
1592 * to a specific thread.
1593 */
1594 virtual void onDisconnect(void);
1595
1596 /**
1597 * A derived method to handle asynchronous I/O requests delivered
1598 * to the specified thread.
1599 */
1600 virtual void onPolling(void);
1601
1602 /**
1603 * A derivable method to call for delivering a signal event to
1604 * a specified thread.
1605 *
1606 * @param - posix signal id.
1607 */
1608 virtual void onSignal(int);
1609
1610 /**
1611 * Used to specify a timeout event that can be delivered to the
1612 * current thread via SIGALRM. When the timer expires, the onTimer()
1613 * method is called for the thread. At present, only one thread
1614 * timer can be active at any given time. On some operating
1615 * systems (including Linux) a timer can be active on each thread.
1616 *
1617 * @param timer timeout in milliseconds.
1618 * @param periodic should the timer be periodic.
1619 * @note currently, periodic timers are only available on
1620 * systems with a working setitimer call.
1621 */
1622 void setTimer(timeout_t timer, bool periodic = false);
1623
1624 /**
1625 * Gets the time remaining for the current threads timer before
1626 * it expires.
1627 *
1628 * @return time remaining before timer expires in milliseconds.
1629 */
1630 timeout_t getTimer(void) const;
1631
1632 /**
1633 * Terminates the timer before the timeout period has expired.
1634 * This prevents the timer from sending it's SIGALRM and makes
1635 * the timer available to other threads.
1636 */
1637 void endTimer(void);
1638
1639#if defined(HAVE_SIGWAIT) || defined(HAVE_SIGWAIT2)
1640 /**
1641 * Used to wait on a Posix signal from another thread. This can be
1642 * used as a crude rondevious/synchronization method between threads.
1643 *
1644 * @param signo a posix signal id.
1645 */
1646 void waitSignal(signo_t signo);
1647#endif
1648
1649 /**
1650 * Used to enable or disable a signal within the current thread.
1651 *
1652 * @param signo posix signal id.
1653 * @param active set to true to enable.
1654 */
1655 void setSignal(int signo, bool active);
1656
1657 /**
1658 * Access to pthread_attr structure
1659 * this allows setting/modifying pthread attributes
1660 * not covered in the platform independant Thread constructor,
1661 * e.g. contention scope or scheduling policy
1662 */
1663 pthread_attr_t *getPthreadAttrPtr(void);
1664
1665 /**
1666 * Get pthread_t of underlying posix thread (useful for
1667 * debugging/logging)
1668 */
1669 pthread_t getPthreadId(void);
1670
1671public:
1672
1673 PosixThread(int pri = 0, size_t stack = 0);
1674
1675 /**
1676 * Delivers a Posix signal to the current thread.
1677 *
1678 * @param signo a posix signal id.
1679 */
1680 inline void signalThread(int signo)
1681 {signalThread(this, signo);};
1682
1683 /**
1684 * Install a signal handler for use by threads and
1685 * the OnSignal() event notification handler.
1686 *
1687 * @param signo posix signal id.
1688 */
1689 static void sigInstall(int signo);
1690};
1691#endif
1692
1693/**
1694 * This class allows the creation of a thread context unique "pointer"
1695 * that can be set and retrieved and can be used to create thread specific
1696 * data areas for implementing "thread safe" library routines.
1697 *
1698 * Finally, Common C++ supports a
1699 * thread-safe "AtomicCounter" class. This can often be used for reference
1700 * counting without having to protect the counter with a separate Mutex
1701 * counter. This lends to lighter-weight code.
1702 *
1703 *
1704 * @author David Sugar <dyfet@ostel.com>
1705 * @short container for thread specific data storage.
1706 */
1707class __EXPORT ThreadKey
1708{
1709private:
1710#ifndef WIN32
1711 pthread_key_t key;
1712 typedef void (*TDestruct)(void*);
1713 friend class ThreadImpl;
1714 ThreadKey(TDestruct destruct);
1715#else
1716 DWORD key;
1717#endif
1718
1719public:
1720 /**
1721 * Create a unique thread specific container.
1722 */
1723 ThreadKey();
1724
1725 /**
1726 * Destroy a thread specific container and any contents reserved.
1727 */
1728 virtual ~ThreadKey();
1729
1730 /**
1731 * Get the value of the pointer for the thread specific data
1732 * container. A unique pointer can be set for each execution
1733 * context.
1734 *
1735 * @return a unique void * for each execution context.
1736 */
1737 void *getKey(void);
1738
1739 /**
1740 * Set the value of the pointer for the current thread specific
1741 * execution context. This can be used to store thread context
1742 * specific data.
1743 *
1744 * @param - ptr to thread context specific data.
1745 */
1746 void setKey(void *);
1747};
1748
1749/**
1750 * Timer ports are used to provide synchronized timing events when managed
1751 * under a "service thread" such as SocketService. This is made into a
1752 * stand-alone base class since other derived libraries (such as the
1753 * serial handlers) may also use the pooled "service thread" model
1754 * and hence also require this code for managing timing.
1755 *
1756 * @author David Sugar <dyfet@ostel.com>
1757 * @short synchronized millisecond timing for service threads.
1758 */
1759class __EXPORT TimerPort
1760{
1761#ifndef WIN32
1762 struct timeval timer;
1763#else
1764 DWORD timer;
1765#endif
1766 bool active;
1767
1768public:
1769 /**
1770 * Create a timer, mark it as inactive, and set the initial
1771 * "start" time to the creation time of the timer object. This
1772 * allows "incTimer" to initially refer to time delays relative
1773 * to the original start time of the object.
1774 */
1775 TimerPort();
1776
1777 /**
1778 * Set a new start time for the object based on when this call is
1779 * made and optionally activate the timer for a specified number
1780 * of milliseconds. This can be used to set the starting time
1781 * of a realtime session.
1782 *
1783 * @param timeout delay in milliseconds from "now"
1784 */
1785 void setTimer(timeout_t timeout = 0);
1786
1787 /**
1788 * Set a timeout based on the current time reference value either
1789 * from object creation or the last setTimer(). This reference
1790 * can be used to time synchronize realtime data over specified
1791 * intervals and force expiration when a new frame should be
1792 * released in a synchronized manner.
1793 *
1794 * @param timeout delay in milliseconds from reference.
1795 */
1796 void incTimer(timeout_t timeout);
1797
1798 /**
1799 * Adjust a timeout based on the current time reference value either
1800 * from object creation or the last setTimer(). This reference
1801 * can be used to time synchronize realtime data over specified
1802 * intervals and force expiration when a new frame should be
1803 * released in a synchronized manner.
1804 *
1805 * @param timeout delay in milliseconds from reference.
1806 */
1807 void decTimer(timeout_t timeout);
1808
1809 /**
1810 * Sleep until the current timer expires. This is useful in time
1811 * syncing realtime periodic tasks.
1812 */
1813 void sleepTimer(void);
1814
1815 /**
1816 * This is used to "disable" the service thread from expiring
1817 * the timer object. It does not effect the reference time from
1818 * either creation or a setTimer().
1819 */
1820 void endTimer(void);
1821
1822 /**
1823 * This is used by service threads to determine how much time
1824 * remains before the timer expires based on a timeout specified
1825 * in setTimer() or incTimer(). It can also be called after
1826 * setting a timeout with incTimer() to see if the current timeout
1827 * has already expired and hence that the application is already
1828 * delayed and should skip frame(s).
1829 *
1830 * return time remaining in milliseconds, or TIMEOUT_INF if
1831 * inactive.
1832 */
1833 timeout_t getTimer(void) const;
1834
1835 /**
1836 * This is used to determine how much time has elapsed since a
1837 * timer port setTimer benchmark time was initially set. This
1838 * allows one to use setTimer() to set the timer to the current
1839 * time and then measure elapsed time from that point forward.
1840 *
1841 * return time elapsed in milliseconds, or TIMEOUT_INF if
1842 * inactive.
1843 */
1844 timeout_t getElapsed(void) const;
1845};
1846
1847
1848
1849// FIXME: not in win32 implementation
1850#if !defined(WIN32)
1851
1852// FIXME: private declaration ???
1853struct timespec *getTimeout(struct timespec *spec, timeout_t timeout);
1854
1855#if !defined(__CYGWIN32__) && !defined(__MINGW32__)
1856void wait(signo_t signo);
1857#endif
1858
1859#endif // !WIN32
1860
1861#ifdef USE_POLL
1862
1863/**
1864 * The poller class is used to help manage pollfd structs for use in the
1865 * updated serial and socket "port" code.
1866 *
1867 * @author Gianni Mariani <gianni@mariani.ws>
1868 * @short pollfd assistance class for port classes.
1869 */
1870class Poller
1871{
1872private:
1873 int nufds;
1874 pollfd *ufds;
1875
1876public:
1877 Poller();
1878
1879 virtual ~Poller();
1880
1881 /**
1882 * reserve a specified number of poll descriptors. If additional
1883 * descriptors are needed, they are allocated.
1884 *
1885 * @return new array of descriptors.
1886 * @param cnt number of desctiptors to reserve
1887 */
1888 pollfd *getList(int cnt);
1889
1890 /**
1891 * Retreive the current array of poll descriptors.
1892 *
1893 * @return array of descriptors.
1894 */
1895 inline pollfd *getList(void)
1896 {return ufds;};
1897};
1898#endif
1899
1900inline Thread *getThread(void)
1901 {return Thread::get();}
1902
1903/**
1904 * This class is used to access non-reentrant date and time functions in the
1905 * standard C library.
1906 *
1907 * The class has two purposes:
1908 * - 1 To be used internaly in CommonCpp's date and time classes to make them
1909 * thread safe.
1910 * - 2 To be used by clients as thread safe replacements to the standard C
1911 * functions, much like Thread::sleep() represents a thread safe version
1912 * of the standard sleep() function.
1913 *
1914 * @note The class provides one function with the same name as its equivalent
1915 * standard function and one with another, unique name. For new clients,
1916 * the version with the unique name is recommended to make it easy to
1917 * grep for accidental usage of the standard functions. The version with
1918 * the standard name is provided for existing clients to sed replace their
1919 * original version.
1920 *
1921 * @note Also note that some functions that returned pointers have been redone
1922 * to take that pointer as an argument instead, making the caller
1923 * responsible for memory allocation/deallocation. This is almost
1924 * how POSIX specifies *_r functions (reentrant versions of the
1925 * standard time functions), except the POSIX functions also return the
1926 * given pointer while we do not. We don't use the *_r functions as they
1927 * aren't all generally available on all platforms yet.
1928 *
1929 * @author Idar Tollefsen <idar@cognita.no>
1930 * @short Thread safe date and time functions.
1931 */
1932class __EXPORT SysTime
1933{
1934private:
1935 static Mutex timeLock;
1936
1937protected:
1938 inline static void lock(void)
1939 {timeLock.enterMutex();}
1940
1941 inline static void unlock(void)
1942 {timeLock.leaveMutex();}
1943
1944public:
1945 static time_t getTime(time_t *tloc = NULL);
1946 static time_t time(time_t *tloc)
1947 { return getTime(tloc); };
1948
1949 static int getTimeOfDay(struct timeval *tp);
1950 static int gettimeofday(struct timeval *tp, struct timezone *)
1951 { return getTimeOfDay(tp); };
1952
1953 static struct tm *getLocalTime(const time_t *clock, struct tm *result);
1954 static struct tm *locatime(const time_t *clock, struct tm *result)
1955 { return getLocalTime(clock, result); };
1956
1957 static struct tm *getGMTTime(const time_t *clock, struct tm *result);
1958 static struct tm *gmtime(const time_t *clock, struct tm *result)
1959 { return getGMTTime(clock, result);};
1960};
1961
1962#ifndef HAVE_LOCALTIME_R
1963
1964inline struct tm *localtime_r(const time_t *t, struct tm *b)
1965 {return SysTime::getLocalTime(t, b);};
1966inline char *ctime_r(const time_t *t, char *buf)
1967 {return ctime(t);};
1968inline struct tm *gmtime_r(const time_t *t, struct tm *b) \
1969{return SysTime::getGMTTime(t, b);};
1970inline char *asctime_r(const struct tm *tm, char *b) \
1971 {return asctime(tm);};
1972
1973#endif
1974
1975#ifdef CCXX_NAMESPACES
1976}
1977#endif
1978
1979#endif
1980/** EMACS **
1981 * Local variables:
1982 * mode: c++
1983 * c-basic-offset: 4
1984 * End:
1985 */