mavtables  0.2.1
MAVLink router and firewall.
semaphore.hpp
Go to the documentation of this file.
1 // MAVLink router and firewall.
2 // Copyright (C) 2017-2018 Michael R. Shannon <mrshannon.aerospace@gmail.com>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 
18 #ifndef SEMAPHORE_HPP_
19 #define SEMAPHORE_HPP_
20 
21 
22 #include <chrono>
23 #include <condition_variable>
24 #include <cstdint>
25 #include <mutex>
26 
27 
28 /** A weak semaphore implementation.
29  *
30  * \note This uses a different naming scheme than the rest of this project
31  * because it is intended to have the same feel as the standard library.
32  *
33  * \note This semaphore implementation is based on
34  * https://gist.github.com/sguzman/9594227
35  */
36 class semaphore
37 {
38  public:
39  semaphore(const semaphore &other) = delete;
40  semaphore(semaphore &&other) = delete;
41  semaphore(size_t initial_value = 0);
42  void notify();
43  void wait();
44  template<class Rep, class Period>
45  bool wait_for(const std::chrono::duration<Rep, Period> &rel_time);
46  template<class Clock, class Duration>
47  bool wait_until(
48  const std::chrono::time_point<Clock, Duration> &timeout_time);
49  semaphore &operator=(const semaphore &other) = delete;
50  semaphore &operator=(semaphore &&other) = delete;
51 
52  private:
53  size_t value_;
54  std::mutex mutex_;
55  std::condition_variable cv_;
56 };
57 
58 
59 /** Wait on the semaphore, or a given duration timeout.
60  *
61  * \param rel_time The duration of the timeout.
62  * \retval true The semaphore has been successfully decremented.
63  * \retval false The semaphore timed out.
64  */
65 template<class Rep, class Period>
66 bool semaphore::wait_for(const std::chrono::duration<Rep, Period> &rel_time)
67 {
68  std::unique_lock<std::mutex> lock(mutex_);
69  bool result = cv_.wait_for(lock, rel_time, [this]()
70  {
71  return value_ > 0;
72  });
73 
74  if (result)
75  {
76  --value_;
77  }
78 
79  return result;
80 }
81 
82 
83 /** Wait on the semaphore, or a given timepoint timeout.
84  *
85  * \param timeout_time The timepoint for the timeout.
86  * \retval true The semaphore has been successfully decremented.
87  * \retval false The semaphore timed out.
88  */
89 template<class Clock, class Duration>
91  const std::chrono::time_point<Clock, Duration> &timeout_time)
92 {
93  std::unique_lock<std::mutex> lock(mutex_);
94  bool result = cv_.wait_until(lock, timeout_time, [this]()
95  {
96  return value_ > 0;
97  });
98 
99  if (result)
100  {
101  --value_;
102  }
103 
104  return result;
105 }
106 
107 
108 #endif // SEMAPHORE_HPP_
void wait()
Definition: semaphore.cpp:52
bool wait_until(const std::chrono::time_point< Clock, Duration > &timeout_time)
Definition: semaphore.hpp:90
void notify()
Definition: semaphore.cpp:38
semaphore(const semaphore &other)=delete
semaphore & operator=(const semaphore &other)=delete
bool wait_for(const std::chrono::duration< Rep, Period > &rel_time)
Definition: semaphore.hpp:66