RAUL  0.8.0
Semaphore.hpp
1 /* This file is part of Raul.
2  * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
3  *
4  * Raul is free software; you can redistribute it and/or modify it under the
5  * terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * Raul is distributed in the hope that it will be useful, but WITHOUT ANY
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16  */
17 
18 #ifndef RAUL_SEMAPHORE_HPP
19 #define RAUL_SEMAPHORE_HPP
20 
21 #ifdef __APPLE__
22 #include <limits.h>
23 #include <CoreServices/CoreServices.h>
24 #else
25 #include <semaphore.h>
26 #endif
27 
28 #include <boost/utility.hpp>
29 
30 namespace Raul {
31 
32 
37 class Semaphore : boost::noncopyable {
38 public:
39  inline Semaphore(unsigned int initial) {
40  #ifdef __APPLE__
41  MPCreateSemaphore(UINT_MAX, initial, &_sem);
42  #else
43  sem_init(&_sem, 0, initial);
44  #endif
45  }
46 
47  inline ~Semaphore() {
48  #ifdef __APPLE__
49  MPDeleteSemaphore(_sem);
50  #else
51  sem_destroy(&_sem);
52  #endif
53  }
54 
59  inline void reset(unsigned int initial) {
60  #ifdef __APPLE__
61  MPDeleteSemaphore(_sem);
62  MPCreateSemaphore(UINT_MAX, initial, &_sem);
63  #else
64  sem_destroy(&_sem);
65  sem_init(&_sem, 0, initial);
66  #endif
67  }
68 
73  inline void post() {
74  #ifdef __APPLE__
75  MPSignalSemaphore(_sem);
76  #else
77  sem_post(&_sem);
78  #endif
79  }
80 
85  inline void wait() {
86  #ifdef __APPLE__
87  MPWaitOnSemaphore(_sem, kDurationForever);
88  #else
89  /* Note that sem_wait always returns 0 in practice, except in
90  gdb (at least), where it returns nonzero, so the while is
91  necessary (and is the correct/safe solution in any case).
92  */
93  while (sem_wait(&_sem) != 0) {}
94  #endif
95  }
96 
103  inline bool try_wait() {
104  #ifdef __APPLE__
105  return MPWaitOnSemaphore(_sem, kDurationImmediate) == noErr;
106  #else
107  return (sem_trywait(&_sem) == 0);
108  #endif
109  }
110 
111 private:
112  #ifdef __APPLE__
113  MPSemaphoreID _sem;
114  #else
115  sem_t _sem;
116  #endif
117 };
118 
119 
120 } // namespace Raul
121 
122 #endif // RAUL_SEMAPHORE_HPP
Raul::Semaphore::try_wait
bool try_wait()
Non-blocking version of wait().
Definition: Semaphore.hpp:103
Raul::Semaphore::wait
void wait()
Wait until count is > 0, then decrement.
Definition: Semaphore.hpp:85
Raul::Semaphore::reset
void reset(unsigned int initial)
Destroy and reset the semaphore to an initial value.
Definition: Semaphore.hpp:59
Raul::Semaphore::post
void post()
Increment (and signal any waiters).
Definition: Semaphore.hpp:73
Raul::Semaphore
Counting semaphore.
Definition: Semaphore.hpp:37