XrdSysPthread.hh

Go to the documentation of this file.
00001 #ifndef __SYS_PTHREAD__
00002 #define __SYS_PTHREAD__
00003 /******************************************************************************/
00004 /*                                                                            */
00005 /*                      X r d S y s P t h r e a d . h h                       */
00006 /*                                                                            */
00007 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University  */
00008 /*       All Rights Reserved. See XrdInfo.cc for complete License Terms       */
00009 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00010 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00011 /******************************************************************************/
00012   
00013 //        $Id: XrdSysPthread.hh 32231 2010-02-05 18:24:46Z ganis $
00014 
00015 #include <errno.h>
00016 #ifdef WIN32
00017 #define HAVE_STRUCT_TIMESPEC 1
00018 #endif
00019 #include <pthread.h>
00020 #include <signal.h>
00021 #ifdef AIX
00022 #include <sys/sem.h>
00023 #else
00024 #include <semaphore.h>
00025 #endif
00026 
00027 #include "XrdSys/XrdSysError.hh"
00028 
00029 /******************************************************************************/
00030 /*                         X r d S y s C o n d V a r                          */
00031 /******************************************************************************/
00032   
00033 // XrdSysCondVar implements the standard POSIX-compliant condition variable.
00034 //               Methods correspond to the equivalent pthread condvar functions.
00035 
00036 class XrdSysCondVar
00037 {
00038 public:
00039 
00040 inline void  Lock()           {pthread_mutex_lock(&cmut);}
00041 
00042 inline void  Signal()         {if (relMutex) pthread_mutex_lock(&cmut);
00043                                pthread_cond_signal(&cvar);
00044                                if (relMutex) pthread_mutex_unlock(&cmut);
00045                               }
00046 
00047 inline void  Broadcast()      {if (relMutex) pthread_mutex_lock(&cmut);
00048                                pthread_cond_broadcast(&cvar);
00049                                if (relMutex) pthread_mutex_unlock(&cmut);
00050                               }
00051 
00052 inline void  UnLock()         {pthread_mutex_unlock(&cmut);}
00053 
00054        int   Wait();
00055        int   Wait(int sec);
00056        int   WaitMS(int msec);
00057 
00058       XrdSysCondVar(      int   relm=1, // 0->Caller will handle lock/unlock
00059                     const char *cid=0   // ID string for debugging only
00060                    ) {pthread_cond_init(&cvar, NULL);
00061                       pthread_mutex_init(&cmut, NULL);
00062                       relMutex = relm; condID = (cid ? cid : "unk");
00063                      }
00064      ~XrdSysCondVar() {pthread_cond_destroy(&cvar);
00065                        pthread_mutex_destroy(&cmut);
00066                       }
00067 private:
00068 
00069 pthread_cond_t  cvar;
00070 pthread_mutex_t cmut;
00071 int             relMutex;
00072 const char     *condID;
00073 };
00074 
00075 
00076 
00077 /******************************************************************************/
00078 /*                     X r d S y s C o n d V a r H e l p e r                  */
00079 /******************************************************************************/
00080 
00081 // XrdSysCondVarHelper is used to implement monitors with the Lock of a a condvar.
00082 //                     Monitors are used to lock
00083 //                     whole regions of code (e.g., a method) and automatically
00084 //                     unlock with exiting the region (e.g., return). The
00085 //                     methods should be self-evident.
00086   
00087 class XrdSysCondVarHelper
00088 {
00089 public:
00090 
00091 inline void   Lock(XrdSysCondVar *CndVar)
00092                   {if (cnd) {if (cnd != CndVar) cnd->UnLock();
00093                                 else return;
00094                             }
00095                    CndVar->Lock();
00096                    cnd = CndVar;
00097                   };
00098 
00099 inline void UnLock() {if (cnd) {cnd->UnLock(); cnd = 0;}}
00100 
00101             XrdSysCondVarHelper(XrdSysCondVar *CndVar=0)
00102                  {if (CndVar) CndVar->Lock();
00103                   cnd = CndVar;
00104                  }
00105             XrdSysCondVarHelper(XrdSysCondVar &CndVar) {
00106                  CndVar.Lock();
00107                  cnd = &CndVar;
00108                  }
00109 
00110            ~XrdSysCondVarHelper() {if (cnd) UnLock();}
00111 private:
00112 XrdSysCondVar *cnd;
00113 };
00114 
00115 
00116 /******************************************************************************/
00117 /*                           X r d S y s M u t e x                            */
00118 /******************************************************************************/
00119 
00120 // XrdSysMutex implements the standard POSIX mutex. The methods correspond
00121 //             to the equivalent pthread mutex functions.
00122   
00123 class XrdSysMutex
00124 {
00125 public:
00126 
00127 inline int CondLock()
00128        {if (pthread_mutex_trylock( &cs )) return 0;
00129         return 1;
00130        }
00131 
00132 inline void   Lock() {pthread_mutex_lock(&cs);}
00133 
00134 inline void UnLock() {pthread_mutex_unlock(&cs);}
00135 
00136         XrdSysMutex() {pthread_mutex_init(&cs, NULL);}
00137        ~XrdSysMutex() {pthread_mutex_destroy(&cs);}
00138 
00139 protected:
00140 
00141 pthread_mutex_t cs;
00142 };
00143 
00144 /******************************************************************************/
00145 /*                         X r d S y s R e c M u t e x                        */
00146 /******************************************************************************/
00147 
00148 // XrdSysRecMutex implements the recursive POSIX mutex. The methods correspond
00149 //             to the equivalent pthread mutex functions.
00150   
00151 class XrdSysRecMutex: public XrdSysMutex
00152 {
00153 public:
00154 
00155 XrdSysRecMutex();
00156 
00157 };
00158 
00159 
00160 /******************************************************************************/
00161 /*                     X r d S y s M u t e x H e l p e r                      */
00162 /******************************************************************************/
00163 
00164 // XrdSysMutexHelper us ised to implement monitors. Monitors are used to lock
00165 //                   whole regions of code (e.g., a method) and automatically
00166 //                   unlock with exiting the region (e.g., return). The
00167 //                   methods should be self-evident.
00168   
00169 class XrdSysMutexHelper
00170 {
00171 public:
00172 
00173 inline void   Lock(XrdSysMutex *Mutex)
00174                   {if (mtx) {if (mtx != Mutex) mtx->UnLock();
00175                                 else return;
00176                             }
00177                    Mutex->Lock();
00178                    mtx = Mutex;
00179                   };
00180 
00181 inline void UnLock() {if (mtx) {mtx->UnLock(); mtx = 0;}}
00182 
00183             XrdSysMutexHelper(XrdSysMutex *mutex=0)
00184                  {if (mutex) mutex->Lock();
00185                   mtx = mutex;
00186                  }
00187             XrdSysMutexHelper(XrdSysMutex &mutex) {
00188                  mutex.Lock();
00189                  mtx = &mutex;
00190                  }
00191 
00192            ~XrdSysMutexHelper() {if (mtx) UnLock();}
00193 private:
00194 XrdSysMutex *mtx;
00195 };
00196 
00197 /******************************************************************************/
00198 /*                       X r d S y s S e m a p h o r e                        */
00199 /******************************************************************************/
00200 
00201 // XrdSysSemaphore implements the classic counting semaphore. The methods
00202 //                 should be self-evident. Note that on certain platforms
00203 //                 semaphores need to be implemented based on condition
00204 //                 variables since no native implementation is available.
00205   
00206 #ifdef __macos__
00207 class XrdSysSemaphore
00208 {
00209 public:
00210 
00211        int  CondWait();
00212 
00213        void Post();
00214 
00215        void Wait();
00216 
00217   XrdSysSemaphore(int semval=1,const char *cid=0) : semVar(0, cid)
00218                                   {semVal = semval; semWait = 0;}
00219  ~XrdSysSemaphore() {}
00220 
00221 private:
00222 
00223 XrdSysCondVar semVar;
00224 int           semVal;
00225 int           semWait;
00226 };
00227 
00228 #else
00229 
00230 class XrdSysSemaphore
00231 {
00232 public:
00233 
00234 inline int  CondWait()
00235        {while(sem_trywait( &h_semaphore ))
00236              {if (errno == EAGAIN) return 0;
00237               if (errno != EINTR) { throw "sem_CondWait() failed";}
00238              }
00239         return 1;
00240        }
00241 
00242 inline void Post() {if (sem_post(&h_semaphore))
00243                        {throw "sem_post() failed";}
00244                    }
00245 
00246 inline void Wait() {while (sem_wait(&h_semaphore))
00247                           {if (EINTR != errno) 
00248                               {throw "sem_wait() failed";}
00249                           }
00250                    }
00251 
00252   XrdSysSemaphore(int semval=1, const char * =0)
00253                                {if (sem_init(&h_semaphore, 0, semval))
00254                                    {throw "sem_init() failed";}
00255                                }
00256  ~XrdSysSemaphore() {if (sem_destroy(&h_semaphore))
00257                        {throw "sem_destroy() failed";}
00258                    }
00259 
00260 private:
00261 
00262 sem_t h_semaphore;
00263 };
00264 #endif
00265 
00266 /******************************************************************************/
00267 /*                          X r d S y s T h r e a d                           */
00268 /******************************************************************************/
00269   
00270 // The C++ standard makes it impossible to link extern "C" methods with C++
00271 // methods. Thus, making a full thread object is nearly impossible. So, this
00272 // object is used as the thread manager. Since it is static for all intense
00273 // and purposes, one does not need to create an instance of it.
00274 //
00275 
00276 // Options to Run()
00277 //
00278 // BIND creates threads that are bound to a kernel thread.
00279 //
00280 #define XRDSYSTHREAD_BIND 0x001
00281 
00282 // HOLD creates a thread that needs to be joined to get its ending value.
00283 //      Otherwise, a detached thread is created.
00284 //
00285 #define XRDSYSTHREAD_HOLD 0x002
00286 
00287 class XrdSysThread
00288 {
00289 public:
00290 
00291 static int          Cancel(pthread_t tid) {return pthread_cancel(tid);}
00292 
00293 static int          Detach(pthread_t tid) {return pthread_detach(tid);}
00294 
00295 
00296 static  int  SetCancelOff() {
00297       return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
00298  };
00299 
00300 static  int  Join(pthread_t tid, void **ret) {
00301    return pthread_join(tid, ret);
00302  };
00303 
00304 static  int  SetCancelOn() {
00305       return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
00306  };
00307 
00308 static  int  SetCancelAsynchronous() {
00309       return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
00310  };
00311 
00312 static int  SetCancelDeferred() {
00313       return pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
00314  };
00315 
00316 static void  CancelPoint() {
00317       pthread_testcancel();
00318  };
00319 
00320 
00321 static pthread_t    ID(void)              {return pthread_self();}
00322 
00323 static int          Kill(pthread_t tid)   {return pthread_cancel(tid);}
00324 
00325 static unsigned long Num(void)
00326                        {if (!initDone) doInit();
00327                         return (unsigned long)pthread_getspecific(threadNumkey);
00328                        }
00329 
00330 static int          Run(pthread_t *, void *(*proc)(void *), void *arg, 
00331                         int opts=0, const char *desc = 0);
00332 
00333 static int          Same(pthread_t t1, pthread_t t2)
00334                         {return pthread_equal(t1, t2);}
00335 
00336 static void         setDebug(XrdSysError *erp) {eDest = erp;}
00337 
00338 static void         setStackSize(size_t stsz) {stackSize = stsz;}
00339 
00340 static int          Signal(pthread_t tid, int snum)
00341                        {return pthread_kill(tid, snum);}
00342  
00343 static int          Wait(pthread_t tid);
00344 
00345                     XrdSysThread() {}
00346                    ~XrdSysThread() {}
00347 
00348 private:
00349 static void          doInit(void);
00350 static XrdSysError  *eDest;
00351 static pthread_key_t threadNumkey;
00352 static size_t        stackSize;
00353 static int           initDone;
00354 };
00355 #endif

Generated on Tue Jul 5 14:47:03 2011 for ROOT_528-00b_version by  doxygen 1.5.1