// Copyright (C) 1999-2005 Open Source Telecom Corporation.
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// 
// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however    
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.    
//
// This exception applies only to the code released under the name GNU
// Common C++.  If you copy code from other releases into a copy of GNU
// Common C++, as the General Public License permits, the exception does
// not apply to the code that you add in this way.  To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own for GNU Common C++, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice.
//

/**
 * @file thread.h
 * @short Synchronization and threading services.
 **/

#ifndef	CCXX_THREAD_H_
#define	CCXX_THREAD_H_

#ifndef WIN32
#define	CCXX_POSIX
#endif // !WIN32

#ifndef CCXX_CONFIG_H_
#include <cc++/config.h>
#endif

#include <ctime>

#ifndef	WIN32
#include <pthread.h>
#endif // !WIN32

#undef CCXX_USE_WIN32_ATOMIC
#ifndef WIN32
#include <time.h>
#include <signal.h>
#include <unistd.h>

#ifdef	_THR_UNIXWARE
#undef	PTHREAD_MUTEXTYPE_RECURSIVE
#endif

typedef	pthread_t	cctid_t;
typedef	unsigned long	timeout_t;

/*
#if defined(__CYGWIN32__)
__declspec(dllimport) long __stdcall InterlockedIncrement(long *);
__declspec(dllimport) long __stdcall InterlockedDecrement(long *);
__declspec(dllimport) long __stdcall InterlockedExchange(long *, long);
#define CCXX_USE_WIN32_ATOMIC 1
#endif
*/

#else // WIN32
typedef	DWORD	cctid_t;
typedef DWORD   timeout_t;

#define	MAX_SEM_VALUE	1000000
#define CCXX_USE_WIN32_ATOMIC 1

#endif // !WIN32

#ifdef	CCXX_NAMESPACES
namespace ost {
#endif

#ifdef	HAVE_GCC_CXX_BITS_ATOMIC
using namespace __gnu_cxx;
#endif

class __EXPORT Thread;
class __EXPORT ThreadKey;

#define TIMEOUT_INF ~((timeout_t) 0)

#define	ENTER_CRITICAL	enterMutex();
#define	LEAVE_CRITICAL	leaveMutex();
#define	ENTER_DEFERRED	setCancel(cancelDeferred);
#define LEAVE_DEFERRED 	setCancel(cancelImmediate);

#ifndef WIN32
// These macros override common functions with thread-safe versions. In
// particular the common "libc" sleep() has problems since it normally
// uses SIGARLM (as actually defined by "posix").  The pthread_delay and
// usleep found in libpthread are gaurenteed not to use SIGALRM and offer
// higher resolution.  psleep() is defined to call the old process sleep.

#undef	sleep
#define	psleep(x)	(sleep)(x)

#ifdef	signal
#undef	signal
#endif

#endif // !WIN32

#undef Yield

class __EXPORT Conditional;
class __EXPORT Event;

/**
 * The Mutex class is used to protect a section of code so that at any
 * given time only a single thread can perform the protected operation.
 * 
 * The Mutex can be used as a base class to protect access in a derived
 * class.  When used in this manner, the ENTER_CRITICAL and LEAVE_CRITICAL
 * macros can be used to specify when code written for the derived class
 * needs to be protected by the default Mutex of the derived class, and
 * hence is presumed to be 'thread safe' from multiple instance execution.
 * One of the most basic Common C++ synchronization object is the Mutex
 * class.  A Mutex only allows one thread to continue execution at a given
 * time over a specific section of code.  Mutex's have a enter and leave
 * method; only one thread can continue from the Enter until the Leave is
 * called.  The next thread waiting can then get through.  Mutex's are also
 * known as "CRITICAL SECTIONS" in win32-speak.
 * 
 * The Mutex is always recursive in that if the same thread invokes
 * the same mutex lock multiple times, it must release it multiple times.
 * This allows a function to call another function which also happens to
 * use the same mutex lock when called directly. This was
 * deemed essential because a mutex might be used to block individual file
 * requests in say, a database, but the same mutex might be needed to block a
 * whole series of database updates that compose a "transaction" for one
 * thread to complete together without having to write alternate non-locking
 * member functions to invoke for each part of a transaction.
 * 
 * Strangely enough, the original pthread draft standard does not directly
 * support recursive mutexes.  In fact this is the most common "NP" extension
 * for most pthread implementations.  Common C++ emulates recursive mutex
 * behavior when the target platform does not directly support it.
 * 
 * In addition to the Mutex, Common C++ supports a rwlock class.  This
 * implements the X/Open recommended "rwlock".  On systems which do not
 * support rwlock's, the behavior is emulated with a Mutex; however, the
 * advantage of a rwlock over a mutex is then entirely lost.  There has been
 * some suggested clever hacks for "emulating" the behavior of a rwlock with
 * a pair of mutexes and a semaphore, and one of these will be adapted for
 * Common C++ in the future for platforms that do not support rwlock's
 * directly.
 * 
 * @author David Sugar <dyfet@ostel.com>
 * @short Mutex lock for protected access.
 */
class __EXPORT Mutex
{
private:
	static bool _debug;
	const char *_name;
#ifndef WIN32
#ifndef	PTHREAD_MUTEXTYPE_RECURSIVE
	int volatile _level;
	Thread *volatile _tid;
#endif
	/*
	 * Pthread mutex object.  This is protected rather than private
	 * because some mixed mode pthread operations require a mutex as
	 * well as their primary pthread object.  A good example of this
	 * is the Event class, as waiting on a conditional object must be
	 * associated with an accessable mutex.  An alternative would be
	 * to make such classes "friend" classes of the Mutex.
	 */
	pthread_mutex_t	_mutex;
#else // WIN32

# if defined(MUTEX_UNDERGROUND_WIN32_MUTEX) && defined(MUTEX_UNDERGROUND_WIN32_CRITICALSECTION)
# error "Can't determine underground for Mutex"
# endif

#ifdef MUTEX_UNDERGROUND_WIN32_MUTEX 
	HANDLE _mutex;
#endif
#ifdef MUTEX_UNDERGROUND_WIN32_CRITICALSECTION 
	CRITICAL_SECTION _criticalSection;
#endif

#endif // WIN32

public:
	/**
	 * The mutex is always initialized as a recursive entity.
	 */
	Mutex(const char *name = NULL);

	/**
	 * Destroying the mutex removes any system resources associated
	 * with it.  If a mutex lock is currently in place, it is presumed
	 * to terminate when the Mutex is destroyed.
	 */
	virtual ~Mutex();

	/**
	 * Enable or disable deadlock debugging.
	 *
	 * @param mode debug mode.
	 */
	static void setDebug(bool mode)
		{_debug = mode;};

	/**
	 * Enable setting of mutex name for deadlock debug.
	 *
	 * @param name for mutex.
	 */
	inline void nameMutex(const char *cp)
		{_name = cp;};

