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