xrootd
XrdSysPthread.hh
Go to the documentation of this file.
1 #ifndef __SYS_PTHREAD__
2 #define __SYS_PTHREAD__
3 /******************************************************************************/
4 /* */
5 /* X r d S y s P t h r e a d . h h */
6 /* */
7 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
8 /* Produced by Andrew Hanushevsky for Stanford University under contract */
9 /* DE-AC02-76-SFO0515 with the Department of Energy */
10 /* */
11 /* This file is part of the XRootD software suite. */
12 /* */
13 /* XRootD is free software: you can redistribute it and/or modify it under */
14 /* the terms of the GNU Lesser General Public License as published by the */
15 /* Free Software Foundation, either version 3 of the License, or (at your */
16 /* option) any later version. */
17 /* */
18 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
19 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
20 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
21 /* License for more details. */
22 /* */
23 /* You should have received a copy of the GNU Lesser General Public License */
24 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
25 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
26 /* */
27 /* The copyright holder's institutional names and contributor's names may not */
28 /* be used to endorse or promote products derived from this software without */
29 /* specific prior written permission of the institution or contributor. */
30 /******************************************************************************/
31 
32 #include <errno.h>
33 #ifdef WIN32
34 #define HAVE_STRUCT_TIMESPEC 1
35 #endif
36 #include <pthread.h>
37 #include <signal.h>
38 #ifdef AIX
39 #include <sys/sem.h>
40 #else
41 #include <semaphore.h>
42 #endif
43 
44 #include "XrdSys/XrdSysError.hh"
45 
46 /******************************************************************************/
47 /* X r d S y s C o n d V a r */
48 /******************************************************************************/
49 
50 // XrdSysCondVar implements the standard POSIX-compliant condition variable.
51 // Methods correspond to the equivalent pthread condvar functions.
52 
54 {
55 public:
56 
57 inline void Lock() {pthread_mutex_lock(&cmut);}
58 
59 inline void Signal() {if (relMutex) pthread_mutex_lock(&cmut);
60  pthread_cond_signal(&cvar);
61  if (relMutex) pthread_mutex_unlock(&cmut);
62  }
63 
64 inline void Broadcast() {if (relMutex) pthread_mutex_lock(&cmut);
65  pthread_cond_broadcast(&cvar);
66  if (relMutex) pthread_mutex_unlock(&cmut);
67  }
68 
69 inline void UnLock() {pthread_mutex_unlock(&cmut);}
70 
71  int Wait();
72  int Wait(int sec);
73  int WaitMS(int msec);
74 
75  XrdSysCondVar( int relm=1, // 0->Caller will handle lock/unlock
76  const char *cid=0 // ID string for debugging only
77  ) {pthread_cond_init(&cvar, NULL);
78  pthread_mutex_init(&cmut, NULL);
79  relMutex = relm; condID = (cid ? cid : "unk");
80  }
81  ~XrdSysCondVar() {pthread_cond_destroy(&cvar);
82  pthread_mutex_destroy(&cmut);
83  }
84 private:
85 
86 pthread_cond_t cvar;
87 pthread_mutex_t cmut;
89 const char *condID;
90 };
91 
92 
93 
94 /******************************************************************************/
95 /* X r d S y s C o n d V a r H e l p e r */
96 /******************************************************************************/
97 
98 // XrdSysCondVarHelper is used to implement monitors with the Lock of a a condvar.
99 // Monitors are used to lock
100 // whole regions of code (e.g., a method) and automatically
101 // unlock with exiting the region (e.g., return). The
102 // methods should be self-evident.
103 
105 {
106 public:
107 
108 inline void Lock(XrdSysCondVar *CndVar)
109  {if (cnd) {if (cnd != CndVar) cnd->UnLock();
110  else return;
111  }
112  CndVar->Lock();
113  cnd = CndVar;
114  };
115 
116 inline void UnLock() {if (cnd) {cnd->UnLock(); cnd = 0;}}
117 
119  {if (CndVar) CndVar->Lock();
120  cnd = CndVar;
121  }
123  {CndVar.Lock();
124  cnd = &CndVar;
125  }
126 
128 private:
130 };
131 
132 
133 /******************************************************************************/
134 /* X r d S y s M u t e x */
135 /******************************************************************************/
136 
137 // XrdSysMutex implements the standard POSIX mutex. The methods correspond
138 // to the equivalent pthread mutex functions.
139 
141 {
142 public:
143 
144 inline int CondLock()
145  {if (pthread_mutex_trylock( &cs )) return 0;
146  return 1;
147  }
148 
149 inline void Lock() {pthread_mutex_lock(&cs);}
150 
151 inline void UnLock() {pthread_mutex_unlock(&cs);}
152 
153  XrdSysMutex() {pthread_mutex_init(&cs, NULL);}
154  ~XrdSysMutex() {pthread_mutex_destroy(&cs);}
155 
156 protected:
157 
158 pthread_mutex_t cs;
159 };
160 
161 /******************************************************************************/
162 /* X r d S y s R e c M u t e x */
163 /******************************************************************************/
164 
165 // XrdSysRecMutex implements the recursive POSIX mutex. The methods correspond
166 // to the equivalent pthread mutex functions.
167 
169 {
170 public:
171 
173 
174 int InitRecMutex();
175 int ReInitRecMutex();
176 
177 };
178 
179 
180 /******************************************************************************/
181 /* X r d S y s M u t e x H e l p e r */
182 /******************************************************************************/
183 
184 // XrdSysMutexHelper us ised to implement monitors. Monitors are used to lock
185 // whole regions of code (e.g., a method) and automatically
186 // unlock with exiting the region (e.g., return). The
187 // methods should be self-evident.
188 
190 {
191 public:
192 
193 inline void Lock(XrdSysMutex *Mutex)
194  {if (mtx) {if (mtx != Mutex) mtx->UnLock();
195  else return;
196  }
197  Mutex->Lock();
198  mtx = Mutex;
199  };
200 
201 inline void UnLock() {if (mtx) {mtx->UnLock(); mtx = 0;}}
202 
204  {if (mutex) mutex->Lock();
205  mtx = mutex;
206  }
208  {mutex.Lock();
209  mtx = &mutex;
210  }
211 
213 private:
215 };
216 
217 /******************************************************************************/
218 /* X r d S y s R W L o c k */
219 /******************************************************************************/
220 
221 // XrdSysRWLock implements the standard POSIX wrlock mutex. The methods correspond
222 // to the equivalent pthread wrlock functions.
223 
225 {
226 public:
227 
228 inline int CondReadLock()
229  {if (pthread_rwlock_tryrdlock( &lock )) return 0;
230  return 1;
231  }
232 inline int CondWriteLock()
233  {if (pthread_rwlock_trywrlock( &lock )) return 0;
234  return 1;
235  }
236 
237 inline void ReadLock() {pthread_rwlock_rdlock(&lock);}
238 inline void WriteLock() {pthread_rwlock_wrlock(&lock);}
239 
240 inline void ReadLock( int &status ) {status = pthread_rwlock_rdlock(&lock);}
241 inline void WriteLock( int &status ) {status = pthread_rwlock_wrlock(&lock);}
242 
243 inline void UnLock() {pthread_rwlock_unlock(&lock);}
244 
245  XrdSysRWLock() {pthread_rwlock_init(&lock, NULL);}
246  ~XrdSysRWLock() {pthread_rwlock_destroy(&lock);}
247 
248 inline void ReInitialize()
249 {
250  pthread_rwlock_destroy(&lock);
251  pthread_rwlock_init(&lock, NULL);
252 }
253 
254 protected:
255 
256 pthread_rwlock_t lock;
257 };
258 
259 /******************************************************************************/
260 /* X r d S y s W R L o c k H e l p e r */
261 /******************************************************************************/
262 
263 // XrdSysWRLockHelper : helper class for XrdSysRWLock
264 
266 {
267 public:
268 
269 inline void Lock(XrdSysRWLock *lock, bool rd = 1)
270  {if (lck) {if (lck != lock) lck->UnLock();
271  else return;
272  }
273  if (rd) lock->ReadLock();
274  else lock->WriteLock();
275  lck = lock;
276  };
277 
278 inline void UnLock() {if (lck) {lck->UnLock(); lck = 0;}}
279 
280  XrdSysRWLockHelper(XrdSysRWLock *l=0, bool rd = 1)
281  { if (l) {if (rd) l->ReadLock();
282  else l->WriteLock();
283  }
284  lck = l;
285  }
287  { if (rd) l.ReadLock();
288  else l.WriteLock();
289  lck = &l;
290  }
291 
293 private:
295 };
296 
297 /******************************************************************************/
298 /* X r d S y s S e m a p h o r e */
299 /******************************************************************************/
300 
301 // XrdSysSemaphore implements the classic counting semaphore. The methods
302 // should be self-evident. Note that on certain platforms
303 // semaphores need to be implemented based on condition
304 // variables since no native implementation is available.
305 
306 #ifdef __APPLE__
307 class XrdSysSemaphore
308 {
309 public:
310 
311  int CondWait();
312 
313  void Post();
314 
315  void Wait();
316 
317 static void CleanUp(void *semVar);
318 
319  XrdSysSemaphore(int semval=1,const char *cid=0) : semVar(0, cid)
320  {semVal = semval; semWait = 0;}
321  ~XrdSysSemaphore() {}
322 
323 private:
324 
325 XrdSysCondVar semVar;
326 int semVal;
327 int semWait;
328 };
329 
330 #else
331 
333 {
334 public:
335 
336 inline int CondWait()
337  {while(sem_trywait( &h_semaphore ))
338  {if (errno == EAGAIN) return 0;
339  if (errno != EINTR) { throw "sem_CondWait() failed";}
340  }
341  return 1;
342  }
343 
344 inline void Post() {if (sem_post(&h_semaphore))
345  {throw "sem_post() failed";}
346  }
347 
348 inline void Wait() {while (sem_wait(&h_semaphore))
349  {if (EINTR != errno)
350  {throw "sem_wait() failed";}
351  }
352  }
353 
354  XrdSysSemaphore(int semval=1, const char * =0)
355  {if (sem_init(&h_semaphore, 0, semval))
356  {throw "sem_init() failed";}
357  }
358  ~XrdSysSemaphore() {if (sem_destroy(&h_semaphore))
359  {abort();}
360  }
361 
362 private:
363 
365 };
366 #endif
367 
368 /******************************************************************************/
369 /* X r d S y s T h r e a d */
370 /******************************************************************************/
371 
372 // The C++ standard makes it impossible to link extern "C" methods with C++
373 // methods. Thus, making a full thread object is nearly impossible. So, this
374 // object is used as the thread manager. Since it is static for all intense
375 // and purposes, one does not need to create an instance of it.
376 //
377 
378 // Options to Run()
379 //
380 // BIND creates threads that are bound to a kernel thread.
381 //
382 #define XRDSYSTHREAD_BIND 0x001
383 
384 // HOLD creates a thread that needs to be joined to get its ending value.
385 // Otherwise, a detached thread is created.
386 //
387 #define XRDSYSTHREAD_HOLD 0x002
388 
390 {
391 public:
392 
393 static int Cancel(pthread_t tid) {return pthread_cancel(tid);}
394 
395 static int Detach(pthread_t tid) {return pthread_detach(tid);}
396 
397 
398 static int SetCancelOff() {
399  return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
400  };
401 
402 static int Join(pthread_t tid, void **ret) {
403  return pthread_join(tid, ret);
404  };
405 
406 static int SetCancelOn() {
407  return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
408  };
409 
410 static int SetCancelAsynchronous() {
411  return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
412  };
413 
414 static int SetCancelDeferred() {
415  return pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
416  };
417 
418 static void CancelPoint() {
419  pthread_testcancel();
420  };
421 
422 
423 static pthread_t ID(void) {return pthread_self();}
424 
425 static int Kill(pthread_t tid) {return pthread_cancel(tid);}
426 
427 static unsigned long Num(void);
428 
429 static int Run(pthread_t *, void *(*proc)(void *), void *arg,
430  int opts=0, const char *desc = 0);
431 
432 static int Same(pthread_t t1, pthread_t t2)
433  {return pthread_equal(t1, t2);}
434 
435 static void setDebug(XrdSysError *erp) {eDest = erp;}
436 
437 static void setStackSize(size_t stsz) {stackSize = stsz;}
438 
439 static int Signal(pthread_t tid, int snum)
440  {return pthread_kill(tid, snum);}
441 
442 static int Wait(pthread_t tid);
443 
446 
447 private:
449 static size_t stackSize;
450 };
451 #endif
XrdSysRWLockHelper(XrdSysRWLock &l, bool rd=1)
Definition: XrdSysPthread.hh:286
void UnLock()
Definition: XrdSysPthread.hh:116
XrdSysMutex * mtx
Definition: XrdSysPthread.hh:214
Definition: XrdSysPthread.hh:168
XrdSysCondVar(int relm=1, const char *cid=0)
Definition: XrdSysPthread.hh:75
pthread_cond_t cvar
Definition: XrdSysPthread.hh:86
void UnLock()
Definition: XrdSysPthread.hh:278
void ReadLock(int &status)
Definition: XrdSysPthread.hh:240
Definition: XrdSysPthread.hh:224
sem_t h_semaphore
Definition: XrdSysPthread.hh:364
pthread_rwlock_t lock
Definition: XrdSysPthread.hh:256
XrdSysRWLock * lck
Definition: XrdSysPthread.hh:294
int CondWait()
Definition: XrdSysPthread.hh:336
static void setDebug(XrdSysError *erp)
Definition: XrdSysPthread.hh:435
static int Kill(pthread_t tid)
Definition: XrdSysPthread.hh:425
void ReInitialize()
Definition: XrdSysPthread.hh:248
void UnLock()
Definition: XrdSysPthread.hh:201
static int Detach(pthread_t tid)
Definition: XrdSysPthread.hh:395
void ReadLock()
Definition: XrdSysPthread.hh:237
void Signal()
Definition: XrdSysPthread.hh:59
void Wait()
Definition: XrdSysPthread.hh:348
XrdSysRWLock()
Definition: XrdSysPthread.hh:245
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
int relMutex
Definition: XrdSysPthread.hh:88
Definition: XrdSysPthread.hh:389
Definition: XrdSysError.hh:89
pthread_mutex_t cmut
Definition: XrdSysPthread.hh:87
static int Cancel(pthread_t tid)
Definition: XrdSysPthread.hh:393
~XrdSysMutex()
Definition: XrdSysPthread.hh:154
static int Signal(pthread_t tid, int snum)
Definition: XrdSysPthread.hh:439
Definition: XrdSysPthread.hh:140
void Lock(XrdSysMutex *Mutex)
Definition: XrdSysPthread.hh:193
void Lock(XrdSysRWLock *lock, bool rd=1)
Definition: XrdSysPthread.hh:269
void WriteLock()
Definition: XrdSysPthread.hh:238
Definition: XrdSysPthread.hh:265
XrdSysRWLockHelper(XrdSysRWLock *l=0, bool rd=1)
Definition: XrdSysPthread.hh:280
static void setStackSize(size_t stsz)
Definition: XrdSysPthread.hh:437
static int Wait(pthread_t tid)
Definition: XrdSysPthread.hh:53
void Post()
Definition: XrdSysPthread.hh:344
int CondReadLock()
Definition: XrdSysPthread.hh:228
pthread_mutex_t cs
Definition: XrdSysPthread.hh:158
Definition: XrdSysPthread.hh:332
static void CancelPoint()
Definition: XrdSysPthread.hh:418
int CondWriteLock()
Definition: XrdSysPthread.hh:232
static pthread_t ID(void)
Definition: XrdSysPthread.hh:423
~XrdSysThread()
Definition: XrdSysPthread.hh:445
~XrdSysRWLock()
Definition: XrdSysPthread.hh:246
void Lock(XrdSysCondVar *CndVar)
Definition: XrdSysPthread.hh:108
static int SetCancelDeferred()
Definition: XrdSysPthread.hh:414
void Broadcast()
Definition: XrdSysPthread.hh:64
Definition: XrdSysPthread.hh:104
~XrdSysCondVarHelper()
Definition: XrdSysPthread.hh:127
XrdSysThread()
Definition: XrdSysPthread.hh:444
static int Join(pthread_t tid, void **ret)
Definition: XrdSysPthread.hh:402
void Lock()
Definition: XrdSysPthread.hh:149
static int SetCancelAsynchronous()
Definition: XrdSysPthread.hh:410
~XrdSysMutexHelper()
Definition: XrdSysPthread.hh:212
~XrdSysRWLockHelper()
Definition: XrdSysPthread.hh:292
int ReInitRecMutex()
~XrdSysSemaphore()
Definition: XrdSysPthread.hh:358
XrdSysCondVarHelper(XrdSysCondVar &CndVar)
Definition: XrdSysPthread.hh:122
const char * condID
Definition: XrdSysPthread.hh:89
int CondLock()
Definition: XrdSysPthread.hh:144
void WriteLock(int &status)
Definition: XrdSysPthread.hh:241
int WaitMS(int msec)
void UnLock()
Definition: XrdSysPthread.hh:69
static int Same(pthread_t t1, pthread_t t2)
Definition: XrdSysPthread.hh:432
XrdSysMutex()
Definition: XrdSysPthread.hh:153
static int SetCancelOn()
Definition: XrdSysPthread.hh:406
XrdSysSemaphore(int semval=1, const char *=0)
Definition: XrdSysPthread.hh:354
static int SetCancelOff()
Definition: XrdSysPthread.hh:398
void UnLock()
Definition: XrdSysPthread.hh:151
static XrdSysError * eDest
Definition: XrdSysPthread.hh:448
XrdSysCondVarHelper(XrdSysCondVar *CndVar=0)
Definition: XrdSysPthread.hh:118
XrdSysMutexHelper(XrdSysMutex *mutex=0)
Definition: XrdSysPthread.hh:203
XrdSysMutexHelper(XrdSysMutex &mutex)
Definition: XrdSysPthread.hh:207
void UnLock()
Definition: XrdSysPthread.hh:243
static size_t stackSize
Definition: XrdSysPthread.hh:449
Definition: XrdSysPthread.hh:189
~XrdSysCondVar()
Definition: XrdSysPthread.hh:81
void Lock()
Definition: XrdSysPthread.hh:57
XrdSysCondVar * cnd
Definition: XrdSysPthread.hh:129
static unsigned long Num(void)