	/**
	 * Entering a Mutex locks the mutex for the current thread.  This
	 * also can be done using the ENTER_CRITICAL macro or by using the
	 * ++ operator on a mutex.
	 * 
	 * @see #leaveMutex
	 */
	void enterMutex(void);

	/**
	 * Future abi will use enter/leave/test members.
	 */
	inline void enter(void)
		{enterMutex();};

	inline void leave(void)
		{leaveMutex();};

	inline bool test(void)
		{return tryEnterMutex();};

	/**
	 * Tries to lock the mutex for the current thread. Behaves like
	 * #enterMutex , except that it doesn't block the calling thread
	 * if the mutex is already locked by another thread.
	 *
	 * @return true if locking the mutex was succesful otherwise false
	 *
	 * @see enterMutex
	 * @see leaveMutex
	 */
	bool tryEnterMutex(void);

	/**
	 * Leaving a mutex frees that mutex for use by another thread.  If
	 * the mutex has been entered (invoked) multiple times (recursivily)
	 * by the same thread, then it will need to be exited the same number
	 * of instances before it is free for re-use.  This operation can
	 * also be done using the LEAVE_CRITICAL macro or by the -- operator
	 * on a mutex.
	 * 
	 * @see #enterMutex
	 */
	void leaveMutex(void);
};

/**
 * The MutexLock class is used to protect a section of code so that at any
 * given time only a single thread can perform the protected operation.
 * 
 * It use Mutex to protect operation. Using this class is usefull and 
 * exception safe.  The mutex that has been locked is automatically
 * released when the function call stack falls out of scope, so one doesnt
 * have to remember to unlock the mutex at each function return.
 * 
 * A common use is
 * 
 * void func_to_protect()
 * {
 *   MutexLock lock(mutex);
 *   ... operation ...
 * }
 *
 * NOTE: do not declare variable as "MutexLock (mutex)", the mutex will be 
 * released at statement end.
 * 
 * @author Frediano Ziglio <freddy77@angelfire.com>
 * @short Mutex automatic locker for protected access.
 */
class __EXPORT MutexLock
{
private:
	Mutex& mutex;
public:
	/**
	 * Acquire the mutex
	 */
	MutexLock( Mutex& _mutex ) : mutex( _mutex ) 
		{ mutex.enterMutex(); }
	/**
	 * Release the mutex automatically
	 */
	// this should be not-virtual
	~MutexLock()
		{ mutex.leaveMutex(); }
};

/**
 * The ThreadLock class impliments a thread rwlock for optimal reader performance
 * on systems which have rwlock support, and reverts to a simple mutex for those
 * that do not.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Posix rwlock extension for protected access.
 */
class __EXPORT ThreadLock
{
private:
#ifdef HAVE_PTHREAD_RWLOCK
	pthread_rwlock_t _lock;
#else
	Mutex mutex;
#endif

public:
	/**
	 * Create a process shared thread lock object.
	 */
	ThreadLock();

	/**
	 * Destroy a process shared thread lock object.
	 */
	virtual ~ThreadLock();

	/**
	 * Aquire a read lock for the current object.
	 */
	void readLock(void);

	/**
	 * Aquire a write lock for the current object.
	 */
	void writeLock(void);

	/**
	 * Attempt read lock for current object.
	 *
	 * @return true on success.
	 */
	bool tryReadLock(void);

	/**
	 * Attempt write lock for current object.
	 *
	 * @return true on success.
	 */
	bool tryWriteLock(void);

	/**
	 * Release any held locks.
	 */
	void unlock(void);
};

/**
 * The ReadLock class is used to protect a section of code through
 * a ThreadLock for "read" access to the member function.  The 
 * ThreadLock is automatically released when the object falls out of
 * scope.
 * 
 * A common use is
 * 
 * void func_to_protect()
 * {
 *   ReadLock lock(threadlock);
 *   ... operation ...
 * }
 *
 * NOTE: do not declare variable as "ReadLock (threadlock)", the 
 * mutex will be released at statement end.
 * 
 * @author David Sugar <dyfet@gnu.org>
 * @short Read mode automatic locker for protected access.
 */
class __EXPORT ReadLock
{
private:
	ThreadLock& tl;

public:
	/**
	 * Wait for read access
	 */
	ReadLock( ThreadLock& _tl ) : tl( _tl ) 
		{ tl.readLock(); }
	/**
	 * Post the semaphore automatically
	 */
	// this should be not-virtual
	~ReadLock()
		{ tl.unlock(); }
};

/**
 * The WriteLock class is used to protect a section of code through
 * a ThreadLock for "write" access to the member function.  The 
 * ThreadLock is automatically released when the object falls out of
 * scope.
 * 
 * A common use is
 * 
 * void func_to_protect()
 * {
 *   WriteLock lock(threadlock);
 *   ... operation ...
 * }
 *
 * NOTE: do not declare variable as "WriteLock (threadlock)", the 
 * mutex will be released at statement end.
 * 
 * @author David Sugar <dyfet@gnu.org>
 * @short Read mode automatic locker for protected access.
 */
class __EXPORT WriteLock
{
private:
	ThreadLock& tl;

public:
	/**
	 * Wait for read access
	 */
	WriteLock( ThreadLock& _tl ) : tl( _tl ) 
		{ tl.writeLock(); }
	/**
	 * Post the semaphore automatically
	 */
	// this should be not-virtual
	~WriteLock()
		{ tl.unlock(); }
};


/**
 * The Mutex Counter is a counter variable which can safely be incremented
 * or decremented by multiple threads.  A Mutex is used to protect access
 * to the counter variable (an integer).  An initial value can be specified 
 * for the counter, and it can be manipulated with the ++ and -- operators.
 * 
 * @author David Sugar <dyfet@ostel.com>
 * @short Thread protected integer counter.
 */
class __EXPORT MutexCounter : public Mutex
{
private:
	volatile int	counter;

public:
	MutexCounter(const char *id = NULL);
	MutexCounter(int initial, const char *id = NULL);

	friend __EXPORT int operator++(MutexCounter &mc);
	friend __EXPORT int operator--(MutexCounter &mc);
};

/**
 * The AtomicCounter class offers thread-safe manipulation of an integer
 * counter.  These are commonly used for building thread-safe "reference"
 * counters for C++ classes.  The AtomicCounter depends on the platforms
 * support for "atomic" integer operations, and can alternately substitute
 * a "mutex" if no atomic support exists.
 *
 * @author Sean Cavanaugh <sean@dimensionalrift.com>
 * @short atomic counter operation.
 */
class __EXPORT AtomicCounter
{
#ifndef CCXX_USE_WIN32_ATOMIC
private:
#ifdef	HAVE_ATOMIC_AIX
	volatile int counter;
#elif   HAVE_GCC_BITS_ATOMIC
	volatile _Atomic_word counter;
#elif   HAVE_GCC_CXX_BITS_ATOMIC
	volatile _Atomic_word counter;
//	__gnu_cxx::_Atomic_word counter;
#elif	HAVE_ATOMIC
	atomic_t atomic;
#else
	volatile int counter;
	pthread_mutex_t _mutex;
#endif

public:
	/**
	 * Initialize an atomic counter to 0.
	 */
	AtomicCounter();

