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 UnLock() {pthread_rwlock_unlock(&lock);}
241 
242  XrdSysRWLock() {pthread_rwlock_init(&lock, NULL);}
243  ~XrdSysRWLock() {pthread_rwlock_destroy(&lock);}
244 
245 inline void ReInitialize()
246 {
247  pthread_rwlock_destroy(&lock);
248  pthread_rwlock_init(&lock, NULL);
249 }
250 
251 protected:
252 
253 pthread_rwlock_t lock;
254 };
255 
256 /******************************************************************************/
257 /* X r d S y s W R L o c k H e l p e r */
258 /******************************************************************************/
259 
260 // XrdSysWRLockHelper : helper class for XrdSysRWLock
261 
263 {
264 public:
265 
266 inline void Lock(XrdSysRWLock *lock, bool rd = 1)
267  {if (lck) {if (lck != lock) lck->UnLock();
268  else return;
269  }
270  if (rd) lock->ReadLock();
271  else lock->WriteLock();
272  lck = lock;
273  };
274 
275 inline void UnLock() {if (lck) {lck->UnLock(); lck = 0;}}
276 
277  XrdSysRWLockHelper(XrdSysRWLock *l=0, bool rd = 1)
278  { if (l) {if (rd) l->ReadLock();
279  else l->WriteLock();
280  }
281  lck = l;
282  }
284  { if (rd) l.ReadLock();
285  else l.WriteLock();
286  lck = &l;
287  }
288 
290 private:
292 };
293 
294 /******************************************************************************/
295 /* X r d S y s S e m a p h o r e */
296 /******************************************************************************/
297 
298 // XrdSysSemaphore implements the classic counting semaphore. The methods
299 // should be self-evident. Note that on certain platforms
300 // semaphores need to be implemented based on condition
301 // variables since no native implementation is available.
302 
303 #ifdef __APPLE__
304 class XrdSysSemaphore
305 {
306 public:
307 
308  int CondWait();
309 
310  void Post();
311 
312  void Wait();
313 
314 static void CleanUp(void *semVar);
315 
316  XrdSysSemaphore(int semval=1,const char *cid=0) : semVar(0, cid)
317  {semVal = semval; semWait = 0;}
318  ~XrdSysSemaphore() {}
319 
320 private:
321 
322 XrdSysCondVar semVar;
323 int semVal;
324 int semWait;
325 };
326 
327 #else
328 
330 {
331 public:
332 
333 inline int CondWait()
334  {while(sem_trywait( &h_semaphore ))
335  {if (errno == EAGAIN) return 0;
336  if (errno != EINTR) { throw "sem_CondWait() failed";}
337  }
338  return 1;
339  }
340 
341 inline void Post() {if (sem_post(&h_semaphore))
342  {throw "sem_post() failed";}
343  }
344 
345 inline void Wait() {while (sem_wait(&h_semaphore))
346  {if (EINTR != errno)
347  {throw "sem_wait() failed";}
348  }
349  }
350 
351  XrdSysSemaphore(int semval=1, const char * =0)
352  {if (sem_init(&h_semaphore, 0, semval))
353  {throw "sem_init() failed";}
354  }
355  ~XrdSysSemaphore() {if (sem_destroy(&h_semaphore))
356  {abort();}
357  }
358 
359 private:
360 
362 };
363 #endif
364 
365 /******************************************************************************/
366 /* X r d S y s T h r e a d */
367 /******************************************************************************/
368 
369 // The C++ standard makes it impossible to link extern "C" methods with C++
370 // methods. Thus, making a full thread object is nearly impossible. So, this
371 // object is used as the thread manager. Since it is static for all intense
372 // and purposes, one does not need to create an instance of it.
373 //
374 
375 // Options to Run()
376 //
377 // BIND creates threads that are bound to a kernel thread.
378 //
379 #define XRDSYSTHREAD_BIND 0x001
380 
381 // HOLD creates a thread that needs to be joined to get its ending value.
382 // Otherwise, a detached thread is created.
383 //
384 #define XRDSYSTHREAD_HOLD 0x002
385 
387 {
388 public:
389 
390 static int Cancel(pthread_t tid) {return pthread_cancel(tid);}
391 
392 static int Detach(pthread_t tid) {return pthread_detach(tid);}
393 
394 
395 static int SetCancelOff() {
396  return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
397  };
398 
399 static int Join(pthread_t tid, void **ret) {
400  return pthread_join(tid, ret);
401  };
402 
403 static int SetCancelOn() {
404  return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
405  };
406 
407 static int SetCancelAsynchronous() {
408  return pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
409  };
410 
411 static int SetCancelDeferred() {
412  return pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
413  };
414 
415 static void CancelPoint() {
416  pthread_testcancel();
417  };
418 
419 
420 static pthread_t ID(void) {return pthread_self();}
421 
422 static int Kill(pthread_t tid) {return pthread_cancel(tid);}
423 
424 static unsigned long Num(void);
425 
426 static int Run(pthread_t *, void *(*proc)(void *), void *arg,
427  int opts=0, const char *desc = 0);
428 
429 static int Same(pthread_t t1, pthread_t t2)
430  {return pthread_equal(t1, t2);}
431 
432 static void setDebug(XrdSysError *erp) {eDest = erp;}
433 
434 static void setStackSize(size_t stsz) {stackSize = stsz;}
435 
436 static int Signal(pthread_t tid, int snum)
437  {return pthread_kill(tid, snum);}
438 
439 static int Wait(pthread_t tid);
440 
443 
444 private:
446 static size_t stackSize;
447 };
448 #endif
XrdSysRWLockHelper(XrdSysRWLock &l, bool rd=1)
Definition: XrdSysPthread.hh:283
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:275
Definition: XrdSysPthread.hh:224
sem_t h_semaphore
Definition: XrdSysPthread.hh:361
pthread_rwlock_t lock
Definition: XrdSysPthread.hh:253
XrdSysRWLock * lck
Definition: XrdSysPthread.hh:291
int CondWait()
Definition: XrdSysPthread.hh:333
static void setDebug(XrdSysError *erp)
Definition: XrdSysPthread.hh:432
static int Kill(pthread_t tid)
Definition: XrdSysPthread.hh:422
void ReInitialize()
Definition: XrdSysPthread.hh:245
void UnLock()
Definition: XrdSysPthread.hh:201
static int Detach(pthread_t tid)
Definition: XrdSysPthread.hh:392
void ReadLock()
Definition: XrdSysPthread.hh:237
void Signal()
Definition: XrdSysPthread.hh:59
void Wait()
Definition: XrdSysPthread.hh:345
XrdSysRWLock()
Definition: XrdSysPthread.hh:242
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:386
Definition: XrdSysError.hh:87
pthread_mutex_t cmut
Definition: XrdSysPthread.hh:87
static int Cancel(pthread_t tid)
Definition: XrdSysPthread.hh:390
~XrdSysMutex()
Definition: XrdSysPthread.hh:154
static int Signal(pthread_t tid, int snum)
Definition: XrdSysPthread.hh:436
Definition: XrdSysPthread.hh:140
void Lock(XrdSysMutex *Mutex)
Definition: XrdSysPthread.hh:193
void Lock(XrdSysRWLock *lock, bool rd=1)
Definition: XrdSysPthread.hh:266
void WriteLock()
Definition: XrdSysPthread.hh:238
Definition: XrdSysPthread.hh:262
XrdSysRWLockHelper(XrdSysRWLock *l=0, bool rd=1)
Definition: XrdSysPthread.hh:277
static void setStackSize(size_t stsz)
Definition: XrdSysPthread.hh:434
static int Wait(pthread_t tid)
Definition: XrdSysPthread.hh:53
void Post()
Definition: XrdSysPthread.hh:341
int CondReadLock()
Definition: XrdSysPthread.hh:228
pthread_mutex_t cs
Definition: XrdSysPthread.hh:158
Definition: XrdSysPthread.hh:329
static void CancelPoint()
Definition: XrdSysPthread.hh:415
int CondWriteLock()
Definition: XrdSysPthread.hh:232
static pthread_t ID(void)
Definition: XrdSysPthread.hh:420
~XrdSysThread()
Definition: XrdSysPthread.hh:442
~XrdSysRWLock()
Definition: XrdSysPthread.hh:243
void Lock(XrdSysCondVar *CndVar)
Definition: XrdSysPthread.hh:108
static int SetCancelDeferred()
Definition: XrdSysPthread.hh:411
void Broadcast()
Definition: XrdSysPthread.hh:64
Definition: XrdSysPthread.hh:104
~XrdSysCondVarHelper()
Definition: XrdSysPthread.hh:127
XrdSysThread()
Definition: XrdSysPthread.hh:441
static int Join(pthread_t tid, void **ret)
Definition: XrdSysPthread.hh:399
void Lock()
Definition: XrdSysPthread.hh:149
static int SetCancelAsynchronous()
Definition: XrdSysPthread.hh:407
~XrdSysMutexHelper()
Definition: XrdSysPthread.hh:212
~XrdSysRWLockHelper()
Definition: XrdSysPthread.hh:289
int ReInitRecMutex()
~XrdSysSemaphore()
Definition: XrdSysPthread.hh:355
XrdSysCondVarHelper(XrdSysCondVar &CndVar)
Definition: XrdSysPthread.hh:122
const char * condID
Definition: XrdSysPthread.hh:89
int CondLock()
Definition: XrdSysPthread.hh:144
int WaitMS(int msec)
void UnLock()
Definition: XrdSysPthread.hh:69
static int Same(pthread_t t1, pthread_t t2)
Definition: XrdSysPthread.hh:429
XrdSysMutex()
Definition: XrdSysPthread.hh:153
static int SetCancelOn()
Definition: XrdSysPthread.hh:403
XrdSysSemaphore(int semval=1, const char *=0)
Definition: XrdSysPthread.hh:351
static int SetCancelOff()
Definition: XrdSysPthread.hh:395
void UnLock()
Definition: XrdSysPthread.hh:151
static XrdSysError * eDest
Definition: XrdSysPthread.hh:445
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:240
static size_t stackSize
Definition: XrdSysPthread.hh:446
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)