nidas  v1.2-1520
ThreadSupport.h
Go to the documentation of this file.
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4; -*-
2 // vim: set shiftwidth=4 softtabstop=4 expandtab:
3 /*
4  ********************************************************************
5  ** NIDAS: NCAR In-situ Data Acquistion Software
6  **
7  ** 2006, Copyright University Corporation for Atmospheric Research
8  **
9  ** This program is free software; you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation; either version 2 of the License, or
12  ** (at your option) any later version.
13  **
14  ** This program is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** The LICENSE.txt file accompanying this software contains
20  ** a copy of the GNU General Public License. If it is not found,
21  ** write to the Free Software Foundation, Inc.,
22  ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  **
24  ********************************************************************
25 */
26 
27 #ifndef NIDAS_UTIL_THREADSUPPORT_H
28 #define NIDAS_UTIL_THREADSUPPORT_H
29 
30 #include <pthread.h>
31 #include <semaphore.h>
32 #include <string>
33 #include <iostream>
34 
35 #include "Exception.h"
36 
37 namespace nidas { namespace util {
38 
52 {
53 public:
54 
61 
66 
68 
74  void setType(int val) throw(Exception);
75  int getType() const;
76 
77 #ifdef PTHREAD_PRIO_INHERIT
78 
86  void setPriorityCeiling(int val) throw(Exception);
87  int getPriorityCeiling() const;
88 #endif
89 
90 #ifdef PTHREAD_PRIO_INHERIT
91 
96  void setProtocol(int val) throw(Exception);
97  int getProtocol() const;
98 #endif
99 
105  void setPShared(int val) throw(Exception);
106  int getPShared() const;
107 
108 
109  pthread_mutexattr_t* ptr()
110  {
111  return &_attrs;
112  }
113 private:
114  pthread_mutexattr_t _attrs;
115 };
116 
123 {
124 public:
126 
131 
133 
139  void setPShared(int val) throw(Exception);
140  int getPShared() const;
141 
142 
143  pthread_rwlockattr_t* ptr()
144  {
145  return &_attrs;
146  }
147 private:
148  pthread_rwlockattr_t _attrs;
149 };
150 
154 class Mutex
155 {
156 
157 public:
171  explicit Mutex(int type=PTHREAD_MUTEX_DEFAULT) throw();
172 
181  Mutex(const MutexAttributes& attr) throw(Exception);
182 
188  Mutex(const Mutex& x) throw();
189 
194  ~Mutex();
195 
206  void lock() throw(Exception)
207  {
208  int res;
209  if((res = ::pthread_mutex_lock(&_p_mutex)))
210  throw Exception("Mutex::lock",res);
211  }
212 
218  void unlock() throw(Exception)
219  {
220  int res;
221  if ((res = ::pthread_mutex_unlock(&_p_mutex)))
222  throw Exception("Mutex::unlock",res);
223  }
224 
228  pthread_mutex_t* ptr();
229 
230 private:
234  Mutex& operator=(const Mutex&);
235 
236  pthread_mutex_t _p_mutex;
237 
239 
240 };
241 
245 class Cond
246 {
247 
248 public:
249 
254  Cond() throw();
255 
259  Cond (const Cond &x) throw();
260 
266  ~Cond();
267 
290  void lock() throw(Exception)
291  {
292  _mutex.lock();
293  }
294 
299  void unlock() throw(Exception)
300  {
301  _mutex.unlock();
302  }
303 
310  void signal() throw(Exception)
311  {
312  // only fails with EINVAL if _p_cond is not initialized.
313  int res;
314  if ((res = ::pthread_cond_signal (&_p_cond)))
315  throw Exception("Cond::signal",res);
316  }
317 
322  void broadcast()
323  {
324  int res;
325  // only fails with EINVAL if _p_cond is not initialized.
326  if ((res = ::pthread_cond_broadcast (&_p_cond)))
327  throw Exception("Cond::broadcast",res);
328  }
329 
341  void wait() throw(Exception);
342 
343 private:
347  Cond &operator= (const Cond &);
348 
349  pthread_cond_t _p_cond;
350 
352 
353 };
354 
358 class RWLock
359 {
360 
361 public:
362 
367  RWLock() throw();
368 
369  RWLock(const RWLockAttributes& attr) throw(Exception);
373  RWLock(const RWLock& x) throw();
374 
379  ~RWLock();
380 
385  void rdlock() throw(Exception)
386  {
387  int res;
388  if ((res = ::pthread_rwlock_rdlock(&_p_rwlock)))
389  throw Exception("RWLock::rdlock",res);
390  }
391 
396  void wrlock() throw(Exception)
397  {
398  int res;
399  if ((res = ::pthread_rwlock_wrlock(&_p_rwlock)))
400  throw Exception("RWLock::wrlock",res);
401  }
402 
407  void unlock() throw(Exception)
408  {
409  int res;
410  if ((res = ::pthread_rwlock_unlock(&_p_rwlock)))
411  throw Exception("RWLock::unlock",res);
412  }
413 
417  pthread_rwlock_t* ptr();
418 
419 private:
423  RWLock& operator=(const RWLock&);
424 
425  pthread_rwlock_t _p_rwlock;
426 
428 
429 };
430 
434 class Semaphore
435 {
436 public:
437 
441  Semaphore():_sem()
442  {
443  sem_init(&_sem,0,0);
444  }
445 
446 
451  {
452  sem_destroy(&_sem);
453  }
454 
459  void wait() throw()
460  {
461  sem_wait(&_sem);
462  }
463 
469  bool check() throw()
470  {
471  return sem_trywait(&_sem) == 0;
472  }
473 
477  void post() throw()
478  {
479  // man page for sem_post:
480  // return value of sem_post can be < 0, in which case errno is ERANGE:
481  // the semaphore value would exceed SEM_VALUE_MAX
482  // (the semaphore count is left unchanged in this case)
483  // Hmmm: do we throw an exception for this pathelogical situation,
484  // which compels users to have to catch it? Naa.
485  sem_post(&_sem);
486  }
487 
491  int getValue() throw()
492  {
493  int val;
494  sem_getvalue(&_sem,&val);
495  return val;
496  }
497 
501  sem_t* ptr() { return &_sem; }
502 
503 private:
504 
508  Semaphore(const Semaphore&);
509 
513  Semaphore& operator=(const Semaphore&);
514 
515  sem_t _sem;
516 };
517 
519 {
520 
521 public:
522  Multisync(int n);
523  void sync();
524  void sync(std::string& msg);
525  void init(); // to reinitialize
526 
527 private:
529  int _n;
530  int _count;
531  int debug;
532 
533 };
534 
535 
545 {
546 public:
547 
554  Synchronized (Cond &cond_) throw(Exception): mutexp(0),condp(&cond_)
555  {
556  condp->lock();
557  }
558  Synchronized (Mutex &mutex_) throw(Exception): mutexp(&mutex_),condp(0)
559  {
560  mutexp->lock();
561  }
562 
567  {
568  if (condp) condp->unlock();
569  else if (mutexp) mutexp->unlock();
570  }
571 
572 private:
575 
576 private:
577  Synchronized (const Synchronized &);
579 
580 };
581 
590 class Autolock
591 {
592 public:
593 
597  Autolock (Cond &cond) throw(Exception): _mutexp(0),_condp(&cond)
598  {
599  cond.lock();
600  }
604  Autolock (Mutex &mutex) throw(Exception): _mutexp(&mutex),_condp(0)
605  {
606  mutex.lock();
607  }
608 
613  {
614  if (_condp) _condp->unlock();
615  else if (_mutexp) _mutexp->unlock();
616  }
617 
618  private:
621 
622  private:
623  Autolock (const Autolock &);
624  Autolock &operator= (const Autolock &);
625 
626 };
627 
632 {
633 public:
634 
638  AutoRdLock (RWLock &rwlock) throw(Exception): _rwlock(rwlock)
639  {
640  _rwlock.rdlock();
641  }
642 
647  {
648  _rwlock.unlock();
649  }
650 
651 private:
653 
654 private:
655  AutoRdLock (const Autolock &);
656  AutoRdLock &operator= (const Autolock &);
657 };
658 
663 {
664 public:
665 
669  AutoWrLock (RWLock &rwlock) throw(Exception): _rwlock(rwlock)
670  {
671  _rwlock.wrlock();
672  }
673 
678  {
679  _rwlock.unlock();
680  }
681 
682 private:
684 
685 private:
686  AutoWrLock (const Autolock &);
687  AutoWrLock &operator= (const Autolock &);
688 };
689 
690 
691 }} // namespace nidas namespace util
692 
693 #endif
694 
void signal()
Unblock at least one thread waiting on the condition variable.
Definition: ThreadSupport.h:310
Synchronized is used a simple guard object for critical sections.
Definition: ThreadSupport.h:544
int _n
Definition: ThreadSupport.h:529
Autolock(Cond &cond)
Construct the guard object and lock() the lock.
Definition: ThreadSupport.h:597
Semaphore()
Constructor.
Definition: ThreadSupport.h:441
~Cond()
Destruct a Cond.
Definition: ThreadSupport.cc:281
~MutexAttributes()
Definition: ThreadSupport.cc:66
void wrlock()
Acquire a write lock.
Definition: ThreadSupport.h:396
Synchronized(Cond &cond_)
Construct the guard object and lock() the lock.
Definition: ThreadSupport.h:554
void lock()
Lock the mutex associated with the condition variable.
Definition: ThreadSupport.h:290
~Autolock()
On destruction, unlock the lock.
Definition: ThreadSupport.h:612
AutoRdLock(RWLock &rwlock)
Construct the guard object and lock() the lock.
Definition: ThreadSupport.h:638
pthread_mutex_t _p_mutex
Definition: ThreadSupport.h:236
sem_t _sem
Definition: ThreadSupport.h:515
void broadcast()
Restart all threads waiting on the condition variable.
Definition: ThreadSupport.h:322
void post()
Atomically increment the Semaphore.
Definition: ThreadSupport.h:477
~AutoWrLock()
On destruction, unlock the lock.
Definition: ThreadSupport.h:677
void unlock()
Unlock the RWLock.
Definition: ThreadSupport.h:407
Mutex * _mutexp
Definition: ThreadSupport.h:619
~Mutex()
Destruct a Mutex.
Definition: ThreadSupport.cc:240
RWLockAttributes _attrs
Definition: ThreadSupport.h:427
A C++ wrapper for a POSIX rwlock attributes.
Definition: ThreadSupport.h:122
Cond * _condp
Definition: ThreadSupport.h:620
void setPShared(int val)
Set the mutex pshared attribute, one of PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED.
Definition: ThreadSupport.cc:144
Synchronized(Mutex &mutex_)
Definition: ThreadSupport.h:558
pthread_rwlockattr_t _attrs
Definition: ThreadSupport.h:148
Autolock for acquiring/releasing a write lock on a RWLock.
Definition: ThreadSupport.h:662
int _count
Definition: ThreadSupport.h:530
int debug
Definition: ThreadSupport.h:531
Cond & operator=(const Cond &)
No assignment allowed.
RWLockAttributes()
Definition: ThreadSupport.cc:167
pthread_mutex_t * ptr()
Get the pointer to the pthread_mutex_t.
Definition: ThreadSupport.cc:258
Mutex & operator=(const Mutex &)
No assignment allowed.
void wait()
Suspend calling thread until the semaphore has a non-zero count.
Definition: ThreadSupport.h:459
Mutex * mutexp
Definition: ThreadSupport.h:573
Mutex _mutex
Definition: ThreadSupport.h:351
Mutex(int type=PTHREAD_MUTEX_DEFAULT)
Construct a POSIX mutex of the given type.
Definition: ThreadSupport.cc:212
Definition: Exception.h:35
A C++ wrapper for a POSIX rwlock.
Definition: ThreadSupport.h:358
pthread_cond_t _p_cond
Definition: ThreadSupport.h:349
~RWLockAttributes()
Definition: ThreadSupport.cc:184
RWLock & _rwlock
Definition: ThreadSupport.h:683
A C++ wrapper for a POSIX mutex attributes.
Definition: ThreadSupport.h:51
void rdlock()
Acquire a read lock.
Definition: ThreadSupport.h:385
void lock()
Lock the Mutex.
Definition: ThreadSupport.h:206
Definition: ThreadSupport.h:518
Cond()
Construct a POSIX condition variable, with default attributes.
Definition: ThreadSupport.cc:263
int getPShared() const
Definition: ThreadSupport.cc:205
A POSIX semaphore.
Definition: ThreadSupport.h:434
Autolock for acquiring/releasing a read lock on a RWLock.
Definition: ThreadSupport.h:631
~Synchronized()
On destruction, unlock the lock.
Definition: ThreadSupport.h:566
void setPShared(int val)
Set the mutex pshared attribute, one of PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED.
Definition: ThreadSupport.cc:189
~Semaphore()
Destructor.
Definition: ThreadSupport.h:450
MutexAttributes _attrs
Definition: ThreadSupport.h:238
Cond _co
Definition: ThreadSupport.h:528
void wait()
Wait on the condition variable.
Definition: ThreadSupport.cc:306
pthread_mutexattr_t _attrs
Definition: ThreadSupport.h:114
RWLock & _rwlock
Definition: ThreadSupport.h:652
Autolock(Mutex &mutex)
Construct the guard object and lock() the lock.
Definition: ThreadSupport.h:604
pthread_mutexattr_t * ptr()
Definition: ThreadSupport.h:109
AutoWrLock(RWLock &rwlock)
Construct the guard object and lock() the lock.
Definition: ThreadSupport.h:669
void setType(int val)
Set the mutex type attribute, one of PTHREAD_MUTEX_NORMAL,PTHREAD_MUTEX_ERRORCHECK,PTHREAD_MUTEX_RECURSIVE, or PTHREAD_MUTEX_DEFAULT.
Definition: ThreadSupport.cc:71
pthread_rwlock_t _p_rwlock
Definition: ThreadSupport.h:425
A wrapper class for a Posix condition variable.
Definition: ThreadSupport.h:245
int getValue()
Get the current value of the Semaphore.
Definition: ThreadSupport.h:491
int getPShared() const
Definition: ThreadSupport.cc:160
sem_t * ptr()
Get the pointer to the semaphore (for legacy C code).
Definition: ThreadSupport.h:501
~AutoRdLock()
On destruction, unlock the lock.
Definition: ThreadSupport.h:646
MutexAttributes()
Create instance with default values, type = PTHREAD_MUTEX_DEFAULT, priority protocol=PTHREAD_PRIO_NON...
Definition: ThreadSupport.cc:42
void unlock()
Unlock the mutex associated with the condition variable.
Definition: ThreadSupport.h:299
A C++ wrapper for a POSIX mutex.
Definition: ThreadSupport.h:154
bool check()
Do a non-blocking wait on the Semaphore.
Definition: ThreadSupport.h:469
pthread_rwlockattr_t * ptr()
Definition: ThreadSupport.h:143
int getType() const
Definition: ThreadSupport.cc:87
void unlock()
Unlock the Mutex.
Definition: ThreadSupport.h:218
Cond * condp
Definition: ThreadSupport.h:574
Autolock is used a simple guard object for critical sections.
Definition: ThreadSupport.h:590