	/**
	 * Initialize an atomic counter to a known value.
	 *
	 * @param value initial value.
	 */
	AtomicCounter(int value);

	~AtomicCounter();

	int operator++(void);
	int operator--(void);
	int operator+=(int change);
	int operator-=(int change);
	int operator+(int change);
	int operator-(int change);
	int operator=(int value);
	bool operator!(void);
	operator int();
#else
private:
	long atomic;

public:
	inline AtomicCounter()
		{atomic = 0;};

	inline AtomicCounter(int value)
		{atomic = value;};

	inline int operator++(void)
		{return InterlockedIncrement(&atomic);};

	inline int operator--(void)
		{return InterlockedDecrement(&atomic);};

	int operator+=(int change);

	int operator-=(int change);

	inline int operator+(int change)
		{return atomic + change;};

	inline int operator-(int change)
		{return atomic - change;};
	
	inline int operator=(int value)
		{return InterlockedExchange(&atomic, value);};

	inline bool operator!(void)
		{return (atomic == 0) ? true : false;};

	inline operator int()
		{return atomic;};
#endif
};

#ifndef WIN32
/**
 * A conditional variable synchcronization object for one to one and
 * one to many signal and control events between processes.
 * Conditional variables may wait for and receive signals to notify
 * when to resume or perform operations.  Multiple waiting threads may
 * be woken with a broadcast signal.
 *
 * @warning While this class inherits from Mutex, the methods of the
 * class Conditional just handle the system conditional variable, so
 * the user is responsible for calling enterMutex and leaveMutex so as
 * to avoid race conditions. Another thing to note is that if you have
 * several threads waiting on one condition, not uncommon in thread
 * pools, each thread must take care to manually unlock the mutex if
 * cancellation occurs. Otherwise the first thread cancelled will
 * deadlock the rest of the thread.
 *
 * @author David Sugar
 * @short conditional.
 * @todo implement in win32
 */
class __EXPORT Conditional 
{
private:
	pthread_cond_t _cond;
	pthread_mutex_t _mutex;

public:
	/**
	 * Create an instance of a conditional.
	 */
	Conditional(const char *id = NULL);

	/**
	 * Destroy the conditional.
	 */
	virtual ~Conditional();

	/**
	 * Signal a conditional object and a waiting threads.
	 *
	 * @param broadcast this signal to all waiting threads if true.
	 */
	void signal(bool broadcast);

	/**
 	 * Wait to be signaled from another thread.
	 *
	 * @param timer time period to wait.
	 * @param locked flag if already locked the mutex.
	 */
	bool wait(timeout_t timer = 0, bool locked = false);

        /**
         * Locks the conditional's mutex for this thread.  Remember
	 * that Conditional's mutex is NOT a recursive mutex!
         *
         * @see #leaveMutex
         */
        void enterMutex(void);

	/**
	 * In the future we will use lock in place of enterMutex since
	 * the conditional composite is not a recursive mutex, and hence
	 * using enterMutex may cause confusion in expectation with the
	 * behavior of the Mutex class.
	 *
	 * @see #enterMutex
	 */
	inline void lock(void)
		{enterMutex();};

        /**
         * Tries to lock the conditional for the current thread. 
	 * Behaves like #enterMutex , except that it doesn't block the 
	 * calling thread.
         *
         * @return true if locking the mutex was succesful otherwise false
         *
         * @see enterMutex
         * @see leaveMutex
         */
        bool tryEnterMutex(void);

	inline bool test(void)
		{return tryEnterMutex();};

        /**
         * Leaving a mutex frees that mutex for use by another thread.  
	 *
         * @see #enterMutex
         */
        void leaveMutex(void);

	inline void unlock(void)
		{return leaveMutex();};
};
#endif

/**
 * A semaphore is generally used as a synchronization object between multiple
 * threads or to protect a limited and finite resource such as a memory or
 * thread pool.  The semaphore has a counter which only permits access by
 * one or more threads when the value of the semaphore is non-zero.  Each
 * access reduces the current value of the semaphore by 1.  One or more
 * threads can wait on a semaphore until it is no longer 0, and hence the
 * semaphore can be used as a simple thread synchronization object to enable
 * one thread to pause others until the thread is ready or has provided data
 * for them.  Semaphores are typically used as a
 * counter for protecting or limiting concurrent access to a given
 * resource, such as to permitting at most "x" number of threads to use
 * resource "y", for example.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short Semaphore counter for thread synchronization.
 */
class __EXPORT Semaphore
{
private:
#ifndef WIN32
	unsigned _count, _waiters;
	pthread_mutex_t _mutex;
	pthread_cond_t _cond;
#else
	HANDLE	semObject;
#endif // !WIN32

public:
	/**
	 * The initial value of the semaphore can be specified.  An initial
	 * value is often used When used to lock a finite resource or to
	 * specify the maximum number of thread instances that can access a
	 * specified resource.
	 *
	 * @param resource specify initial resource count or 0 default.
	 */
	Semaphore(unsigned resource = 0);

	/**
	 * Destroying a semaphore also removes any system resources
	 * associated with it.  If a semaphore has threads currently waiting
	 * on it, those threads will all continue when a semaphore is
	 * destroyed.
	 */
	virtual ~Semaphore();

	/**
	 * Wait is used to keep a thread held until the semaphore counter
	 * is greater than 0.  If the current thread is held, then another
	 * thread must increment the semaphore.  Once the thread is accepted, 
	 * the semaphore is automatically decremented, and the thread 
	 * continues execution.
	 * 
	 * The pthread semaphore object does not support a timed "wait", and
	 * hence to maintain consistancy, neither the posix nor win32 source
	 * trees support "timed" semaphore objects.
	 * 
	 * @return false if timed out
	 * @param timeout period in milliseconds to wait
	 * @see #post
	 */
	bool wait(timeout_t timeout = 0);

	/**
	 * Posting to a semaphore increments its current value and releases
	 * the first thread waiting for the semaphore if it is currently at
	 * 0.  Interestingly, there is no support to increment a semaphore by
	 * any value greater than 1 to release multiple waiting threads in
	 * either pthread or the win32 API.  Hence, if one wants to release
	 * a semaphore to enable multiple threads to execute, one must perform
	 * multiple post operations.
	 * 
	 * @see #wait
	 */
	void post(void);

