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 UnLock() {pthread_rwlock_unlock(&lock);}
00241
00242 XrdSysRWLock() {pthread_rwlock_init(&lock, NULL);}
00243 ~XrdSysRWLock() {pthread_rwlock_destroy(&lock);}
00244
00245 inline void ReInitialize()
00246 {
00247 pthread_rwlock_destroy(&lock);
00248 pthread_rwlock_init(&lock, NULL);
00249 }
00250
00251 protected:
00252
00253 pthread_rwlock_t lock;
00254 };
00255
00256
00257
00258
00259
00260
00261
00262 class XrdSysRWLockHelper
00263 {
00264 public:
00265
00266 inline void Lock(XrdSysRWLock *lock, bool rd = 1)
00267 {if (lck) {if (lck != lock) lck->UnLock();
00268 else return;
00269 }
00270 if (rd) lock->ReadLock();
00271 else lock->WriteLock();
00272 lck = lock;
00273 };
00274
00275 inline void UnLock() {if (lck) {lck->UnLock(); lck = 0;}}
00276
00277 XrdSysRWLockHelper(XrdSysRWLock *l=0, bool rd = 1)
00278 { if (l) {if (rd) l->ReadLock();
00279 else l->WriteLock();
00280 }
00281 lck = l;
00282 }
00283 XrdSysRWLockHelper(XrdSysRWLock &l, bool rd = 1)
00284 { if (rd) l.ReadLock();
00285 else l.WriteLock();
00286 lck = &l;
00287 }
00288
00289 ~XrdSysRWLockHelper() {if (lck) UnLock();}
00290 private:
00291 XrdSysRWLock *lck;
00292 };
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 #ifdef __APPLE__
00304 class XrdSysSemaphore
00305 {
00306 public:
00307
00308 int CondWait();
00309
00310 void Post();
00311
00312 void Wait();
00313
00314 static void CleanUp(void *semVar);
00315
00316 XrdSysSemaphore(int semval=1,const char *cid=0) : semVar(0, cid)
00317 {semVal = semval; semWait = 0;}
00318 ~XrdSysSemaphore() {}
00319
00320 private:
00321
00322 XrdSysCondVar semVar;
00323 int semVal;
00324 int semWait;
00325 };
00326
00327 #else
00328
00329 class XrdSysSemaphore
00330 {
00331 public:
00332
00333 inline int CondWait()
00334 {while(sem_trywait( &h_semaphore ))
00335 {if (errno == EAGAIN) return 0;
00336 if (errno != EINTR) { throw "sem_CondWait() failed";}
00337 }
00338 return 1;
00339 }
00340
00341 inline void Post() {if (sem_post(&h_semaphore))
00342 {throw "sem_post() failed";}
00343 }
00344
00345 inline void Wait() {while (sem_wait(&h_semaphore))
00346 {if (EINTR != errno)
00347 {throw "sem_wait() failed";}
00348 }
00349 }
00350
00351 XrdSysSemaphore(int semval=1, const char * =0)
00352 {if (sem_init(&h_semaphore, 0, semval))
00353 {throw "sem_init() failed";}
00354 }
00355 ~XrdSysSemaphore() {if (sem_destroy(&h_semaphore))
00356 {abort();}
00357 }
00358
00359 private:
00360
00361 sem_t h_semaphore;
00362 };
00363 #endif
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 #define XRDSYSTHREAD_BIND 0x001
00380
00381
00382
00383
00384 #define XRDSYSTHREAD_HOLD 0x002
00385
00386 class XrdSysThread
00387 {
00388 public:
00389
00390 static int Cancel(pthread_t tid) {return pthread_cancel(tid);}
00391
00392 static int Detach(pthread_t tid) {return pthread_detach(tid);}
00393
00394
00395 static int SetCancelOff() {
00396 return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
00397 };
00398
00399 static int Join(pthread_t tid, void **ret) {
00400 return pthread_join(tid, ret);
00401 };
00402
00403 static int SetCancelOn() {
00404 return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
00405 };
00406
00407 static int SetCancelAsynchronous() {
00408 return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
00409 };
00410
00411 static int SetCancelDeferred() {
00412 return pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
00413 };
00414
00415 static void CancelPoint() {
00416 pthread_testcancel();
00417 };
00418
00419
00420 static pthread_t ID(void) {return pthread_self();}
00421
00422 static int Kill(pthread_t tid) {return pthread_cancel(tid);}
00423
00424 static unsigned long Num(void);
00425
00426 static int Run(pthread_t *, void *(*proc)(void *), void *arg,
00427 int opts=0, const char *desc = 0);
00428
00429 static int Same(pthread_t t1, pthread_t t2)
00430 {return pthread_equal(t1, t2);}
00431
00432 static void setDebug(XrdSysError *erp) {eDest = erp;}
00433
00434 static void setStackSize(size_t stsz) {stackSize = stsz;}
00435
00436 static int Signal(pthread_t tid, int snum)
00437 {return pthread_kill(tid, snum);}
00438
00439 static int Wait(pthread_t tid);
00440
00441 XrdSysThread() {}
00442 ~XrdSysThread() {}
00443
00444 private:
00445 static XrdSysError *eDest;
00446 static size_t stackSize;
00447 };
00448 #endif