xtd 0.2.0
semaphore.h
Go to the documentation of this file.
1 #pragma once
4 #if defined(__cpp_lib_semaphore) || __cplusplus >= 202002l
6 #include <semaphore>
7 #else
8 #include <condition_variable>
9 #include <cstdint>
10 #include <cstddef>
11 #include <limits>
12 #include <mutex>
13 
14 namespace std {
15  template<std::ptrdiff_t least_max_value = std::numeric_limits<std::ptrdiff_t>::max()>
16  class counting_semaphore {
17  public:
18  static constexpr std::ptrdiff_t max() noexcept {return least_max_value;}
19  explicit counting_semaphore(std::ptrdiff_t desired = 0) : count_(desired) {}
20  counting_semaphore(const counting_semaphore&) = delete;
21 
22  void acquire() {
23  std::unique_lock<std::mutex> lock(mutex_);
24  while (count_ <= 0) {
25  condition_.wait(lock);
26  }
27  --count_;
28  }
29 
30  bool try_acquire() noexcept {
31  std::unique_lock<std::mutex> lock(mutex_);
32  if (count_ > 0) {
33  --count_;
34  return true;
35  }
36  return false;
37  }
38 
39  bool try_acquire_for(const std::chrono::milliseconds& duration) {
40  std::unique_lock<std::mutex> lock(mutex_);
41  if (condition_.wait_for(lock, duration, [this]() { return count_ > 0; })) {
42  --count_;
43  return true;
44  }
45  return false;
46  }
47 
48  template< class clock_t, class duration_t >
49  bool try_acquire_until(const std::chrono::time_point<clock_t, duration_t>& timeout_time) {
50  return try_acquire_until(timeout_time, [this] {return count_ > 0;});
51  }
52 
53  template< class clock_t, class duration_t, class predicate_t >
54  bool try_acquire_until(const std::chrono::time_point<clock_t, duration_t>& timeout_time, predicate_t stop_waiting) {
55  std::unique_lock<std::mutex> lock(mutex_);
56  if (condition_.wait_until(lock, timeout_time, stop_waiting)) {
57  --count_;
58  return true;
59  }
60  return false;
61  }
62 
63  void release(std::ptrdiff_t update = 1) {
64  std::lock_guard<std::mutex> lock(mutex_);
65  for (std::ptrdiff_t index = 0; index < update; ++index) {
66  ++count_;
67  condition_.notify_one();
68  }
69  }
70 
71  std::ptrdiff_t available() const {
72  std::lock_guard<std::mutex> lock(mutex_);
73  return count_;
74  }
75 
76  private:
77  mutable std::mutex mutex_;
78  std::condition_variable condition_;
79  std::ptrdiff_t count_;
80  };
81 
82  using binary_semaphore = std::counting_semaphore<1>;
83 }
84 #endif
85 
Build type release.
xtd::threading::lock_guard lock
Provides a mechanism that synchronizes access to objects with xtd::threading::monitor.
Definition: lock.h:22