	// FIXME: how implement getValue for posix compatibility ?
	// not portable...

#if	0
	/**
	 * Get the current value of a semaphore.
	 *
	 * @return current value.
	 */
	int getValue(void);
#endif
};

/**
 * The SemaphoreLock class is used to protect a section of code through
 * a semaphore so that only x instances of the member function may
 * execute concurrently.
 * 
 * A common use is
 * 
 * void func_to_protect()
 * {
 *   SemaphoreLock lock(semaphore);
 *   ... operation ...
 * }
 *
 * NOTE: do not declare variable as "SemaohoreLock (semaphore)", the 
 * mutex will be released at statement end.
 * 
 * @author David Sugar <dyfet@gnu.org>
 * @short Semaphore automatic locker for protected access.
 */
class __EXPORT SemaphoreLock
{
private:
	Semaphore& sem;

public:
	/**
	 * Wait for the semaphore
	 */
	SemaphoreLock( Semaphore& _sem ) : sem( _sem ) 
		{ sem.wait(); }
	/**
	 * Post the semaphore automatically
	 */
	// this should be not-virtual
	~SemaphoreLock()
		{ sem.post(); }
};

/**
 * The Event class implements a feature originally found in the WIN32 API;
 * event notification.  A target thread waits on a resetable Event, and one
 * or more other threads can then signal the waiting thread to resume 
 * execution.  A timeout can be used to specify a wait duration in 
 * milliseconds.  The Event class must be reset before it can be used again 
 * as a trigger.  These event objects
 * use a trigger/reset mechanism and are related to low level conditional
 * variables.
 * 
 * @author: David Sugar <dyfet@ostel.com>
 * @short Thread synchornization on event notification.
 */
class __EXPORT Event
{
private:
#ifndef WIN32
	pthread_mutex_t _mutex;
	pthread_cond_t _cond;
	bool _signaled;
	int _count;
#else
	HANDLE cond;
#endif

public:
	Event();

	virtual ~Event();

	/**
	 * Once signaled, the Event class must be "reset" before responding
	 * to a new signal.
	 * 
	 * @see #signal
	 */
	void reset(void);

	/**
	 * Signal the event for the waiting thread.
	 */
	void signal(void);

	/**
	 * Wait either for the event to be signaled by another thread or
	 * for the specified timeout duration.
	 * 
	 * @see #signal
	 * @return true if signaled, false if timed out.
	 * @param timer timeout in milliseconds to wait for a signal.
	 */
	bool wait(timeout_t timer);
	bool wait(void);
};


/**
 * Every thread of execution in an application is created by
 * instantiating an object of a class derived from the Thread
 * class. Classes derived from Thread must implement the run() method,
 * which specifies the code of the thread. The base Thread class
 * supports encapsulation of the generic threading methods implemented
 * on various target operating systems.  This includes the ability to
 * start and stop threads in a synchronized and controllable manner,
 * the ability to specify thread execution priority, and thread
 * specific "system call" wrappers, such as for sleep and yield.  A
 * thread exception is thrown if the thread cannot be created.
 * Threading was the first part of Common C++ I wrote, back when it
 * was still the APE library.  My goal for Common C++ threading has
 * been to make threading as natural and easy to use in C++
 * application development as threading is in Java.  With this said,
 * one does not need to use threading at all to take advantage of
 * Common C++.  However, all Common C++ classes are designed at least
 * to be thread-aware/thread-safe as appropriate and necessary.
 * 
 * Common C++ threading is currently built either from the Posix "pthread"
 * library or using the win32 SDK.  In that the Posix "pthread" draft
 * has gone through many revisions, and many system implementations are
 * only marginally compliant, and even then usually in different ways, I
 * wrote a large series of autoconf macros found in ost_pthread.m4 which
 * handle the task of identifying which pthread features and capabilities
 * your target platform supports.  In the process I learned much about what
 * autoconf can and cannot do for you..
 * 
 * Currently the GNU Portable Thread library (GNU pth) is not directly
 * supported in Common C++.  While GNU "Pth" doesn't offer direct
 * native threading support or benefit from SMP hardware, many of the design
 * advantages of threading can be gained from it's use, and the  Pth pthread
 * "emulation" library should be usable with Common C++.  In the future,
 * Common C++ will directly support Pth, as well as OS/2 and BeOS native
 * threading API's.
 * 
 * Common C++ itself defines a fairly "neutral" threading model that is
 * not tied to any specific API such as pthread, win32, etc.  This neutral
 * thread model is contained in a series of classes which handle threading
 * and synchronization and which may be used together to build reliable
 * threaded applications.
 * 
 * Common C++ defines application specific threads as objects which are
 * derived from the Common C++ "Thread" base class.  At minimum the "Run"
 * method must be implemented, and this method essentially is the "thread",
 * for it is executed within the execution context of the thread, and when
 * the Run method terminates the thread is assumed to have terminated.
 * 
 * Common C++ allows one to specify the running priority of a newly created
 * thread relative to the "parent" thread which is the thread that is
 * executing when the constructor is called.  Since most newer C++
 * implementations do not allow one to call virtual constructors or virtual
 * methods from constructors, the thread must be "started" after the
 * constructor returns.  This is done either by defining a "starting"
 * semaphore object that one or more newly created thread objects can wait
 * upon, or by invoking an explicit "start" member function.
 * 
 * Threads can be "suspended" and "resumed".  As this behavior is not defined
 * in the Posix "pthread" specification, it is often emulated through
 * signals.  Typically SIGUSR1 will be used for this purpose in Common C++
 * applications, depending in the target platform.  On Linux, since threads
 * are indeed processes, SIGSTP and SIGCONT can be used.  On solaris, the
 * Solaris thread library supports suspend and resume directly.
 * 
 * Threads can be canceled.  Not all platforms support the concept of
 * externally cancelable threads.  On those platforms and API
 * implementations that do not, threads are typically canceled through the
 * action of a signal handler.
 * 
 * As noted earlier, threads are considered running until the "Run" method
 * returns, or until a cancellation request is made.  Common C++ threads can
 * control how they respond to cancellation, using setCancellation().
 * Cancellation requests can be ignored, set to occur only when a
 * cancellation "point" has been reached in the code, or occur immediately.
 * Threads can also exit by returning from Run() or by invoking the Exit()
 * method.
 * 
 * Generally it is a good practice to initialize any resources the thread may
 * require within the constructor of your derived thread class, and to purge
 * or restore any allocated resources in the destructor.  In most cases, the
 * destructor will be executed after the thread has terminated, and hence
 * will execute within the context of the thread that requested a join rather
 * than in the context of the thread that is being terminated.  Most
 * destructors in derived thread classes should first call Terminate() to
 * make sure the thread has stopped running before releasing resources.
 * 
 * A Common C++ thread is normally canceled by deleting the thread object.
 * The process of deletion invokes the thread's destructor, and the
 * destructor will then perform a "join" against the thread using the
 * Terminate() function.  This behavior is not always desirable since the
 * thread may block itself from cancellation and block the current "delete"
 * operation from completing.  One can alternately invoke Terminate()
 * directly before deleting a thread object.
 * 
 * When a given Common C++ thread exits on it's own through it's Run()
 * method, a "Final" method will be called.  This Final method will be called
 * while the thread is "detached".  If a thread object is constructed through
 * a "new" operator, it's final method can be used to "self delete" when
 * done, and allows an independent thread to construct and remove itself
 * autonomously.
 * 
 * A special global function, getThread(), is provided to identify the thread
 * object that represents the current execution context you are running
 * under.  This is sometimes needed to deliver signals to the correct thread.
 * Since all thread manipulation should be done through the Common C++ (base) 
 * thread class itself, this provides the same functionality as things like
 * "pthread_self" for Common C++.
 *
 * All Common C++ threads have an exception "mode" which determines
 * their behavior when an exception is thrown by another Common C++
 * class.  Extensions to Common C++ should respect the current
 * exception mode and use getException() to determine what to do when
 * they are about to throw an object.  The default exception mode
 * (defined in the Thread() constructor) is throwObject, which causes
 * a pointer to an instance of the class where the error occured to be
 * thrown.  Other exception modes are throwException, which causes a
 * class-specific exception class to be thrown, and throwNothing,
 * which causes errors to be ignored.  
 *
 * As an example, you could try to call the Socket class with an
 * invalid address that the system could not bind to.  This would
 * cause an object of type Socket * to be thrown by default, as the
 * default exception mode is throwObject.  If you call
 * setException(throwException) before the bad call to the Socket
 * constructor, an object of type SockException (the exception class
 * for class Socket) will be thrown instead.  
 *
 * To determine what exception class is thrown by a given Common C++
 * class when the exception mode is set to throwException, search the
 * source files for the class you are interested in for a class which
 * inherits directly or indirectly from class Exception.  This is the
 * exception class which would be thrown when the exception mode is
 * set to throwException.
 *
 * The advantage of using throwException versus throwObject is that
 * more information is available to the programmer from the thrown
 * object.  All class-specific exceptions inherit from class
 * Exception, which provides a getString() method which can be called
 * to get a human-readable error string.
 * 
 * Common C++ threads are often aggregated into other classes to provide
 * services that are "managed" from or operate within the context of a
 * thread, even within the Common C++ framework itself.  A good example of
 * this is the TCPSession class, which essentially is a combination of a TCP
 * client connection and a separate thread the user can define by deriving a
 * class with a Run() method to handle the connected service.  This
 * aggregation logically connects the successful allocation of a given
 * resource with the construction of a thread to manage and perform 
 * operations for said resource.
 * 
 * Threads are also used in "service pools".  In Common C++, a service pool
 * is one or more threads that are used to manage a set of resources.  While
 * Common C++ does not provide a direct "pool" class, it does provide a model
 * for their implementation, usually by constructing an array of thread
 * "service" objects, each of which can then be assigned the next new
 * instance of a given resource in turn or algorithmically.
 * 
 * Threads have signal handlers associated with them.  Several signal types
 * are "predefined" and have special meaning.  All signal handlers are
 * defined as virtual member functions of the Thread class which are called
 * when a specific signal is received for a given thread.  The "SIGPIPE"
 * event is defined as a "Disconnect" event since it's normally associated
 * with a socket disconnecting or broken fifo.  The Hangup() method is
 * associated with the SIGHUP signal.  All other signals are handled through
 * the more generic Signal().
 * 
 * Incidently, unlike Posix, the win32 API has no concept of signals, and
 * certainly no means to define or deliver signals on a per-thread basis.
 * For this reason, no signal handling is supported or emulated in the win32
 * implementation of Common C++ at this time.
 * 
 * In addition to TCPStream, there is a TCPSession class which combines a
 * thread with a TCPStream object.  The assumption made by TCPSession is that
 * one will service each TCP connection with a separate thread, and this
 * makes sense for systems where extended connections may be maintained and
 * complex protocols are being used over TCP.
 * 
 * 
 * @author David Sugar <dyfet@ostel.com>
 * @short base class used to derive all threads of execution.
 */
class __EXPORT Thread
{
public:
	/**
	 * How to raise error
	 */
	typedef enum Throw {
		throwNothing,  /**< continue without throwing error */
		throwObject,   /**< throw object that cause error (throw this) */
		throwException /**< throw an object relative to error */
	} Throw;
	
