00001 #ifndef __SYS_PTHREAD__
00002 #define __SYS_PTHREAD__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00031
00032
00033
00034
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,
00059 const char *cid=0
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
00079
00080
00081
00082
00083
00084
00085
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
00118
00119
00120
00121
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
00146
00147
00148
00149
00150
00151 class XrdSysRecMutex: public XrdSysMutex
00152 {
00153 public:
00154
00155 XrdSysRecMutex();
00156
00157 };
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
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
00199
00200
00201
00202
00203
00204 class XrdSysRWLock
00205 {
00206 public:
00207
00208 inline int CondReadLock()
00209 {if (pthread_rwlock_tryrdlock( &lock )) return 0;
00210 return 1;
00211 }
00212 inline int CondWriteLock()
00213 {if (pthread_rwlock_trywrlock( &lock )) return 0;
00214 return 1;
00215 }
00216
00217 inline void ReadLock() {pthread_rwlock_rdlock(&lock);}
00218 inline void WriteLock() {pthread_rwlock_wrlock(&lock);}
00219
00220 inline void UnLock() {pthread_rwlock_unlock(&lock);}
00221
00222 XrdSysRWLock() {pthread_rwlock_init(&lock, NULL);}
00223 ~XrdSysRWLock() {pthread_rwlock_destroy(&lock);}
00224
00225 protected:
00226
00227 pthread_rwlock_t lock;
00228 };
00229
00230
00231
00232
00233
00234
00235
00236 class XrdSysRWLockHelper
00237 {
00238 public:
00239
00240 inline void Lock(XrdSysRWLock *lock, bool rd = 1)
00241 {if (lck) {if (lck != lock) lck->UnLock();
00242 else return;
00243 }
00244 if (rd) lock->ReadLock();
00245 else lock->WriteLock();
00246 lck = lock;
00247 };
00248
00249 inline void UnLock() {if (lck) {lck->UnLock(); lck = 0;}}
00250
00251 XrdSysRWLockHelper(XrdSysRWLock *l=0, bool rd = 1)
00252 { if (l) {if (rd) l->ReadLock();
00253 else l->WriteLock();
00254 }
00255 lck = l;
00256 }
00257 XrdSysRWLockHelper(XrdSysRWLock &l, bool rd = 1)
00258 { if (rd) l.ReadLock();
00259 else l.WriteLock();
00260 lck = &l;
00261 }
00262
00263 ~XrdSysRWLockHelper() {if (lck) UnLock();}
00264 private:
00265 XrdSysRWLock *lck;
00266 };
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 #ifdef __macos__
00278 class XrdSysSemaphore
00279 {
00280 public:
00281
00282 int CondWait();
00283
00284 void Post();
00285
00286 void Wait();
00287
00288 XrdSysSemaphore(int semval=1,const char *cid=0) : semVar(0, cid)
00289 {semVal = semval; semWait = 0;}
00290 ~XrdSysSemaphore() {}
00291
00292 private:
00293
00294 XrdSysCondVar semVar;
00295 int semVal;
00296 int semWait;
00297 };
00298
00299 #else
00300
00301 class XrdSysSemaphore
00302 {
00303 public:
00304
00305 inline int CondWait()
00306 {while(sem_trywait( &h_semaphore ))
00307 {if (errno == EAGAIN) return 0;
00308 if (errno != EINTR) { throw "sem_CondWait() failed";}
00309 }
00310 return 1;
00311 }
00312
00313 inline void Post() {if (sem_post(&h_semaphore))
00314 {throw "sem_post() failed";}
00315 }
00316
00317 inline void Wait() {while (sem_wait(&h_semaphore))
00318 {if (EINTR != errno)
00319 {throw "sem_wait() failed";}
00320 }
00321 }
00322
00323 XrdSysSemaphore(int semval=1, const char * =0)
00324 {if (sem_init(&h_semaphore, 0, semval))
00325 {throw "sem_init() failed";}
00326 }
00327 ~XrdSysSemaphore() {if (sem_destroy(&h_semaphore))
00328 {throw "sem_destroy() failed";}
00329 }
00330
00331 private:
00332
00333 sem_t h_semaphore;
00334 };
00335 #endif
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 #define XRDSYSTHREAD_BIND 0x001
00352
00353
00354
00355
00356 #define XRDSYSTHREAD_HOLD 0x002
00357
00358 class XrdSysThread
00359 {
00360 public:
00361
00362 static int Cancel(pthread_t tid) {return pthread_cancel(tid);}
00363
00364 static int Detach(pthread_t tid) {return pthread_detach(tid);}
00365
00366
00367 static int SetCancelOff() {
00368 return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
00369 };
00370
00371 static int Join(pthread_t tid, void **ret) {
00372 return pthread_join(tid, ret);
00373 };
00374
00375 static int SetCancelOn() {
00376 return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
00377 };
00378
00379 static int SetCancelAsynchronous() {
00380 return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
00381 };
00382
00383 static int SetCancelDeferred() {
00384 return pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
00385 };
00386
00387 static void CancelPoint() {
00388 pthread_testcancel();
00389 };
00390
00391
00392 static pthread_t ID(void) {return pthread_self();}
00393
00394 static int Kill(pthread_t tid) {return pthread_cancel(tid);}
00395
00396 static unsigned long Num(void)
00397 {if (!initDone) doInit();
00398 return (unsigned long)pthread_getspecific(threadNumkey);
00399 }
00400
00401 static int Run(pthread_t *, void *(*proc)(void *), void *arg,
00402 int opts=0, const char *desc = 0);
00403
00404 static int Same(pthread_t t1, pthread_t t2)
00405 {return pthread_equal(t1, t2);}
00406
00407 static void setDebug(XrdSysError *erp) {eDest = erp;}
00408
00409 static void setStackSize(size_t stsz) {stackSize = stsz;}
00410
00411 static int Signal(pthread_t tid, int snum)
00412 {return pthread_kill(tid, snum);}
00413
00414 static int Wait(pthread_t tid);
00415
00416 XrdSysThread() {}
00417 ~XrdSysThread() {}
00418
00419 private:
00420 static void doInit(void);
00421 static XrdSysError *eDest;
00422 static pthread_key_t threadNumkey;
00423 static size_t stackSize;
00424 static int initDone;
00425 };
00426 #endif