2 // detail/std_event.hpp
3 // ~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_DETAIL_STD_EVENT_HPP
12 #define BOOST_ASIO_DETAIL_STD_EVENT_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
20 #if defined(BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR)
23 #include <condition_variable>
24 #include <boost/asio/detail/assert.hpp>
25 #include <boost/asio/detail/noncopyable.hpp>
27 #include <boost/asio/detail/push_options.hpp>
48 // Signal the event. (Retained for backward compatibility.)
49 template <typename Lock>
50 void signal(Lock& lock)
52 this->signal_all(lock);
55 // Signal all waiters.
56 template <typename Lock>
57 void signal_all(Lock& lock)
59 BOOST_ASIO_ASSERT(lock.locked());
65 // Unlock the mutex and signal one waiter.
66 template <typename Lock>
67 void unlock_and_signal_one(Lock& lock)
69 BOOST_ASIO_ASSERT(lock.locked());
71 bool have_waiters = (state_ > 1);
77 // If there's a waiter, unlock the mutex and signal it.
78 template <typename Lock>
79 bool maybe_unlock_and_signal_one(Lock& lock)
81 BOOST_ASIO_ASSERT(lock.locked());
93 template <typename Lock>
94 void clear(Lock& lock)
96 BOOST_ASIO_ASSERT(lock.locked());
98 state_ &= ~std::size_t(1);
101 // Wait for the event to become signalled.
102 template <typename Lock>
103 void wait(Lock& lock)
105 BOOST_ASIO_ASSERT(lock.locked());
106 unique_lock_adapter u_lock(lock);
107 while ((state_ & 1) == 0)
110 cond_.wait(u_lock.unique_lock_);
114 // Timed wait for the event to become signalled.
115 template <typename Lock>
116 bool wait_for_usec(Lock& lock, long usec)
118 BOOST_ASIO_ASSERT(lock.locked());
119 unique_lock_adapter u_lock(lock);
120 if ((state_ & 1) == 0)
123 cond_.wait_for(u_lock.unique_lock_, std::chrono::microseconds(usec));
125 return (state_ & 1) != 0;
129 // Helper class to temporarily adapt a scoped_lock into a unique_lock so that
130 // it can be passed to std::condition_variable::wait().
131 struct unique_lock_adapter
133 template <typename Lock>
134 explicit unique_lock_adapter(Lock& lock)
135 : unique_lock_(lock.mutex().mutex_, std::adopt_lock)
139 ~unique_lock_adapter()
141 unique_lock_.release();
144 std::unique_lock<std::mutex> unique_lock_;
147 // Helper to increment and decrement the state to track outstanding waiters.
151 explicit waiter(std::size_t& state)
166 std::condition_variable cond_;
170 } // namespace detail
174 #include <boost/asio/detail/pop_options.hpp>
176 #endif // defined(BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR)
178 #endif // BOOST_ASIO_DETAIL_STD_EVENT_HPP