	/**
	 * How work cancellation
	 */
	typedef enum Cancel
	{
		cancelInitial=0,  /**< used internally, do not use */
		cancelDeferred=1, /**< exit thread on cancellation pointsuch as yield */
		cancelImmediate,  /**< exit befor cancellation */
		cancelDisabled,   /**< ignore cancellation */
		cancelManual,     /**< unimplemented (working in progress)
					    @todo implement */
		cancelDefault=cancelDeferred
			/**< default you should use this for compatibility instead of deferred */
	} Cancel;

	/**
	 * How work suspend
	 */
	typedef enum Suspend
	{
		suspendEnable, /**< suspend enabled */
	        suspendDisable /**< suspend disabled, Suspend do nothing */
	} Suspend;

#ifndef WIN32
/** @internal */
friend class PosixThread;
#endif
/** @internal */
friend class DummyThread;
private:
	friend class Cancellation;
	friend class postream_type;
	friend class Slog;

	Semaphore joinSem;
	static Thread* _main;

	Thread *_parent;
	Cancel _cancel;
	Semaphore *_start;

	// private data
	friend class ThreadImpl;
	class ThreadImpl* priv;

public:
	static Thread *get(void);

private:
#ifdef	WIN32
	static unsigned __stdcall Execute(Thread *th);
#endif

	// close current thread, free all and call Notify
	void close();

private:
	char _name[32];
	static size_t _autostack;

#ifdef WIN32
        DWORD waitHandle(HANDLE obj, timeout_t timeout);
#endif

protected:
	/**
	 * Set the name of the current thread.  If the name is passed
	 * as NULL, then the default name is set (usually object
	 * pointer).
	 *
	 * @param text name to use.
	 */
	void setName(const char *text);

       	/**
	 * All threads execute by deriving the Run method of Thread.
	 * This method is called after Initial to begin normal operation
	 * of the thread.  If the method terminates, then the thread will
	 * also terminate after notifying it's parent and calling it's
	 * Final() method.
	 *
	 * @see #Initial
	 */
	virtual void run(void) = 0;

	/**
	 * A thread that is self terminating, either by invoking exit() or
	 * leaving it's run(), will have this method called.  It can be used
	 * to self delete the current object assuming the object was created
	 * with new on the heap rather than stack local, hence one may often
	 * see final defined as "delete this" in a derived thread class.  A
	 * final method, while running, cannot be terminated or cancelled by
	 * another thread. Final is called for all cancellation type (even
	 * immediate).
	 * 
	 * You can safe delete thread ("delete this") class on final, but 
	 * you should exit ASAP (or do not try to call CommonC++ methods...)
	 * 
	 * @note A thread cannot delete its own context or join
	 * itself.  To make a thread that is a self running object
	 * that self-deletes, one has to detach the thread by using
	 * detach() instead of start().
	 *
	 * @see #exit
	 * @see #run
	 */
	virtual void final(void);

