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_WIN_EVENT_HPP
0012 #define BOOST_ASIO_DETAIL_WIN_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
0020 #if defined(BOOST_ASIO_WINDOWS)
0021
0022 #include <cstddef>
0023 #include <boost/asio/detail/assert.hpp>
0024 #include <boost/asio/detail/noncopyable.hpp>
0025 #include <boost/asio/detail/socket_types.hpp>
0026
0027 #include <boost/asio/detail/push_options.hpp>
0028
0029 namespace boost {
0030 namespace asio {
0031 namespace detail {
0032
0033 class win_event
0034 : private noncopyable
0035 {
0036 public:
0037
0038 BOOST_ASIO_DECL win_event();
0039
0040
0041 BOOST_ASIO_DECL ~win_event();
0042
0043
0044 template <typename Lock>
0045 void signal(Lock& lock)
0046 {
0047 this->signal_all(lock);
0048 }
0049
0050
0051 template <typename Lock>
0052 void signal_all(Lock& lock)
0053 {
0054 BOOST_ASIO_ASSERT(lock.locked());
0055 (void)lock;
0056 state_ |= 1;
0057 ::SetEvent(events_[0]);
0058 }
0059
0060
0061 template <typename Lock>
0062 void unlock_and_signal_one(Lock& lock)
0063 {
0064 BOOST_ASIO_ASSERT(lock.locked());
0065 state_ |= 1;
0066 bool have_waiters = (state_ > 1);
0067 lock.unlock();
0068 if (have_waiters)
0069 ::SetEvent(events_[1]);
0070 }
0071
0072
0073 template <typename Lock>
0074 void unlock_and_signal_one_for_destruction(Lock& lock)
0075 {
0076 BOOST_ASIO_ASSERT(lock.locked());
0077 state_ |= 1;
0078 bool have_waiters = (state_ > 1);
0079 if (have_waiters)
0080 ::SetEvent(events_[1]);
0081 lock.unlock();
0082 }
0083
0084
0085 template <typename Lock>
0086 bool maybe_unlock_and_signal_one(Lock& lock)
0087 {
0088 BOOST_ASIO_ASSERT(lock.locked());
0089 state_ |= 1;
0090 if (state_ > 1)
0091 {
0092 lock.unlock();
0093 ::SetEvent(events_[1]);
0094 return true;
0095 }
0096 return false;
0097 }
0098
0099
0100 template <typename Lock>
0101 void clear(Lock& lock)
0102 {
0103 BOOST_ASIO_ASSERT(lock.locked());
0104 (void)lock;
0105 ::ResetEvent(events_[0]);
0106 state_ &= ~std::size_t(1);
0107 }
0108
0109
0110 template <typename Lock>
0111 void wait(Lock& lock)
0112 {
0113 BOOST_ASIO_ASSERT(lock.locked());
0114 while ((state_ & 1) == 0)
0115 {
0116 state_ += 2;
0117 lock.unlock();
0118 #if defined(BOOST_ASIO_WINDOWS_APP)
0119 ::WaitForMultipleObjectsEx(2, events_, false, INFINITE, false);
0120 #else
0121 ::WaitForMultipleObjects(2, events_, false, INFINITE);
0122 #endif
0123 lock.lock();
0124 state_ -= 2;
0125 }
0126 }
0127
0128
0129 template <typename Lock>
0130 bool wait_for_usec(Lock& lock, long usec)
0131 {
0132 BOOST_ASIO_ASSERT(lock.locked());
0133 if ((state_ & 1) == 0)
0134 {
0135 state_ += 2;
0136 lock.unlock();
0137 DWORD msec = usec > 0 ? (usec < 1000 ? 1 : usec / 1000) : 0;
0138 #if defined(BOOST_ASIO_WINDOWS_APP)
0139 ::WaitForMultipleObjectsEx(2, events_, false, msec, false);
0140 #else
0141 ::WaitForMultipleObjects(2, events_, false, msec);
0142 #endif
0143 lock.lock();
0144 state_ -= 2;
0145 }
0146 return (state_ & 1) != 0;
0147 }
0148
0149 private:
0150 HANDLE events_[2];
0151 std::size_t state_;
0152 };
0153
0154 }
0155 }
0156 }
0157
0158 #include <boost/asio/detail/pop_options.hpp>
0159
0160 #if defined(BOOST_ASIO_HEADER_ONLY)
0161 # include <boost/asio/detail/impl/win_event.ipp>
0162 #endif
0163
0164 #endif
0165
0166 #endif