YARP
Yet Another Robot Platform
Semaphore.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <yarp/os/Semaphore.h>
8 
9 #include <condition_variable>
10 #include <mutex>
11 
13 
15 {
16 public:
17  Private(unsigned int initialCount = 1) :
18  count(initialCount)
19  {
20  }
21 
22  Private(Private&) = delete;
23  Private& operator=(Private&) = delete;
24  virtual ~Private() = default;
25 
26  // blocking wait
27  void wait()
28  {
29  std::unique_lock<std::mutex> lock(mutex);
30  count--;
31  if (count < 0) {
32  cond.wait(lock,
33  [this] { return wakeups > 0; });
34  wakeups--;
35  }
36  }
37 
38  // blocking wait with timeout
39  bool waitWithTimeout(double timeout)
40  {
41  std::unique_lock<std::mutex> lock(mutex);
42  count--;
43  if (count < 0) {
44  std::chrono::duration<double> ctime(timeout);
45  cond.wait_for(lock, ctime, [this] { return wakeups > 0; });
46 
47  if (wakeups <= 0) {
48  count++;
49  return false;
50  }
51  wakeups--;
52  }
53  return true;
54  }
55 
56  // polling wait
57  bool check()
58  {
59  std::unique_lock<std::mutex> lock(mutex);
60  if (count != 0) {
61  count--;
62  return true;
63  }
64  return false;
65  }
66 
67  // increment
68  void post()
69  {
70  std::lock_guard<std::mutex> lock(mutex);
71  count++;
72  if (count <= 0) {
73  wakeups++;
74  cond.notify_one();
75  }
76  }
77 
78 private:
79  std::mutex mutex;
80  std::condition_variable cond;
81  int count;
82  int wakeups{0};
83 };
84 
85 
86 Semaphore::Semaphore(unsigned int initialCount) :
87  mPriv(new Private(initialCount))
88 {
89 }
90 
92 {
93  delete mPriv;
94 }
95 
97 {
98  mPriv->wait();
99 }
100 
101 bool Semaphore::waitWithTimeout(double timeoutInSeconds)
102 {
103  return mPriv->waitWithTimeout(timeoutInSeconds);
104 }
105 
107 {
108  return mPriv->check();
109 }
110 
112 {
113  mPriv->post();
114 }
Private(Private &)=delete
bool waitWithTimeout(double timeout)
Definition: Semaphore.cpp:39
virtual ~Private()=default
Private(unsigned int initialCount=1)
Definition: Semaphore.cpp:17
Private & operator=(Private &)=delete
A class for thread synchronization and mutual exclusion.
Definition: Semaphore.h:26
virtual ~Semaphore()
Destructor.
Definition: Semaphore.cpp:91
bool waitWithTimeout(double timeoutInSeconds)
Try to decrement the counter, even if we must wait - but don't wait forever.
Definition: Semaphore.cpp:101
void wait()
Decrement the counter, even if we must wait to do that.
Definition: Semaphore.cpp:96
bool check()
Decrement the counter, unless that would require waiting.
Definition: Semaphore.cpp:106
void post()
Increment the counter.
Definition: Semaphore.cpp:111