	/**
	 * The initial method is called by a newly created thread when it
	 * starts execution.  This method is ran with deferred cancellation
	 * disabled by default.  The Initial method is given a separate
	 * handler so that it can create temporary objects on it's own
	 * stack frame, rather than having objects created on run() that
	 * are only needed by startup and yet continue to consume stack space.
	 * 
	 * @see #run
	 * @see #final
	 */
	virtual void initial(void);

	/**
	 * Since getParent() and getThread() only refer to an object of the
	 * Thread "base" type, this virtual method can be replaced in a
	 * derived class with something that returns data specific to the
	 * derived class that can still be accessed through the pointer
	 * returned by getParent() and getThread().
	 *
	 * @return pointer to derived class specific data.
	 */
	virtual void* getExtended(void);

	/**
	 * When a thread terminates, it now sends a notification message
	 * to the parent thread which created it.  The actual use of this
	 * notification is left to be defined in a derived class.
	 * 
	 * @param - the thread that has terminated.
	 */
	virtual void notify(Thread*);

	/**
	 * Used to properly exit from a Thread derived run() or initial()
	 * method.  Terminates execution of the current thread and calls
	 * the derived classes final() method.
	 */
	void exit(void);

	/**
	 * Used to wait for a join or cancel, in place of explicit exit.
	 */
	void sync(void);

	/**
	 * test a cancellation point for deferred thread cancellation.
	 */
	bool testCancel(void);

	/**
	 * Sets thread cancellation mode.  Threads can either be set immune to
	 * termination (cancelDisabled), can be set to terminate when
	 * reaching specific "thread cancellation points"
	 * (cancelDeferred)
	 * or immediately when Terminate is requested (cancelImmediate).
	 * 
	 * @param mode for cancellation of the current thread.
	 */
	void setCancel(Cancel mode);

	/**
	 * Sets the thread's ability to be suspended from execution.  The
	 * thread may either have suspend enabled (suspendEnable) or
	 * disabled (suspendDisable).
	 * 
	 * @param mode for suspend.
	 */
	void setSuspend(Suspend mode);

	/**
	 * Used by another thread to terminate the current thread.  Termination
	 * actually occurs based on the current setCancel() mode.  When the
	 * current thread does terminate, control is returned to the requesting
	 * thread.  terminate() should always be called at the start of any
	 * destructor of a class derived from Thread to assure the remaining
	 * part of the destructor is called without the thread still executing.
	 */
	void terminate(void);

	/**
	 * clear parent thread relationship.
	 */
	inline void clrParent(void)
		{_parent = NULL;};

public:
	/**
	 * This is actually a special constructor that is used to create a
	 * thread "object" for the current execution context when that context
	 * is not created via an instance of a derived Thread object itself.
	 * This constructor does not support First.
	 * 
	 * @param isMain bool used if the main "thread" of the application.
	 */
	Thread(bool isMain);

	/**
	 * When a thread object is contructed, a new thread of execution
	 * context is created.  This constructor allows basic properties
	 * of that context (thread priority, stack space, etc) to be defined.
	 * The starting condition is also specified for whether the thread
	 * is to wait on a semaphore before begining execution or wait until
	 * it's start method is called.
	 * 
	 * @param pri thread base priority relative to it's parent.
	 * @param stack space as needed in some implementations.
	 */
	Thread(int pri = 0, size_t stack = 0);

#ifndef WIN32
	/**
	 * A thread of execution can also be specified by cloning an existing
	 * thread.  The existing thread's properties (cancel mode, priority,
	 * etc), are also duplicated.
	 * 
	 * @param th currently executing thread object to clone.
	 * @todo implement in win32
	 */
	Thread(const Thread &th);
#endif

	/**
	 * The thread destructor should clear up any resources that have
	 * been allocated by the thread.  The desctructor of a derived
	 * thread should begin with Terminate() and is presumed to then
	 * execute within the context of the thread causing terminaton.
	 */
	virtual ~Thread();

	/**
	 * Set base stack limit before manual stack sizes have effect.
	 *
	 * @param size stack size to set, or use 0 to clear autostack.
	 */
	static void setStack(size_t size = 0)
		{_autostack = size;};

	/**
	 * A thread-safe sleep call.  On most Posix systems, "sleep()"
	 * is implimented with SIGALRM making it unusable from multipe
	 * threads.  Pthread libraries often define an alternate "sleep"
	 * handler such as usleep(), nanosleep(), or nap(), that is thread
	 * safe, and also offers a higher timer resolution.
	 * 
	 * @param msec timeout in milliseconds.
	 */
	static void sleep(timeout_t msec);

	/**
	 * Yields the current thread's CPU time slice to allow another thread to
	 * begin immediate execution.
	 */
	static void yield(void);

	/**
	 * When a new thread is created, it does not begin immediate
	 * execution.  This is because the derived class virtual tables
	 * are not properly loaded at the time the C++ object is created
	 * within the constructor itself, at least in some compiler/system 
	 * combinations.  The thread can either be told to wait for an
	 * external semaphore, or it can be started directly after the
	 * constructor completes by calling the start() method.
	 * 
	 * @return error code if execution fails.
	 * @param start optional starting semaphore to alternately use.
	 */
	int start(Semaphore *start = 0);

	/**
	 * Start a new thread as "detached".  This is an alternative
	 * start() method that resolves some issues with later glibc
	 * implimentations which incorrectly impliment self-detach.
	 *
	 * @return error code if execution fails.
	 * @param start optional starting semaphore to alternately use.
	 */
	int detach(Semaphore *start = 0);

	/**
	 * Gets the pointer to the Thread class which created the current
	 * thread object.
	 * 
	 * @return a Thread *, or "(Thread *)this" if no parent.
	 */
	inline Thread *getParent(void)
		{return _parent;};

	/**
	 * Suspends execution of the selected thread.  Pthreads do not
	 * normally support suspendable threads, so the behavior is
	 * simulated with signals.  On systems such as Linux that
	 * define threads as processes, SIGSTOP and SIGCONT may be used.
	 */
	void suspend(void);

	/**
	 * Resumes execution of the selected thread.
	 */
	void resume(void);

	/**
	 * Used to retrieve the cancellation mode in effect for the
	 * selected thread.
	 * 
	 * @return cancellation mode constant.
	 */
	inline Cancel getCancel(void)
		{return _cancel;};

	/**
	 * Verifies if the thread is still running or has already been
	 * terminated but not yet deleted.
	 * 
	 * @return true if the thread is still executing.
	 */
	bool isRunning(void);

	/**
	 * Check if this thread is detached.
	 *
	 * @return true if the thread is detached.
	 */
	bool isDetached(void);

        /**
	 * Blocking call which unlocks when thread terminates.
	 */
	void join(void);

	/**
	 * Tests to see if the current execution context is the same as
	 * the specified thread object.
	 * 
	 * @return true if the current context is this object.
	 */
	bool isThread(void);

