Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:45

0001 //
0002 // detail/win_event.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // defined(_MSC_VER) && (_MSC_VER >= 1200)
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   // Constructor.
0038   BOOST_ASIO_DECL win_event();
0039 
0040   // Destructor.
0041   BOOST_ASIO_DECL ~win_event();
0042 
0043   // Signal the event. (Retained for backward compatibility.)
0044   template <typename Lock>
0045   void signal(Lock& lock)
0046   {
0047     this->signal_all(lock);
0048   }
0049 
0050   // Signal all waiters.
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   // Unlock the mutex and signal one waiter.
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   // Unlock the mutex and signal one waiter who may destroy us.
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   // If there's a waiter, unlock the mutex and signal it.
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   // Reset the event.
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   // Wait for the event to become signalled.
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 // defined(BOOST_ASIO_WINDOWS_APP)
0121       ::WaitForMultipleObjects(2, events_, false, INFINITE);
0122 #endif // defined(BOOST_ASIO_WINDOWS_APP)
0123       lock.lock();
0124       state_ -= 2;
0125     }
0126   }
0127 
0128   // Timed wait for the event to become signalled.
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 // defined(BOOST_ASIO_WINDOWS_APP)
0141       ::WaitForMultipleObjects(2, events_, false, msec);
0142 #endif // defined(BOOST_ASIO_WINDOWS_APP)
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 } // namespace detail
0155 } // namespace asio
0156 } // namespace boost
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 // defined(BOOST_ASIO_HEADER_ONLY)
0163 
0164 #endif // defined(BOOST_ASIO_WINDOWS)
0165 
0166 #endif // BOOST_ASIO_DETAIL_WIN_EVENT_HPP