Realistic 3D camera system
3D camera system components
std_event.hpp
Go to the documentation of this file.
1 //
2 // detail/std_event.hpp
3 // ~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_DETAIL_STD_EVENT_HPP
12 #define ASIO_DETAIL_STD_EVENT_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 
20 #if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)
21 
22 #include <chrono>
23 #include <condition_variable>
24 #include "asio/detail/assert.hpp"
26 
28 
29 namespace asio {
30 namespace detail {
31 
32 class std_event
33  : private noncopyable
34 {
35 public:
36  // Constructor.
37  std_event()
38  : state_(0)
39  {
40  }
41 
42  // Destructor.
43  ~std_event()
44  {
45  }
46 
47  // Signal the event. (Retained for backward compatibility.)
48  template <typename Lock>
49  void signal(Lock& lock)
50  {
51  this->signal_all(lock);
52  }
53 
54  // Signal all waiters.
55  template <typename Lock>
56  void signal_all(Lock& lock)
57  {
58  ASIO_ASSERT(lock.locked());
59  (void)lock;
60  state_ |= 1;
61  cond_.notify_all();
62  }
63 
64  // Unlock the mutex and signal one waiter.
65  template <typename Lock>
66  void unlock_and_signal_one(Lock& lock)
67  {
68  ASIO_ASSERT(lock.locked());
69  state_ |= 1;
70  bool have_waiters = (state_ > 1);
71  lock.unlock();
72  if (have_waiters)
73  cond_.notify_one();
74  }
75 
76  // If there's a waiter, unlock the mutex and signal it.
77  template <typename Lock>
78  bool maybe_unlock_and_signal_one(Lock& lock)
79  {
80  ASIO_ASSERT(lock.locked());
81  state_ |= 1;
82  if (state_ > 1)
83  {
84  lock.unlock();
85  cond_.notify_one();
86  return true;
87  }
88  return false;
89  }
90 
91  // Reset the event.
92  template <typename Lock>
93  void clear(Lock& lock)
94  {
95  ASIO_ASSERT(lock.locked());
96  (void)lock;
97  state_ &= ~std::size_t(1);
98  }
99 
100  // Wait for the event to become signalled.
101  template <typename Lock>
102  void wait(Lock& lock)
103  {
104  ASIO_ASSERT(lock.locked());
105  unique_lock_adapter u_lock(lock);
106  while ((state_ & 1) == 0)
107  {
108  waiter w(state_);
109  cond_.wait(u_lock.unique_lock_);
110  }
111  }
112 
113  // Timed wait for the event to become signalled.
114  template <typename Lock>
115  bool wait_for_usec(Lock& lock, long usec)
116  {
117  ASIO_ASSERT(lock.locked());
118  unique_lock_adapter u_lock(lock);
119  if ((state_ & 1) == 0)
120  {
121  waiter w(state_);
122  cond_.wait_for(u_lock.unique_lock_, std::chrono::microseconds(usec));
123  }
124  return (state_ & 1) != 0;
125  }
126 
127 private:
128  // Helper class to temporarily adapt a scoped_lock into a unique_lock so that
129  // it can be passed to std::condition_variable::wait().
130  struct unique_lock_adapter
131  {
132  template <typename Lock>
133  explicit unique_lock_adapter(Lock& lock)
134  : unique_lock_(lock.mutex().mutex_, std::adopt_lock)
135  {
136  }
137 
138  ~unique_lock_adapter()
139  {
140  unique_lock_.release();
141  }
142 
143  std::unique_lock<std::mutex> unique_lock_;
144  };
145 
146  // Helper to increment and decrement the state to track outstanding waiters.
147  class waiter
148  {
149  public:
150  explicit waiter(std::size_t& state)
151  : state_(state)
152  {
153  state_ += 2;
154  }
155 
156  ~waiter()
157  {
158  state_ -= 2;
159  }
160 
161  private:
162  std::size_t& state_;
163  };
164 
165  std::condition_variable cond_;
166  std::size_t state_;
167 };
168 
169 } // namespace detail
170 } // namespace asio
171 
173 
174 #endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)
175 
176 #endif // ASIO_DETAIL_STD_EVENT_HPP
#define ASIO_ASSERT(expr)
Definition: assert.hpp:29
null_mutex mutex
Definition: mutex.hpp:36
STL namespace.