	/**
	 * Get system thread numeric identifier.
	 *
	 * @return numeric identifier of this thread.
	 */
	cctid_t getId(void) const;

	/**
	 * Get the name string for this thread, to use in
	 * debug messages.
	 *
	 * @return debug name.
	 */
	const char *getName(void)
		{return _name;};

	/**
	 * Get exception mode of the current thread.
	 *
	 * @return exception mode.
	 */
	static Throw getException(void);

	/**
	 * Set exception mode of the current thread.
	 *
	 * @return exception mode.
	 */
	static void setException(Throw mode);

	/**
	 * Signal the semaphore that the specified thread is waiting for
	 * before beginning execution.
	 * 
	 * @param th specified thread.
	 */
	friend inline void operator++(Thread &th)
		{if (th._start) th._start->post();};

	friend inline void operator--(Thread &th)
		{if (th._start) th._start->wait();};

#ifdef WIN32
	bool isCancelled();

	static DWORD waitThread(HANDLE hRef, timeout_t timeout);
#endif

	/**
	 * This is used to help build wrapper functions in libraries
	 * around system calls that should behave as cancellation
	 * points but don't.
	 *
	 * @return saved cancel type.
	 */
	static Cancel enterCancel(void);

	/**
	 * This is used to restore a cancel block.	
	 *
	 * @param saved cancel type.
	 */
	static void exitCancel(Cancel cancel);
};

/**
 * A class to automatically set the thread cancellation mode of a
 * member function.  When the member function returns and the automatic
 * variable falls out of scope, the previous thread cancellation mode
 * is restored.
 *
 * @author David Sugar <dyfet@gnu.org>
 * @short Automatic cancellation mode setting.
 */
class __EXPORT Cancellation
{
private:
	Thread::Cancel prior;

public:
	Cancellation(Thread::Cancel cancel);
	~Cancellation();
};

#if !defined(WIN32) && !defined(__MINGW32__)
typedef	int		signo_t;

class PosixThread: public Thread
{
private:
#ifndef WIN32
	/** @internal */
	friend class ThreadImpl;
	friend class Thread;
#endif
#ifndef	CCXX_SIG_THREAD_ALARM
	static PosixThread *_timer;
	static Mutex _arm;
#endif
	
	time_t	_alarm;
	static void signalThread(Thread* th,signo_t signo);
protected:
		
	/**
	 * In the Posix version of Common C++, this can be used to send a
	 * signal into the parent thread of the current object.
	 * 
	 * @param signo a posix signal id.
	 */
	inline void signalParent(signo_t signo)
		{ signalThread(_parent,signo); };
	
	/**
	 * In the Posix version of Common C++, this can be used to send a
	 * signal into the main application thread.
	 * 
	 * @param signo a posix signal id.
	 */
	inline void signalMain(signo_t signo)
		{ signalThread(_main,signo);};

	/**
	 * A derivable method to call when a SIGALRM is being delivered
	 * to a specific thread.
	 */
	virtual void onTimer(void);

	/**
	 * A derived method to handle hangup events being delivered
	 * to a specific thread.
	 */
	virtual void onHangup(void);

	/**
	 * A derived method to call when a SIGABRT is being delivered
	 * to a specific thread.
	 */
	virtual void onException(void);

	/**
	 * A derived method to call when a SIGPIPE is being delivered
	 * to a specific thread.
	 */
	virtual void onDisconnect(void);

	/**
	 * A derived method to handle asynchronous I/O requests delivered
	 * to the specified thread.
	 */
	virtual void onPolling(void);

	/**
	 * A derivable method to call for delivering a signal event to
	 * a specified thread.
	 *
	 * @param - posix signal id.
	 */
	virtual void onSignal(int);
	
	/**
	 * Used to specify a timeout event that can be delivered to the
	 * current thread via SIGALRM.  When the timer expires, the onTimer() 
	 * method is called for the thread.  At present, only one thread
	 * timer can be active at any given time.  On some operating
	 * systems (including Linux) a timer can be active on each thread.
	 * 
	 * @param timer timeout in milliseconds.
	 * @param periodic should the timer be periodic.
	 * @note currently, periodic timers are only available on
	 * systems with a working setitimer call.
	 */
	void setTimer(timeout_t timer, bool periodic = false);
	
	/**
	 * Gets the time remaining for the current threads timer before
	 * it expires.
	 * 
	 * @return time remaining before timer expires in milliseconds.
	 */
	timeout_t getTimer(void) const;
	
	/**
	 * Terminates the timer before the timeout period has expired.
	 * This prevents the timer from sending it's SIGALRM and makes
	 * the timer available to other threads.
	 */
	void endTimer(void);

#if defined(HAVE_SIGWAIT) || defined(HAVE_SIGWAIT2)	
	/**
	 * Used to wait on a Posix signal from another thread.  This can be
	 * used as a crude rondevious/synchronization method between threads.
	 * 
	 * @param signo a posix signal id.
	 */
	void waitSignal(signo_t signo);
#endif
	
	/**
	 * Used to enable or disable a signal within the current thread.
	 *
	 * @param signo posix signal id.
	 * @param active set to true to enable.
	 */
	void setSignal(int signo, bool active);

	/**
 	 * Access to pthread_attr structure
 	 *  this allows setting/modifying pthread attributes
 	 *  not covered in the platform independant Thread constructor,
 	 *  e.g. contention scope or scheduling policy
 	 */
	pthread_attr_t *getPthreadAttrPtr(void);

	/**
 	 * Get pthread_t of underlying posix thread (useful for 
	 * debugging/logging)
  	 */
	pthread_t getPthreadId(void);

public:

	PosixThread(int pri = 0, size_t stack = 0);
	
	/**
	 * Delivers a Posix signal to the current thread.
	 * 
	 * @param signo a posix signal id.
	 */
	inline void signalThread(int signo)
		{signalThread(this, signo);};

	/**
	 * Install a signal handler for use by threads and
	 * the OnSignal() event notification handler.
	 *
	 * @param signo posix signal id.
	 */
	static void sigInstall(int signo);
};
#endif

/**
 * This class allows the creation of a thread context unique "pointer"
 * that can be set and retrieved and can be used to create thread specific
 * data areas for implementing "thread safe" library routines.
 * 
 *  Finally, Common C++ supports a
 * thread-safe "AtomicCounter" class.  This can often be used for reference
 * counting without having to protect the counter with a separate Mutex
 * counter.  This lends to lighter-weight code.
 * 
 * 
 * @author David Sugar <dyfet@ostel.com>
 * @short container for thread specific data storage.
 */
class __EXPORT ThreadKey
{
private:
#ifndef WIN32
	pthread_key_t key;
	typedef void (*TDestruct)(void*);
	friend class ThreadImpl;
	ThreadKey(TDestruct destruct);
#else
	DWORD	key;
#endif

public:
	/**
	 * Create a unique thread specific container.
	 */
	ThreadKey();

