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
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
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 #define XRDSYSTHREAD_BIND 0x001
00281
00282
00283
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