00001 #ifndef __SYS_PTHREAD__
00002 #define __SYS_PTHREAD__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <errno.h>
00033 #ifdef WIN32
00034 #define HAVE_STRUCT_TIMESPEC 1
00035 #endif
00036 #include <pthread.h>
00037 #include <signal.h>
00038 #ifdef AIX
00039 #include <sys/sem.h>
00040 #else
00041 #include <semaphore.h>
00042 #endif
00043
00044 #include "XrdSys/XrdSysError.hh"
00045
00046
00047
00048
00049
00050
00051
00052
00053 class XrdSysCondVar
00054 {
00055 public:
00056
00057 inline void Lock() {pthread_mutex_lock(&cmut);}
00058
00059 inline void Signal() {if (relMutex) pthread_mutex_lock(&cmut);
00060 pthread_cond_signal(&cvar);
00061 if (relMutex) pthread_mutex_unlock(&cmut);
00062 }
00063
00064 inline void Broadcast() {if (relMutex) pthread_mutex_lock(&cmut);
00065 pthread_cond_broadcast(&cvar);
00066 if (relMutex) pthread_mutex_unlock(&cmut);
00067 }
00068
00069 inline void UnLock() {pthread_mutex_unlock(&cmut);}
00070
00071 int Wait();
00072 int Wait(int sec);
00073 int WaitMS(int msec);
00074
00075 XrdSysCondVar( int relm=1,
00076 const char *cid=0
00077 ) {pthread_cond_init(&cvar, NULL);
00078 pthread_mutex_init(&cmut, NULL);
00079 relMutex = relm; condID = (cid ? cid : "unk");
00080 }
00081 ~XrdSysCondVar() {pthread_cond_destroy(&cvar);
00082 pthread_mutex_destroy(&cmut);
00083 }
00084 private:
00085
00086 pthread_cond_t cvar;
00087 pthread_mutex_t cmut;
00088 int relMutex;
00089 const char *condID;
00090 };
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 class XrdSysCondVarHelper
00105 {
00106 public:
00107
00108 inline void Lock(XrdSysCondVar *CndVar)
00109 {if (cnd) {if (cnd != CndVar) cnd->UnLock();
00110 else return;
00111 }
00112 CndVar->Lock();
00113 cnd = CndVar;
00114 };
00115
00116 inline void UnLock() {if (cnd) {cnd->UnLock(); cnd = 0;}}
00117
00118 XrdSysCondVarHelper(XrdSysCondVar *CndVar=0)
00119 {if (CndVar) CndVar->Lock();
00120 cnd = CndVar;
00121 }
00122 XrdSysCondVarHelper(XrdSysCondVar &CndVar)
00123 {CndVar.Lock();
00124 cnd = &CndVar;
00125 }
00126
00127 ~XrdSysCondVarHelper() {if (cnd) UnLock();}
00128 private:
00129 XrdSysCondVar *cnd;
00130 };
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 class XrdSysMutex
00141 {
00142 public:
00143
00144 inline int CondLock()
00145 {if (pthread_mutex_trylock( &cs )) return 0;
00146 return 1;
00147 }
00148
00149 inline void Lock() {pthread_mutex_lock(&cs);}
00150
00151 inline void UnLock() {pthread_mutex_unlock(&cs);}
00152
00153 XrdSysMutex() {pthread_mutex_init(&cs, NULL);}
00154 ~XrdSysMutex() {pthread_mutex_destroy(&cs);}
00155
00156 protected:
00157
00158 pthread_mutex_t cs;
00159 };
00160
00161
00162
00163
00164
00165
00166
00167
00168 class XrdSysRecMutex: public XrdSysMutex
00169 {
00170 public:
00171
00172 XrdSysRecMutex();
00173
00174 int InitRecMutex();
00175 int ReInitRecMutex();
00176
00177 };
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 class XrdSysMutexHelper
00190 {
00191 public:
00192
00193 inline void Lock(XrdSysMutex *Mutex)
00194 {if (mtx) {if (mtx != Mutex) mtx->UnLock();
00195 else return;
00196 }
00197 Mutex->Lock();
00198 mtx = Mutex;
00199 };
00200
00201 inline void UnLock() {if (mtx) {mtx->UnLock(); mtx = 0;}}
00202
00203 XrdSysMutexHelper(XrdSysMutex *mutex=0)
00204 {if (mutex) mutex->Lock();
00205 mtx = mutex;
00206 }
00207 XrdSysMutexHelper(XrdSysMutex &mutex)
00208 {mutex.Lock();
00209 mtx = &mutex;
00210 }
00211
00212 ~XrdSysMutexHelper() {if (mtx) UnLock();}
00213 private:
00214 XrdSysMutex *mtx;
00215 };
00216
00217
00218
00219
00220
00221
00222
00223
00224 class XrdSysRWLock
00225 {
00226 public:
00227
00228 inline int CondReadLock()
00229 {if (pthread_rwlock_tryrdlock( &lock )) return 0;
00230 return 1;
00231 }
00232 inline int CondWriteLock()
00233 {if (pthread_rwlock_trywrlock( &lock )) return 0;
00234 return 1;
00235 }
00236
00237 inline void ReadLock() {pthread_rwlock_rdlock(&lock);}
00238 inline void WriteLock() {pthread_rwlock_wrlock(&lock);}
00239
00240 inline void ReadLock( int &status ) {status = pthread_rwlock_rdlock(&lock);}
00241 inline void WriteLock( int &status ) {status = pthread_rwlock_wrlock(&lock);}
00242
00243 inline void UnLock() {pthread_rwlock_unlock(&lock);}
00244
00245 XrdSysRWLock() {pthread_rwlock_init(&lock, NULL);}
00246 ~XrdSysRWLock() {pthread_rwlock_destroy(&lock);}
00247
00248 inline void ReInitialize()
00249 {
00250 pthread_rwlock_destroy(&lock);
00251 pthread_rwlock_init(&lock, NULL);
00252 }
00253
00254 protected:
00255
00256 pthread_rwlock_t lock;
00257 };
00258
00259
00260
00261
00262
00263
00264
00265 class XrdSysRWLockHelper
00266 {
00267 public:
00268
00269 inline void Lock(XrdSysRWLock *lock, bool rd = 1)
00270 {if (lck) {if (lck != lock) lck->UnLock();
00271 else return;
00272 }
00273 if (rd) lock->ReadLock();
00274 else lock->WriteLock();
00275 lck = lock;
00276 };
00277
00278 inline void UnLock() {if (lck) {lck->UnLock(); lck = 0;}}
00279
00280 XrdSysRWLockHelper(XrdSysRWLock *l=0, bool rd = 1)
00281 { if (l) {if (rd) l->ReadLock();
00282 else l->WriteLock();
00283 }
00284 lck = l;
00285 }
00286 XrdSysRWLockHelper(XrdSysRWLock &l, bool rd = 1)
00287 { if (rd) l.ReadLock();
00288 else l.WriteLock();
00289 lck = &l;
00290 }
00291
00292 ~XrdSysRWLockHelper() {if (lck) UnLock();}
00293 private:
00294 XrdSysRWLock *lck;
00295 };
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 #ifdef __APPLE__
00307 class XrdSysSemaphore
00308 {
00309 public:
00310
00311 int CondWait();
00312
00313 void Post();
00314
00315 void Wait();
00316
00317 static void CleanUp(void *semVar);
00318
00319 XrdSysSemaphore(int semval=1,const char *cid=0) : semVar(0, cid)
00320 {semVal = semval; semWait = 0;}
00321 ~XrdSysSemaphore() {}
00322
00323 private:
00324
00325 XrdSysCondVar semVar;
00326 int semVal;
00327 int semWait;
00328 };
00329
00330 #else
00331
00332 class XrdSysSemaphore
00333 {
00334 public:
00335
00336 inline int CondWait()
00337 {while(sem_trywait( &h_semaphore ))
00338 {if (errno == EAGAIN) return 0;
00339 if (errno != EINTR) { throw "sem_CondWait() failed";}
00340 }
00341 return 1;
00342 }
00343
00344 inline void Post() {if (sem_post(&h_semaphore))
00345 {throw "sem_post() failed";}
00346 }
00347
00348 inline void Wait() {while (sem_wait(&h_semaphore))
00349 {if (EINTR != errno)
00350 {throw "sem_wait() failed";}
00351 }
00352 }
00353
00354 XrdSysSemaphore(int semval=1, const char * =0)
00355 {if (sem_init(&h_semaphore, 0, semval))
00356 {throw "sem_init() failed";}
00357 }
00358 ~XrdSysSemaphore() {if (sem_destroy(&h_semaphore))
00359 {abort();}
00360 }
00361
00362 private:
00363
00364 sem_t h_semaphore;
00365 };
00366 #endif
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 #define XRDSYSTHREAD_BIND 0x001
00383
00384
00385
00386
00387 #define XRDSYSTHREAD_HOLD 0x002
00388
00389 class XrdSysThread
00390 {
00391 public:
00392
00393 static int Cancel(pthread_t tid) {return pthread_cancel(tid);}
00394
00395 static int Detach(pthread_t tid) {return pthread_detach(tid);}
00396
00397
00398 static int SetCancelOff() {
00399 return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
00400 };
00401
00402 static int Join(pthread_t tid, void **ret) {
00403 return pthread_join(tid, ret);
00404 };
00405
00406 static int SetCancelOn() {
00407 return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
00408 };
00409
00410 static int SetCancelAsynchronous() {
00411 return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
00412 };
00413
00414 static int SetCancelDeferred() {
00415 return pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
00416 };
00417
00418 static void CancelPoint() {
00419 pthread_testcancel();
00420 };
00421
00422
00423 static pthread_t ID(void) {return pthread_self();}
00424
00425 static int Kill(pthread_t tid) {return pthread_cancel(tid);}
00426
00427 static unsigned long Num(void);
00428
00429 static int Run(pthread_t *, void *(*proc)(void *), void *arg,
00430 int opts=0, const char *desc = 0);
00431
00432 static int Same(pthread_t t1, pthread_t t2)
00433 {return pthread_equal(t1, t2);}
00434
00435 static void setDebug(XrdSysError *erp) {eDest = erp;}
00436
00437 static void setStackSize(size_t stsz) {stackSize = stsz;}
00438
00439 static int Signal(pthread_t tid, int snum)
00440 {return pthread_kill(tid, snum);}
00441
00442 static int Wait(pthread_t tid);
00443
00444 XrdSysThread() {}
00445 ~XrdSysThread() {}
00446
00447 private:
00448 static XrdSysError *eDest;
00449 static size_t stackSize;
00450 };
00451 #endif