File indexing completed on 2025-01-18 09:28:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_STD_EVENT_HPP
0012 #define BOOST_ASIO_DETAIL_STD_EVENT_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <chrono>
0020 #include <condition_variable>
0021 #include <boost/asio/detail/assert.hpp>
0022 #include <boost/asio/detail/noncopyable.hpp>
0023
0024 #include <boost/asio/detail/push_options.hpp>
0025
0026 namespace boost {
0027 namespace asio {
0028 namespace detail {
0029
0030 class std_event
0031 : private noncopyable
0032 {
0033 public:
0034
0035 std_event()
0036 : state_(0)
0037 {
0038 }
0039
0040
0041 ~std_event()
0042 {
0043 }
0044
0045
0046 template <typename Lock>
0047 void signal(Lock& lock)
0048 {
0049 this->signal_all(lock);
0050 }
0051
0052
0053 template <typename Lock>
0054 void signal_all(Lock& lock)
0055 {
0056 BOOST_ASIO_ASSERT(lock.locked());
0057 (void)lock;
0058 state_ |= 1;
0059 cond_.notify_all();
0060 }
0061
0062
0063 template <typename Lock>
0064 void unlock_and_signal_one(Lock& lock)
0065 {
0066 BOOST_ASIO_ASSERT(lock.locked());
0067 state_ |= 1;
0068 bool have_waiters = (state_ > 1);
0069 lock.unlock();
0070 if (have_waiters)
0071 cond_.notify_one();
0072 }
0073
0074
0075 template <typename Lock>
0076 void unlock_and_signal_one_for_destruction(Lock& lock)
0077 {
0078 BOOST_ASIO_ASSERT(lock.locked());
0079 state_ |= 1;
0080 bool have_waiters = (state_ > 1);
0081 if (have_waiters)
0082 cond_.notify_one();
0083 lock.unlock();
0084 }
0085
0086
0087 template <typename Lock>
0088 bool maybe_unlock_and_signal_one(Lock& lock)
0089 {
0090 BOOST_ASIO_ASSERT(lock.locked());
0091 state_ |= 1;
0092 if (state_ > 1)
0093 {
0094 lock.unlock();
0095 cond_.notify_one();
0096 return true;
0097 }
0098 return false;
0099 }
0100
0101
0102 template <typename Lock>
0103 void clear(Lock& lock)
0104 {
0105 BOOST_ASIO_ASSERT(lock.locked());
0106 (void)lock;
0107 state_ &= ~std::size_t(1);
0108 }
0109
0110
0111 template <typename Lock>
0112 void wait(Lock& lock)
0113 {
0114 BOOST_ASIO_ASSERT(lock.locked());
0115 unique_lock_adapter u_lock(lock);
0116 while ((state_ & 1) == 0)
0117 {
0118 waiter w(state_);
0119 cond_.wait(u_lock.unique_lock_);
0120 }
0121 }
0122
0123
0124 template <typename Lock>
0125 bool wait_for_usec(Lock& lock, long usec)
0126 {
0127 BOOST_ASIO_ASSERT(lock.locked());
0128 unique_lock_adapter u_lock(lock);
0129 if ((state_ & 1) == 0)
0130 {
0131 waiter w(state_);
0132 cond_.wait_for(u_lock.unique_lock_, std::chrono::microseconds(usec));
0133 }
0134 return (state_ & 1) != 0;
0135 }
0136
0137 private:
0138
0139
0140 struct unique_lock_adapter
0141 {
0142 template <typename Lock>
0143 explicit unique_lock_adapter(Lock& lock)
0144 : unique_lock_(lock.mutex().mutex_, std::adopt_lock)
0145 {
0146 }
0147
0148 ~unique_lock_adapter()
0149 {
0150 unique_lock_.release();
0151 }
0152
0153 std::unique_lock<std::mutex> unique_lock_;
0154 };
0155
0156
0157 class waiter
0158 {
0159 public:
0160 explicit waiter(std::size_t& state)
0161 : state_(state)
0162 {
0163 state_ += 2;
0164 }
0165
0166 ~waiter()
0167 {
0168 state_ -= 2;
0169 }
0170
0171 private:
0172 std::size_t& state_;
0173 };
0174
0175 std::condition_variable cond_;
0176 std::size_t state_;
0177 };
0178
0179 }
0180 }
0181 }
0182
0183 #include <boost/asio/detail/pop_options.hpp>
0184
0185 #endif