File indexing completed on 2025-01-18 10:15:43
0001 #ifndef __SYS_PTHREAD__
0002 #define __SYS_PTHREAD__
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <cerrno>
0033 #ifdef WIN32
0034 #define HAVE_STRUCT_TIMESPEC 1
0035 #endif
0036 #include <pthread.h>
0037 #include <signal.h>
0038 #ifdef AIX
0039 #include <sys/sem.h>
0040 #else
0041 #include <semaphore.h>
0042 #endif
0043
0044 #ifdef __APPLE__
0045 #ifndef CLOCK_REALTIME
0046 #include <mach/clock.h>
0047 #include <mach/mach.h>
0048 #endif
0049 namespace
0050 {
0051 template< typename TYPE >
0052 void get_apple_realtime( TYPE & wait )
0053 {
0054 #ifdef CLOCK_REALTIME
0055 clock_gettime(CLOCK_REALTIME, &wait);
0056 #else
0057 clock_serv_t cclock;
0058 mach_timespec_t mts;
0059 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
0060 clock_get_time(cclock, &mts);
0061 mach_port_deallocate(mach_task_self(), cclock);
0062 wait.tv_sec = mts.tv_sec;
0063 wait.tv_nsec = mts.tv_nsec;
0064 #endif
0065 }
0066 }
0067 #endif
0068
0069 #include "XrdSys/XrdSysError.hh"
0070
0071
0072
0073
0074
0075
0076
0077
0078 class XrdSysCondVar
0079 {
0080 public:
0081
0082 inline void Lock() {pthread_mutex_lock(&cmut);}
0083
0084 inline void Signal() {if (relMutex) pthread_mutex_lock(&cmut);
0085 pthread_cond_signal(&cvar);
0086 if (relMutex) pthread_mutex_unlock(&cmut);
0087 }
0088
0089 inline void Broadcast() {if (relMutex) pthread_mutex_lock(&cmut);
0090 pthread_cond_broadcast(&cvar);
0091 if (relMutex) pthread_mutex_unlock(&cmut);
0092 }
0093
0094 inline void UnLock() {pthread_mutex_unlock(&cmut);}
0095
0096 int Wait();
0097 int Wait(int sec);
0098 int WaitMS(int msec);
0099
0100 XrdSysCondVar( int relm=1,
0101 const char *cid=0
0102 ) {pthread_cond_init(&cvar, NULL);
0103 pthread_mutex_init(&cmut, NULL);
0104 relMutex = relm; condID = (cid ? cid : "unk");
0105 }
0106 ~XrdSysCondVar() {pthread_cond_destroy(&cvar);
0107 pthread_mutex_destroy(&cmut);
0108 }
0109 private:
0110
0111 pthread_cond_t cvar;
0112 pthread_mutex_t cmut;
0113 int relMutex;
0114 const char *condID;
0115 };
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 class XrdSysCondVarHelper
0129 {
0130 public:
0131
0132 inline void Lock(XrdSysCondVar *CndVar)
0133 {if (cnd) {if (cnd != CndVar) cnd->UnLock();
0134 else return;
0135 }
0136 CndVar->Lock();
0137 cnd = CndVar;
0138 };
0139
0140 inline void UnLock() {if (cnd) {cnd->UnLock(); cnd = 0;}}
0141
0142 XrdSysCondVarHelper(XrdSysCondVar *CndVar=0)
0143 {if (CndVar) CndVar->Lock();
0144 cnd = CndVar;
0145 }
0146 XrdSysCondVarHelper(XrdSysCondVar &CndVar)
0147 {CndVar.Lock();
0148 cnd = &CndVar;
0149 }
0150
0151 ~XrdSysCondVarHelper() {if (cnd) UnLock();}
0152 private:
0153 XrdSysCondVar *cnd;
0154 };
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 class XrdSysMutex
0165 {
0166 public:
0167 friend class XrdSysCondVar2;
0168
0169 inline int CondLock()
0170 {if (pthread_mutex_trylock( &cs )) return 0;
0171 return 1;
0172 }
0173 #ifdef __APPLE__
0174 inline int TimedLock( int wait_ms )
0175 {
0176 struct timespec wait, cur, dur;
0177 get_apple_realtime(wait);
0178 wait.tv_sec += (wait_ms / 1000);
0179 wait.tv_nsec += (wait_ms % 1000) * 1000000;
0180 wait.tv_sec += (wait.tv_nsec / 1000000000);
0181 wait.tv_nsec = wait.tv_nsec % 1000000000;
0182
0183 int rc;
0184 while( ( rc = pthread_mutex_trylock( &cs ) ) == EBUSY )
0185 {
0186 get_apple_realtime(cur);
0187 if( ( cur.tv_sec > wait.tv_sec ) ||
0188 ( ( cur.tv_sec == wait.tv_sec ) && ( cur.tv_nsec >= wait.tv_nsec ) ) )
0189 return 0;
0190
0191 dur.tv_sec = wait.tv_sec - cur.tv_sec;
0192 dur.tv_nsec = wait.tv_nsec - cur.tv_nsec;
0193 if( dur.tv_nsec < 0 )
0194 {
0195 --dur.tv_sec;
0196 dur.tv_nsec += 1000000000;
0197 }
0198
0199 if( ( dur.tv_sec != 0 ) || ( dur.tv_nsec > 1000000 ) )
0200 {
0201 dur.tv_sec = 0;
0202 dur.tv_nsec = 1000000;
0203 }
0204
0205 nanosleep( &dur, 0 );
0206 }
0207
0208 return !rc;
0209 }
0210 #else
0211 inline int TimedLock(int wait_ms)
0212 {struct timespec wait;
0213 clock_gettime(CLOCK_REALTIME, &wait);
0214 wait.tv_sec += (wait_ms / 1000);
0215 wait.tv_nsec += (wait_ms % 1000) * 1000000;
0216 wait.tv_sec += (wait.tv_nsec / 1000000000);
0217 wait.tv_nsec = wait.tv_nsec % 1000000000;
0218 return !pthread_mutex_timedlock(&cs, &wait);
0219 }
0220 #endif
0221
0222 inline void Lock() {pthread_mutex_lock(&cs);}
0223
0224 inline void UnLock() {pthread_mutex_unlock(&cs);}
0225
0226 XrdSysMutex() {pthread_mutex_init(&cs, NULL);}
0227 ~XrdSysMutex() {pthread_mutex_destroy(&cs);}
0228
0229 protected:
0230
0231 pthread_mutex_t cs;
0232 };
0233
0234
0235
0236
0237
0238
0239
0240
0241 class XrdSysRecMutex: public XrdSysMutex
0242 {
0243 public:
0244
0245 XrdSysRecMutex();
0246
0247 int InitRecMutex();
0248 int ReInitRecMutex();
0249
0250 };
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262 class XrdSysMutexHelper
0263 {
0264 public:
0265
0266 inline void Lock(XrdSysMutex *Mutex)
0267 {if (mtx) {if (mtx != Mutex) mtx->UnLock();
0268 else return;
0269 }
0270 Mutex->Lock();
0271 mtx = Mutex;
0272 };
0273
0274 inline void UnLock() {if (mtx) {mtx->UnLock(); mtx = 0;}}
0275
0276 XrdSysMutexHelper(XrdSysMutex *mutex=0)
0277 {if (mutex) mutex->Lock();
0278 mtx = mutex;
0279 }
0280 XrdSysMutexHelper(XrdSysMutex &mutex)
0281 {mutex.Lock();
0282 mtx = &mutex;
0283 }
0284
0285 ~XrdSysMutexHelper() {if (mtx) UnLock();}
0286 private:
0287 XrdSysMutex *mtx;
0288 };
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 class XrdSysCondVar2
0300 {
0301 public:
0302
0303 inline void Signal() {pthread_cond_signal(&cvar);}
0304
0305 inline void Broadcast() {pthread_cond_broadcast(&cvar);}
0306
0307 inline int Wait() {return pthread_cond_wait(&cvar, mtxP);}
0308 bool Wait(int sec) {return WaitMS(sec*1000);}
0309 bool WaitMS(int msec);
0310
0311 XrdSysCondVar2(XrdSysMutex &mtx) : mtxP(&mtx.cs)
0312 {pthread_cond_init(&cvar, NULL);}
0313
0314 ~XrdSysCondVar2() {pthread_cond_destroy(&cvar);}
0315
0316 protected:
0317
0318 pthread_cond_t cvar;
0319 pthread_mutex_t *mtxP;
0320 };
0321
0322
0323
0324
0325
0326
0327
0328
0329 class XrdSysRWLock
0330 {
0331 public:
0332
0333 inline int CondReadLock()
0334 {if (pthread_rwlock_tryrdlock( &lock )) return 0;
0335 return 1;
0336 }
0337 inline int CondWriteLock()
0338 {if (pthread_rwlock_trywrlock( &lock )) return 0;
0339 return 1;
0340 }
0341
0342 inline void ReadLock() {pthread_rwlock_rdlock(&lock);}
0343 inline void WriteLock() {pthread_rwlock_wrlock(&lock);}
0344
0345 inline void ReadLock( int &status ) {status = pthread_rwlock_rdlock(&lock);}
0346 inline void WriteLock( int &status ) {status = pthread_rwlock_wrlock(&lock);}
0347
0348 inline void UnLock() {pthread_rwlock_unlock(&lock);}
0349
0350 enum PrefType {prefWR=1};
0351
0352 XrdSysRWLock(PrefType )
0353 {
0354 #if defined(__linux__) && (defined(__GLIBC__) || defined(__UCLIBC__))
0355 pthread_rwlockattr_t attr;
0356 pthread_rwlockattr_setkind_np(&attr,
0357 PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
0358 pthread_rwlock_init(&lock, &attr);
0359 #else
0360 pthread_rwlock_init(&lock, NULL);
0361 #endif
0362 }
0363
0364 XrdSysRWLock() {pthread_rwlock_init(&lock, NULL);}
0365 ~XrdSysRWLock() {pthread_rwlock_destroy(&lock);}
0366
0367 inline void ReInitialize(PrefType )
0368 {
0369 pthread_rwlock_destroy(&lock);
0370 #if defined(__linux__) && (defined(__GLIBC__) || defined(__UCLIBC__))
0371 pthread_rwlockattr_t attr;
0372 pthread_rwlockattr_setkind_np(&attr,
0373 PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
0374 pthread_rwlock_init(&lock, &attr);
0375 #else
0376 pthread_rwlock_init(&lock, NULL);
0377 #endif
0378 }
0379
0380 inline void ReInitialize()
0381 {
0382 pthread_rwlock_destroy(&lock);
0383 pthread_rwlock_init(&lock, NULL);
0384 }
0385
0386 protected:
0387
0388 pthread_rwlock_t lock;
0389 };
0390
0391
0392
0393
0394
0395
0396
0397 class XrdSysRWLockHelper
0398 {
0399 public:
0400
0401 inline void Lock(XrdSysRWLock *lock, bool rd = 1)
0402 {if (lck) {if (lck != lock) lck->UnLock();
0403 else return;
0404 }
0405 if (rd) lock->ReadLock();
0406 else lock->WriteLock();
0407 lck = lock;
0408 };
0409
0410 inline void UnLock() {if (lck) {lck->UnLock(); lck = 0;}}
0411
0412 XrdSysRWLockHelper(XrdSysRWLock *l=0, bool rd = 1)
0413 { if (l) {if (rd) l->ReadLock();
0414 else l->WriteLock();
0415 }
0416 lck = l;
0417 }
0418 XrdSysRWLockHelper(XrdSysRWLock &l, bool rd = 1)
0419 { if (rd) l.ReadLock();
0420 else l.WriteLock();
0421 lck = &l;
0422 }
0423
0424 ~XrdSysRWLockHelper() {if (lck) UnLock();}
0425 private:
0426 XrdSysRWLock *lck;
0427 };
0428
0429
0430
0431
0432
0433 class XrdSysFusedMutex
0434 {
0435 public:
0436
0437 inline void Lock() {isRW ? rwLok->WriteLock() : mutex->Lock();}
0438
0439 inline void ReadLock() {isRW ? rwLok->ReadLock() : mutex->Lock();}
0440
0441 inline void WriteLock() {isRW ? rwLok->WriteLock() : mutex->Lock();}
0442
0443 inline void UnLock() {isRW ? rwLok->UnLock() : mutex->UnLock();}
0444
0445 XrdSysFusedMutex(XrdSysRWLock &mtx)
0446 : rwLok(&mtx), isRW(true) {}
0447
0448 XrdSysFusedMutex(XrdSysMutex &mtx)
0449 : mutex(&mtx), isRW(false) {}
0450
0451 ~XrdSysFusedMutex() {}
0452 private:
0453
0454 union {XrdSysRWLock *rwLok; XrdSysMutex *mutex;};
0455 bool isRW;
0456 };
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467 #if defined(__APPLE__) || defined(__GNU__)
0468 class XrdSysSemaphore
0469 {
0470 public:
0471
0472 int CondWait();
0473
0474 void Post();
0475
0476 void Wait();
0477
0478 static void CleanUp(void *semVar);
0479
0480 XrdSysSemaphore(int semval=1,const char *cid=0) : semVar(0, cid)
0481 {semVal = semval; semWait = 0;}
0482 ~XrdSysSemaphore() {}
0483
0484 private:
0485
0486 XrdSysCondVar semVar;
0487 int semVal;
0488 int semWait;
0489 };
0490
0491 #else
0492
0493 class XrdSysSemaphore
0494 {
0495 public:
0496
0497 inline int CondWait()
0498 {while(sem_trywait( &h_semaphore ))
0499 {if (errno == EAGAIN) return 0;
0500 if (errno != EINTR) { throw "sem_CondWait() failed";}
0501 }
0502 return 1;
0503 }
0504
0505 inline void Post() {if (sem_post(&h_semaphore))
0506 {throw "sem_post() failed";}
0507 }
0508
0509 inline void Wait() {while (sem_wait(&h_semaphore))
0510 {if (EINTR != errno)
0511 {throw "sem_wait() failed";}
0512 }
0513 }
0514
0515 XrdSysSemaphore(int semval=1, const char * =0)
0516 {if (sem_init(&h_semaphore, 0, semval))
0517 {throw "sem_init() failed";}
0518 }
0519 ~XrdSysSemaphore() {if (sem_destroy(&h_semaphore))
0520 {abort();}
0521 }
0522
0523 private:
0524
0525 sem_t h_semaphore;
0526 };
0527 #endif
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543 #define XRDSYSTHREAD_BIND 0x001
0544
0545
0546
0547
0548 #define XRDSYSTHREAD_HOLD 0x002
0549
0550 class XrdSysThread
0551 {
0552 public:
0553
0554 static int Cancel(pthread_t tid) {return pthread_cancel(tid);}
0555
0556 static int Detach(pthread_t tid) {return pthread_detach(tid);}
0557
0558
0559 static int SetCancelOff() {
0560 return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
0561 };
0562
0563 static int Join(pthread_t tid, void **ret) {
0564 return pthread_join(tid, ret);
0565 };
0566
0567 static int SetCancelOn() {
0568 return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
0569 };
0570
0571 static int SetCancelAsynchronous() {
0572 return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
0573 };
0574
0575 static int SetCancelDeferred() {
0576 return pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
0577 };
0578
0579 static void CancelPoint() {
0580 pthread_testcancel();
0581 };
0582
0583
0584 static pthread_t ID(void) {return pthread_self();}
0585
0586 static int Kill(pthread_t tid) {return pthread_cancel(tid);}
0587
0588 static unsigned long Num(void);
0589
0590 static int Run(pthread_t *, void *(*proc)(void *), void *arg,
0591 int opts=0, const char *desc = 0);
0592
0593 static int Same(pthread_t t1, pthread_t t2)
0594 {return pthread_equal(t1, t2);}
0595
0596 static void setDebug(XrdSysError *erp) {eDest = erp;}
0597
0598 static void setStackSize(size_t stsz, bool force=false);
0599
0600 static int Signal(pthread_t tid, int snum)
0601 {return pthread_kill(tid, snum);}
0602
0603 static int Wait(pthread_t tid);
0604
0605 XrdSysThread() {}
0606 ~XrdSysThread() {}
0607
0608 private:
0609 static XrdSysError *eDest;
0610 static size_t stackSize;
0611 };
0612 #endif