summaryrefslogtreecommitdiffstats
path: root/lib/asio/detail/win_event.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asio/detail/win_event.hpp')
-rw-r--r--lib/asio/detail/win_event.hpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/lib/asio/detail/win_event.hpp b/lib/asio/detail/win_event.hpp
new file mode 100644
index 0000000..859cdee
--- /dev/null
+++ b/lib/asio/detail/win_event.hpp
@@ -0,0 +1,151 @@
+//
+// detail/win_event.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_DETAIL_WIN_EVENT_HPP
+#define ASIO_DETAIL_WIN_EVENT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#if defined(ASIO_WINDOWS)
+
+#include "asio/detail/assert.hpp"
+#include "asio/detail/noncopyable.hpp"
+#include "asio/detail/socket_types.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+class win_event
+ : private noncopyable
+{
+public:
+ // Constructor.
+ ASIO_DECL win_event();
+
+ // Destructor.
+ ASIO_DECL ~win_event();
+
+ // Signal the event. (Retained for backward compatibility.)
+ template <typename Lock>
+ void signal(Lock& lock)
+ {
+ this->signal_all(lock);
+ }
+
+ // Signal all waiters.
+ template <typename Lock>
+ void signal_all(Lock& lock)
+ {
+ ASIO_ASSERT(lock.locked());
+ (void)lock;
+ state_ |= 1;
+ ::SetEvent(events_[0]);
+ }
+
+ // Unlock the mutex and signal one waiter.
+ template <typename Lock>
+ void unlock_and_signal_one(Lock& lock)
+ {
+ ASIO_ASSERT(lock.locked());
+ state_ |= 1;
+ bool have_waiters = (state_ > 1);
+ lock.unlock();
+ if (have_waiters)
+ ::SetEvent(events_[1]);
+ }
+
+ // If there's a waiter, unlock the mutex and signal it.
+ template <typename Lock>
+ bool maybe_unlock_and_signal_one(Lock& lock)
+ {
+ ASIO_ASSERT(lock.locked());
+ state_ |= 1;
+ if (state_ > 1)
+ {
+ lock.unlock();
+ ::SetEvent(events_[1]);
+ return true;
+ }
+ return false;
+ }
+
+ // Reset the event.
+ template <typename Lock>
+ void clear(Lock& lock)
+ {
+ ASIO_ASSERT(lock.locked());
+ (void)lock;
+ ::ResetEvent(events_[0]);
+ state_ &= ~std::size_t(1);
+ }
+
+ // Wait for the event to become signalled.
+ template <typename Lock>
+ void wait(Lock& lock)
+ {
+ ASIO_ASSERT(lock.locked());
+ while ((state_ & 1) == 0)
+ {
+ state_ += 2;
+ lock.unlock();
+#if defined(ASIO_WINDOWS_APP)
+ ::WaitForMultipleObjectsEx(2, events_, false, INFINITE, false);
+#else // defined(ASIO_WINDOWS_APP)
+ ::WaitForMultipleObjects(2, events_, false, INFINITE);
+#endif // defined(ASIO_WINDOWS_APP)
+ lock.lock();
+ state_ -= 2;
+ }
+ }
+
+ // Timed wait for the event to become signalled.
+ template <typename Lock>
+ bool wait_for_usec(Lock& lock, long usec)
+ {
+ ASIO_ASSERT(lock.locked());
+ if ((state_ & 1) == 0)
+ {
+ state_ += 2;
+ lock.unlock();
+ DWORD msec = usec > 0 ? (usec < 1000 ? 1 : usec / 1000) : 0;
+#if defined(ASIO_WINDOWS_APP)
+ ::WaitForMultipleObjectsEx(2, events_, false, msec, false);
+#else // defined(ASIO_WINDOWS_APP)
+ ::WaitForMultipleObjects(2, events_, false, msec);
+#endif // defined(ASIO_WINDOWS_APP)
+ lock.lock();
+ state_ -= 2;
+ }
+ return (state_ & 1) != 0;
+ }
+
+private:
+ HANDLE events_[2];
+ std::size_t state_;
+};
+
+} // namespace detail
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#if defined(ASIO_HEADER_ONLY)
+# include "asio/detail/impl/win_event.ipp"
+#endif // defined(ASIO_HEADER_ONLY)
+
+#endif // defined(ASIO_WINDOWS)
+
+#endif // ASIO_DETAIL_WIN_EVENT_HPP