Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

thread.h

Go to the documentation of this file.
00001 // Copyright (C) 1999-2001 Open Source Telecom Corporation.
00002 //  
00003 // This program is free software; you can redistribute it and/or modify
00004 // it under the terms of the GNU General Public License as published by
00005 // the Free Software Foundation; either version 2 of the License, or
00006 // (at your option) any later version.
00007 // 
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 // 
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software 
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00016 // 
00017 // As a special exception to the GNU General Public License, permission is 
00018 // granted for additional uses of the text contained in its release 
00019 // of Common C++.
00020 // 
00021 // The exception is that, if you link the Common C++ library with other
00022 // files to produce an executable, this does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public License.
00024 // Your use of that executable is in no way restricted on account of
00025 // linking the Common C++ library code into it.
00026 //
00027 // This exception does not however invalidate any other reasons why
00028 // the executable file might be covered by the GNU General Public License.
00029 // 
00030 // This exception applies only to the code released under the 
00031 // name Common C++.  If you copy code from other releases into a copy of
00032 // Common C++, as the General Public License permits, the exception does
00033 // not apply to the code that you add in this way.  To avoid misleading
00034 // anyone as to the status of such modified files, you must delete
00035 // this exception notice from them.
00036 // 
00037 // If you write modifications of your own for Common C++, it is your choice
00038 // whether to permit this exception to apply to your modifications.
00039 // If you do not wish that, delete this exception notice.  
00040 
00041 #ifndef __CCXX_THREAD_H__
00042 #define __CCXX_THREAD_H__
00043 
00044 #ifndef WIN32
00045 #define __CCXX_POSIX
00046 
00047 #ifndef _REENTRANT
00048 #define _REENTRANT
00049 #endif
00050 
00051 #ifndef _THREAD_SAFE
00052 #define _THREAD_SAFE
00053 #endif
00054 #else // WIN32
00055 #include <setjmp.h>
00056 #endif // !WIN32
00057 
00058 #ifndef __CCXX_CONFIG_H__
00059 #include <cc++/config.h>
00060 #endif
00061 
00062 #ifndef __CCXX_EXCEPTION_H__
00063 #include <cc++/exception.h>
00064 #endif
00065 
00066 #ifndef WIN32
00067 #if defined(__FreeBSD__) && __FreeBSD__ <= 3
00068 #define _SYSV_SEMAPHORES
00069 #endif
00070 
00071 #ifndef HAVE_PTHREAD_H
00072 #include <pthread.h>
00073 #ifndef _SYSV_SEMAPHORES
00074 #include <semaphore.h>
00075 #endif
00076 #endif
00077 #endif // !WIN32
00078 
00079 #if _MSC_VER > 1000
00080 #pragma once
00081 #endif
00082 
00083 #ifndef WIN32
00084 #include <time.h>
00085 #include <signal.h>
00086 #include <setjmp.h>
00087 #include <unistd.h>
00088 
00089 #ifdef  __linux__
00090 #define _SIG_THREAD_ALARM
00091 #endif
00092 
00093 #ifdef  _THR_UNIXWARE
00094 #undef  PTHREAD_MUTEXTYPE_RECURSIVE
00095 #endif
00096 
00097 typedef pthread_t       cctid_t;
00098 typedef unsigned long   timeout_t;
00099 #else // WIN32
00100 typedef DWORD   cctid_t;
00101 typedef DWORD   timeout_t;
00102 
00103 #define MAX_SEM_VALUE   1000000
00104 #if defined(__MINGW32__) || defined(__CYGWIN32__)
00105 #include <Windows32/CommonFunctions.h>
00106 #else
00107 __declspec(dllimport) long __stdcall InterlockedIncrement(long *);
00108 __declspec(dllimport) long __stdcall InterlockedDecrement(long *);
00109 __declspec(dllimport) long __stdcall InterlockedExchange(long *, long);
00110 #endif
00111 
00112 #endif // !WIN32
00113 
00114 #ifdef  __NAMESPACES__
00115 namespace ost {
00116 #endif
00117 
00118 enum throw_t {
00119         THROW_NOTHING, 
00120         THROW_OBJECT, 
00121         THROW_EXCEPTION
00122 };
00123 typedef enum throw_t throw_t;
00124 class Thread;
00125 
00126 #define TIMEOUT_INF ~((timeout_t) 0)
00127 
00128 #define ENTER_CRITICAL  EnterMutex();
00129 #define LEAVE_CRITICAL  LeaveMutex();
00130 #define ENTER_DEFERRED  setCancel(THREAD_CANCEL_DEFERRED);
00131 #define LEAVE_DEFERRED  setCancel(THREAD_CANCEL_IMMEDIATE);
00132 
00133 enum thread_cancel_t
00134 {
00135         THREAD_CANCEL_INITIAL=0,
00136         THREAD_CANCEL_DEFERRED=1,
00137         THREAD_CANCEL_IMMEDIATE,
00138         THREAD_CANCEL_DISABLED,
00139         THREAD_CANCEL_DEFAULT=THREAD_CANCEL_DEFERRED
00140 };
00141 typedef enum thread_cancel_t thread_cancel_t;
00142 
00143 enum thread_suspend_t
00144 {
00145         THREAD_SUSPEND_ENABLE,
00146         THREAD_SUSPEND_DISABLE
00147 };
00148 typedef enum thread_suspend_t thread_suspend_t;
00149 
00150 #ifndef WIN32
00151 // These macros override common functions with thread-safe versions. In
00152 // particular the common "libc" sleep() has problems since it normally
00153 // uses SIGARLM (as actually defined by "posix").  The pthread_delay and
00154 // usleep found in libpthread are gaurenteed not to use SIGALRM and offer
00155 // higher resolution.  psleep() is defined to call the old process sleep.
00156 
00157 #undef  sleep
00158 #define psleep(x)       (sleep)(x)
00159 
00160 static RETSIGTYPE ccxx_sigsuspend(int);
00161 extern "C" void execHandler(Thread *th);
00162 
00163 #endif // !WIN32
00164 
00165 
00166 CCXX_EXPORT(Thread*) getThread(void);
00167 CCXX_EXPORT(throw_t) getException(void);
00168 CCXX_EXPORT(void) setException(throw_t mode);
00169 CCXX_EXPORT(void) ccxx_sleep(timeout_t msec);
00170 CCXX_EXPORT(void) ccxx_yield(void);
00171 
00172 #undef Yield
00173 #define sleep(x)        ccxx_sleep((x) * 1000)
00174 #define yield()         ccxx_yield()
00175 
00176 #ifdef WIN32
00177 CCXX_EXPORT(DWORD) waitThread(HANDLE hRef, timeout_t timeout);
00178 #endif
00179 
00180 class Conditional;
00181 class CCXX_CLASS_EXPORT Event;
00182 
00226 class CCXX_CLASS_EXPORT Mutex
00227 {
00228         friend class Conditional;
00229         friend class Event;
00230 private:
00231 #ifndef WIN32
00232 #ifndef PTHREAD_MUTEXTYPE_RECURSIVE
00233         volatile int _level;
00234         volatile Thread *_tid;
00235 #endif
00236 
00244         pthread_mutex_t _mutex;
00245 #else
00246         HANDLE mutex;
00247 #endif
00248 
00249 public:
00253         Mutex();
00254 
00260         virtual ~Mutex();
00261 
00269         void EnterMutex(void);
00270 
00281         bool TryEnterMutex(void);
00282 
00293         void LeaveMutex(void);
00294 };
00295 
00317 class MutexLock
00318 {
00319 private:
00320         Mutex& mutex;
00321 public:
00325         MutexLock( Mutex& _mutex ) : mutex( _mutex ) 
00326                 { mutex.EnterMutex(); }
00330         // this should be not-virtual
00331         ~MutexLock()
00332                 { mutex.LeaveMutex(); }
00333 };
00334 
00343 class CCXX_CLASS_EXPORT ThreadLock
00344 {
00345 private:
00346 #ifdef HAVE_PTHREAD_RWLOCK
00347         pthread_rwlock_t _lock;
00348 #else
00349         Mutex mutex;
00350 #endif
00351 
00352 public:
00356         ThreadLock();
00357 
00361         virtual ~ThreadLock();
00362 
00366         void ReadLock(void);
00367 
00371         void WriteLock(void);
00372 
00378         bool TryReadLock(void);
00379 
00385         bool TryWriteLock(void);
00386 
00390         void Unlock(void);
00391 };
00392 
00402 class CCXX_CLASS_EXPORT MutexCounter : public Mutex
00403 {
00404 private:
00405         int     counter;
00406 
00407 public:
00408         MutexCounter();
00409         MutexCounter(int initial);
00410 
00411         friend CCXX_EXPORT(int) operator++(MutexCounter &mc);
00412         friend CCXX_EXPORT(int) operator--(MutexCounter &mc);
00413 };
00414 
00425 class CCXX_CLASS_EXPORT AtomicCounter
00426 {
00427 #ifndef WIN32
00428 private:
00429 #ifdef  HAVE_ATOMIC
00430         atomic_t atomic;
00431 #else
00432         int counter;
00433         Mutex lock;
00434 #endif
00435 
00436 public:
00440         AtomicCounter();
00441 
00447         AtomicCounter(int value);
00448 
00449         int operator++(void);
00450         int operator--(void);
00451         int operator+=(int change);
00452         int operator-=(int change);
00453         int operator+(int change);
00454         int operator-(int change);
00455         int operator=(int value);
00456         bool operator!(void);
00457         operator int();
00458 #else
00459 private:
00460         long atomic;
00461 
00462 public:
00463         inline AtomicCounter()
00464                 {atomic = 0;};
00465 
00466         inline AtomicCounter(int value)
00467                 {atomic = value;};
00468 
00469         inline int operator++(void)
00470                 {return InterlockedIncrement(&atomic);};
00471 
00472         inline int operator--(void)
00473                 {return InterlockedDecrement(&atomic);};
00474 
00475         int operator+=(int change);
00476 
00477         int operator-=(int change);
00478 
00479         inline int operator+(int change)
00480                 {return atomic + change;};
00481 
00482         inline int operator-(int change)
00483                 {return atomic - change;};
00484         
00485         inline int operator=(int value)
00486                 {return InterlockedExchange(&atomic, value);};
00487 
00488         inline bool operator!(void)
00489                 {return (atomic == 0) ? true : false;};
00490 
00491         inline operator int()
00492                 {return atomic;};
00493 #endif
00494 };
00495 
00496 // FIXME: implement Conditional class for win32
00497 #ifndef WIN32
00498 
00508 class Conditional : public Mutex
00509 {
00510 private:
00511         pthread_cond_t _cond;
00512 
00513 public:
00517         Conditional();
00518 
00522         virtual ~Conditional();
00523 
00529         void Signal(bool broadcast);
00530 
00534         void Wait(timeout_t timer = 0); 
00535 };
00536 #endif
00537 
00555 class CCXX_CLASS_EXPORT Semaphore
00556 {
00557 private:
00558 #ifndef WIN32
00559 #ifdef  _SYSV_SEMAPHORES
00560         int _semaphore;
00561 #else
00562         sem_t _semaphore;
00563 #endif
00564 #else // WIN32
00565         HANDLE  semObject;
00566 #endif // !WIN32
00567 
00568 public:
00577         Semaphore(size_t resource = 0);
00578 
00585         virtual ~Semaphore();
00586 
00600         void Wait(void);
00601 
00613         bool TryWait(void);
00614 
00626         void Post(void);
00627 
00628         // FIXME: how implement getValue for posix compatibility ?
00634 #ifndef WIN32
00635 #ifndef __CYGWIN32__
00636         int getValue(void);
00637 #endif
00638 #endif
00639 };
00640 
00654 class CCXX_CLASS_EXPORT Event
00655 {
00656 private:
00657 #ifndef WIN32
00658         Mutex mutex;
00659         pthread_cond_t _cond;
00660         bool _signaled;
00661         int _count;
00662 #else
00663         HANDLE cond;
00664 #endif
00665 
00666 public:
00667         Event();
00668 
00669         virtual ~Event();
00670 
00677         void Reset(void);
00678 
00682         void Signal(void);
00683 
00692         bool Wait(timeout_t timer);
00693         bool Wait(void);
00694 };
00695 
00717 class CCXX_CLASS_EXPORT Buffer
00718 {
00719 private:
00720         Mutex lock_head, lock_tail;
00721         Semaphore size_head, size_tail;
00722         size_t _size;
00723         size_t _used;
00724 
00725 protected:
00731         virtual int OnPeek(void *buf) = 0;
00737         virtual int OnWait(void *buf) = 0;
00743         virtual int OnPost(void *buf) = 0;
00744 
00745 public:
00750         Buffer(size_t capacity);
00755         virtual ~Buffer()
00756                 {return;};
00757 
00762         inline size_t getSize(void)
00763                 {return _size;};
00764         
00771         inline size_t getUsed(void)
00772                 {return _used;};
00773 
00782         int Wait(void *buf);
00783 
00791         int Post(void *buf);
00792 
00799         int Peek(void *buf);
00800 
00805         virtual bool isValid(void)
00806                 {return true;};
00807 };
00808 
00816 class CCXX_CLASS_EXPORT FixedBuffer : public Buffer
00817 {
00818 private:
00819         char *buf, *head, *tail;
00820         size_t objsize;
00821 
00822 protected:
00828         int OnPeek(void *buf);
00829 
00835         int OnWait(void *buf);
00836 
00842         int OnPost(void *buf);  
00843 
00844 public:
00852         FixedBuffer(size_t capacity, size_t objsize);
00853 
00860         FixedBuffer(const FixedBuffer &fb);
00861 
00865         virtual ~FixedBuffer();
00866 
00867         FixedBuffer &operator=(const FixedBuffer &fb);
00868 
00869         bool isValid(void);
00870 };
00871 
01019 class Thread
01020 {
01021 #ifndef WIN32
01022 friend class PosixThread;
01023 friend RETSIGTYPE ccxx_sigsuspend(int);
01024 #endif
01025 private:
01026         friend class Slog;
01027 
01028         static Thread *_main;
01029 
01030         Thread *_parent;
01031 #ifndef WIN32
01032         pthread_t _tid;
01033         pthread_attr_t _attr;
01034         AtomicCounter _suspendcount;
01035 #else
01036         DWORD _tid;
01037         HANDLE _cancellation;
01038 #endif
01039         thread_cancel_t _cancel;
01040         jmp_buf _env;
01041         Semaphore *_start;
01042         int _msgpos;
01043         char _msgbuf[128];
01044         throw_t _throw;
01045 
01046 #ifndef WIN32
01047         friend void execHandler(Thread *th);
01048         friend Thread *getThread(void);
01049 #else
01050         bool _active:1;
01051         bool _suspendEnable:1;
01052         static unsigned __stdcall Execute(Thread *th);
01053         HANDLE  _hThread;
01054 #endif
01055 
01056 protected:
01066         virtual void Run(void) = 0;
01067 
01080         CCXX_MEMBER_EXPORT(virtual void) Final(void)
01081                 {return;};
01082 
01093         CCXX_MEMBER_EXPORT(virtual void) Initial(void)
01094                 {return;};
01095 
01105         CCXX_MEMBER_EXPORT(virtual void*) getExtended(void)
01106                 {return NULL;};
01107 
01115         CCXX_MEMBER_EXPORT(virtual void) Notify(Thread *th)
01116                 {return;};
01117 
01127         CCXX_MEMBER_EXPORT(void) Sleep(timeout_t msec)
01128 #ifndef WIN32
01129                 {ccxx_sleep(msec);}
01130 #endif
01131         ;
01132 
01138         inline void Exit(void)
01139                 {longjmp(_env, 1);};
01140 
01145         CCXX_MEMBER_EXPORT(void) Yield(void);
01146 
01150         CCXX_MEMBER_EXPORT(void) testCancel(void);
01151 
01160         CCXX_MEMBER_EXPORT(void) setCancel(thread_cancel_t mode);
01161 
01169         CCXX_MEMBER_EXPORT(void) setSuspend(thread_suspend_t mode);
01170 
01179         CCXX_MEMBER_EXPORT(void) Terminate(void);
01180 
01184         inline void clrParent(void)
01185                 {_parent = NULL;};
01186 
01187 #ifdef WIN32
01188         // FIXME: should be private
01189         CCXX_MEMBER_EXPORT(DWORD) WaitHandle(HANDLE obj, timeout_t timeout);
01190 #endif
01191 
01192 public:
01201         CCXX_MEMBER_EXPORT(CCXX_EMPTY) Thread(bool isMain);
01202 
01215         CCXX_MEMBER_EXPORT(CCXX_EMPTY) Thread(int pri = 0, size_t stack = 0);
01216 
01217         // FIXME: win32 lack copy constructor
01218 #ifndef WIN32
01219 
01226         Thread(const Thread &th);
01227 #endif
01228 
01235         CCXX_MEMBER_EXPORT(virtual) ~Thread()
01236                 {Terminate();};
01237 
01250         CCXX_MEMBER_EXPORT(int) Start(Semaphore *start = 0);
01251 
01260         CCXX_MEMBER_EXPORT(int) Detach(Semaphore *start = 0);
01261 
01268         inline Thread *getParent(void)
01269                 {return _parent;};
01270 
01277         CCXX_MEMBER_EXPORT(void) Suspend(void);
01278 
01282         CCXX_MEMBER_EXPORT(void) Resume(void);
01283 
01290         inline thread_cancel_t getCancel(void)
01291                 {return _cancel;};
01292 
01299         bool isRunning(void)
01300 #ifdef WIN32
01301                 {return (_tid != 0) ? true : false;}
01302 #endif
01303         ;
01304 
01311         bool isThread(void)
01312 #ifdef WIN32
01313                 {return ((_tid == GetCurrentThreadId())) ? true : false;}
01314 #endif
01315         ;
01316 
01322         friend CCXX_EXPORT(throw_t) getException(void);
01323 
01329         friend CCXX_EXPORT(void) setException(throw_t mode);
01330 
01334         friend inline int start(Thread &th, Semaphore *start = 0)
01335                 {return th.Start(start);};
01336 
01343         friend inline void operator++(Thread &th)
01344                 {th._start->Post();};
01345 
01346         friend inline void operator--(Thread &th)
01347                 {th._start->Wait();};
01348 
01354         friend CCXX_EXPORT(void) ccxx_sleep(timeout_t msec);
01355 
01356 #ifdef WIN32
01357         // FIXME: not defined in posix
01358         inline bool isCancelled(void)
01359                 {return waitThread(_cancellation, 0) == WAIT_OBJECT_0; };
01360 
01361         inline bool isCancelled(timeout_t timer)
01362                 {return waitThread(_cancellation, timer) == WAIT_OBJECT_0; };
01363                 
01364         friend CCXX_EXPORT(DWORD) waitThread(HANDLE hRef, timeout_t timeout);
01365         friend CCXX_EXPORT(void) ccxx_yield(void);
01366 #endif
01367 };
01368 
01374 inline void suspend(Thread &th)
01375 { th.Suspend(); }
01376 
01382 inline void resume(Thread &th)
01383 { th.Resume(); }
01384 
01385 #ifndef WIN32
01386 extern "C" void sigHandler(int signo);
01387 
01388 typedef int             signo_t;
01389 
01390 class PosixThread: public Thread
01391 {
01392 private:
01393 #ifndef WIN32
01394         friend void execHandler(Thread *th);
01395 #endif
01396 #ifndef _SIG_THREAD_ALARM
01397         static PosixThread *_timer;
01398         static Mutex _arm;
01399 #endif
01400         
01401         time_t  _alarm;
01402         friend void sigHandler(int signo);
01403         inline static void SignalThread(Thread* th,signo_t signo)
01404                 {pthread_kill(th->_tid, signo);};
01405 protected:
01406                 
01413         inline void SignalParent(signo_t signo)
01414                 { SignalThread(_parent,signo); };
01415         
01422         inline void SignalMain(signo_t signo)
01423                 { SignalThread(_main,signo);};
01424 
01429         virtual void OnTimer(void)
01430                 {return;};
01431 
01436         virtual void OnHangup(void)
01437                 {return;};
01438 
01443         virtual void OnException(void)
01444                 {return;};
01445 
01450         virtual void OnDisconnect(void)
01451                 {return;};
01452 
01457         virtual void OnPolling(void)
01458                 {return;};
01459 
01466         virtual void OnSignal(int signo)
01467                 {return;};
01468         
01478         void setTimer(timeout_t timer);
01479         
01486         timeout_t getTimer(void);
01487         
01493         void endTimer(void);
01494         
01501         void WaitSignal(signo_t signo);
01502         
01509         void setSignal(int signo, bool mode);
01510 public:
01511         
01517         inline void SignalThread(int signo)
01518                 {SignalThread(this, signo);};
01519 
01526         friend void siginstall(int signo);
01527 };
01528 inline void signal(PosixThread &th, int signo)
01529         {th.SignalThread(signo);};
01530 #endif
01531 
01546 class CCXX_CLASS_EXPORT ThreadKey
01547 {
01548 private:
01549 #ifndef WIN32
01550         pthread_key_t key;
01551 #else
01552         DWORD   key;
01553 #endif
01554 
01555 public:
01559         ThreadKey();
01563         virtual ~ThreadKey();
01571         void *getKey(void);
01579         void setKey(void *);
01580 };
01581 
01592 class CCXX_CLASS_EXPORT TimerPort
01593 {
01594 #ifndef WIN32
01595         struct timeval timer;
01596 #else
01597         DWORD timer;
01598 #endif
01599         bool active;
01600 
01601 public:
01608         TimerPort();
01609 
01618         void setTimer(timeout_t timeout = 0);
01619 
01629         void incTimer(timeout_t timeout);
01630 
01636         void endTimer(void);
01637 
01648         timeout_t getTimer(void);
01649 
01658         timeout_t getElapsed(void);
01659 };
01660 
01661 /*
01662  * on some systems, signal(signum, handler) is a macro
01663  */
01664 #undef signal
01665 
01666 inline void *getKey(ThreadKey &tk)
01667         {return tk.getKey();};
01668 
01669 inline void setKey(ThreadKey &tk, void *ptr)
01670         {tk.setKey(ptr);};
01671 
01672 inline void operator++(Mutex &m)
01673         {m.EnterMutex();};
01674                 
01675 inline void operator--(Mutex &m)
01676         {m.LeaveMutex();};
01677 
01678 inline void operator++(Semaphore &s)
01679         {s.Post();};
01680 
01681 inline void operator--(Semaphore &s)
01682         {s.Wait();};
01683 
01684 inline void operator ++(Event &s)
01685         {s.Signal();};
01686 
01687 inline void operator --(Event &s)
01688         {s.Wait();};
01689 
01690 inline void signal(Event &ev)
01691         {ev.Signal();};
01692 
01693 inline void wait(Event &ev)
01694         {ev.Wait();};
01695 
01696 inline void wait(Event &ev, timeout_t timer)
01697         {ev.Wait(timer);};
01698 
01699 inline void reset(Event &ev)
01700         {ev.Reset();};
01701 
01702 inline void signal(Semaphore &sem)
01703         {sem.Post();};
01704 
01705 inline void wait(Semaphore &sem)
01706         {sem.Wait();};
01707 
01708 inline int get(Buffer &b, void *o)
01709         {return b.Wait(o);};
01710 
01711 inline int put(Buffer &b, void *o)
01712         {return b.Post(o);};
01713 
01714 inline int peek(Buffer &b, void *o)
01715         {return b.Peek(o);};
01716 
01717 
01718 // FIXME: not in win32 implementation
01719 #ifndef WIN32
01720 
01721 struct  timespec *gettimeout(struct timespec *spec, timeout_t timeout); 
01722 void    wait(signo_t signo);
01731 void    pdetach(void);
01732 #endif // !WIN32
01733 
01734 // FIXME: no way to implement in win32
01735 #ifndef WIN32
01736 #if defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H)
01737 #if defined(HAVE_SYS_STREAM_H)
01738 #if defined(__linux__)
01739 #define __CCXX_USE_POLL 1
01740 #endif
01741 #else
01742 #define __CCXX_USE_POLL 1
01743 #endif
01744 #endif
01745 
01746 #ifdef __CCXX_USE_POLL
01747 
01755 class Poller 
01756 {
01757 private:
01758         int nufds;
01759         pollfd *ufds;
01760 
01761 public:
01762         Poller();
01763 
01764         virtual ~Poller();
01765 
01773         pollfd *getList(int cnt);
01774 
01780         inline  pollfd *getList(void)
01781                 {return ufds;};
01782 };
01783 #endif
01784 #endif // !WIN32
01785 
01786 #ifdef  COMMON_STD_EXCEPTION
01787 
01793 class ThrException : public Exception
01794 {
01795 public:
01796         ThrException(const std::string &what_arg) : Exception(what_arg) {};
01797 };
01798 
01805 class SyncException : public ThrException
01806 {
01807 public:
01808         SyncException(const std::string &what_arg) : ThrException(what_arg) {};
01809 };
01810 #endif
01811 
01812 #ifdef  __NAMESPACES__
01813 };
01814 #endif
01815 
01816 #endif
01817 

Generated at Tue Nov 20 12:34:33 2001 for CommonC++ by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001