	/**
	 * Destroy a thread specific container and any contents reserved.
	 */
	virtual ~ThreadKey();

	/**
	 * Get the value of the pointer for the thread specific data
	 * container.  A unique pointer can be set for each execution
	 * context.
	 * 
	 * @return a unique void * for each execution context.
	 */
	void *getKey(void);

	/**
	 * Set the value of the pointer for the current thread specific
	 * execution context.  This can be used to store thread context
	 * specific data.
	 * 
	 * @param - ptr to thread context specific data.
	 */
	void setKey(void *);
};

/**
 * Timer ports are used to provide synchronized timing events when managed
 * under a "service thread" such as SocketService.  This is made into a
 * stand-alone base class since other derived libraries (such as the
 * serial handlers) may also use the pooled "service thread" model
 * and hence also require this code for managing timing.
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short synchronized millisecond timing for service threads.
 */
class __EXPORT TimerPort
{
#ifndef WIN32
	struct timeval timer;
#else
	DWORD timer;
#endif
	bool active;

public:
	/**
	 * Create a timer, mark it as inactive, and set the initial
	 * "start" time to the creation time of the timer object.  This
	 * allows "incTimer" to initially refer to time delays relative
	 * to the original start time of the object.
	 */
	TimerPort();

	/**
	 * Set a new start time for the object based on when this call is
	 * made and optionally activate the timer for a specified number
	 * of milliseconds.  This can be used to set the starting time
	 * of a realtime session.
	 *
	 * @param timeout delay in milliseconds from "now"
	 */
	void setTimer(timeout_t timeout = 0);

	/**
	 * Set a timeout based on the current time reference value either
	 * from object creation or the last setTimer().  This reference
	 * can be used to time synchronize realtime data over specified
	 * intervals and force expiration when a new frame should be
	 * released in a synchronized manner.  
	 *
	 * @param timeout delay in milliseconds from reference.
	 */
	void incTimer(timeout_t timeout);

	/**
	 * This is used to "disable" the service thread from expiring
	 * the timer object.  It does not effect the reference time from
	 * either creation or a setTimer().
	 */
	void endTimer(void);

	/**
	 * This is used by service threads to determine how much time
	 * remains before the timer expires based on a timeout specified
	 * in setTimer() or incTimer().  It can also be called after
	 * setting a timeout with incTimer() to see if the current timeout
	 * has already expired and hence that the application is already
	 * delayed and should skip frame(s).
	 *
	 * return time remaining in milliseconds, or TIMEOUT_INF if
	 * inactive.
	 */
	timeout_t getTimer(void) const;

	/**
	 * This is used to determine how much time has elapsed since a
	 * timer port setTimer benchmark time was initially set.  This
	 * allows one to use setTimer() to set the timer to the current
	 * time and then measure elapsed time from that point forward.
	 *
	 * return time elapsed in milliseconds, or TIMEOUT_INF if
	 * inactive.
	 */
	timeout_t getElapsed(void) const;
};



// FIXME: not in win32 implementation
#if !defined(WIN32)

// FIXME: private declaration ???
struct	timespec *getTimeout(struct timespec *spec, timeout_t timeout);	

#if !defined(__CYGWIN32__) && !defined(__MINGW32__)
void	wait(signo_t signo);
#endif

#endif // !WIN32

#ifdef USE_POLL

/**
 * The poller class is used to help manage pollfd structs for use in the
 * updated serial and socket "port" code.
 *
 * @author Gianni Mariani <gianni@mariani.ws>
 * @short pollfd assistance class for port classes.
 */
class Poller 
{
private:
	int nufds;
	pollfd *ufds;

public:
	Poller();

	virtual ~Poller();

	/**
	 * reserve a specified number of poll descriptors.  If additional
	 * descriptors are needed, they are allocated.
	 *
	 * @return new array of descriptors.
	 * @param cnt number of desctiptors to reserve
	 */
	pollfd *getList(int cnt);

	/**
	 * Retreive the current array of poll descriptors.
	 *
	 * @return array of descriptors.
	 */
	inline	pollfd *getList(void)
		{return ufds;};
};
#endif

inline Thread *getThread(void)
	{return Thread::get();}

/**
 * This class is used to access non-reentrant date and time functions in the
 * standard C library.
 *
 * The class has two purposes:
 * - 1 To be used internaly in CommonCpp's date and time classes to make them
 *     thread safe.
 * - 2 To be used by clients as thread safe replacements to the standard C
 *     functions, much like Thread::sleep() represents a thread safe version
 *     of the standard sleep() function.
 *
 * @note The class provides one function with the same name as its equivalent
 *       standard function and one with another, unique name. For new clients,
 *       the version with the unique name is recommended to make it easy to
 *       grep for accidental usage of the standard functions. The version with
 *       the standard name is provided for existing clients to sed replace their
 *       original version.
 *
 * @note Also note that some functions that returned pointers have been redone
 *       to take that pointer as an argument instead, making the caller
 *       responsible for memory allocation/deallocation. This is almost
 *       how POSIX specifies *_r functions (reentrant versions of the
 *       standard time functions), except the POSIX functions also return the
 *       given pointer while we do not. We don't use the *_r functions as they
 *       aren't all generally available on all platforms yet.
 *
 * @author Idar Tollefsen <idar@cognita.no>
 * @short Thread safe date and time functions.
 */
class __EXPORT SysTime
{
private:
		static Mutex timeLock;

protected:
		inline static void lock(void)
			{timeLock.enterMutex();}

		inline static void unlock(void)
			{timeLock.leaveMutex();}

public:
        static time_t getTime(time_t *tloc = NULL);
        static time_t time(time_t *tloc) 
			{ return getTime(tloc); };

        static int getTimeOfDay(struct timeval *tp);
        static int gettimeofday(struct timeval *tp, struct timezone *)
			{ return getTimeOfDay(tp); };
        
        static struct tm *getLocalTime(const time_t *clock, struct tm *result);
        static struct tm *locatime(const time_t *clock, struct tm *result)
			{ return getLocalTime(clock, result); };

		static struct tm *getGMTTime(const time_t *clock, struct tm *result);
		static struct tm *gmtime(const time_t *clock, struct tm *result)
			{ return getGMTTime(clock, result);};
}; 

#ifndef	HAVE_LOCALTIME_R

inline struct tm *localtime_r(const time_t *t, struct tm *b)
	{return SysTime::getLocalTime(t, b);};
inline char *ctime_r(const time_t *t, char *buf)
	{return ctime(t);};
inline struct tm *gmtime_r(const time_t *t, struct tm *b) \
{return SysTime::getGMTTime(t, b);};
inline char *asctime_r(const struct tm *tm, char *b) \
	{return asctime(tm);};

#endif 
	
#ifdef	CCXX_NAMESPACES
}
#endif

#endif
/** EMACS **
 * Local variables:
 * mode: c++
 * c-basic-offset: 8
 * End:
 */
