1 //
2 // detail/conditionally_enabled_event.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
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)
9 //
10 
11 #ifndef BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
12 #define BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/detail/conditionally_enabled_mutex.hpp>
20 #include <boost/asio/detail/event.hpp>
21 #include <boost/asio/detail/noncopyable.hpp>
22 #include <boost/asio/detail/null_event.hpp>
23 #include <boost/asio/detail/scoped_lock.hpp>
24 
25 #include <boost/asio/detail/push_options.hpp>
26 
27 namespace boost {
28 namespace asio {
29 namespace detail {
30 
31 // Mutex adapter used to conditionally enable or disable locking.
32 class conditionally_enabled_event
33   : private noncopyable
34 {
35 public:
36   // Constructor.
conditionally_enabled_event()37   conditionally_enabled_event()
38   {
39   }
40 
41   // Destructor.
~conditionally_enabled_event()42   ~conditionally_enabled_event()
43   {
44   }
45 
46   // Signal the event. (Retained for backward compatibility.)
signal(conditionally_enabled_mutex::scoped_lock & lock)47   void signal(conditionally_enabled_mutex::scoped_lock& lock)
48   {
49     if (lock.mutex_.enabled_)
50       event_.signal(lock);
51   }
52 
53   // Signal all waiters.
signal_all(conditionally_enabled_mutex::scoped_lock & lock)54   void signal_all(conditionally_enabled_mutex::scoped_lock& lock)
55   {
56     if (lock.mutex_.enabled_)
57       event_.signal_all(lock);
58   }
59 
60   // Unlock the mutex and signal one waiter.
unlock_and_signal_one(conditionally_enabled_mutex::scoped_lock & lock)61   void unlock_and_signal_one(
62       conditionally_enabled_mutex::scoped_lock& lock)
63   {
64     if (lock.mutex_.enabled_)
65       event_.unlock_and_signal_one(lock);
66   }
67 
68   // Unlock the mutex and signal one waiter who may destroy us.
unlock_and_signal_one_for_destruction(conditionally_enabled_mutex::scoped_lock & lock)69   void unlock_and_signal_one_for_destruction(
70       conditionally_enabled_mutex::scoped_lock& lock)
71   {
72     if (lock.mutex_.enabled_)
73       event_.unlock_and_signal_one(lock);
74   }
75 
76   // If there's a waiter, unlock the mutex and signal it.
maybe_unlock_and_signal_one(conditionally_enabled_mutex::scoped_lock & lock)77   bool maybe_unlock_and_signal_one(
78       conditionally_enabled_mutex::scoped_lock& lock)
79   {
80     if (lock.mutex_.enabled_)
81       return event_.maybe_unlock_and_signal_one(lock);
82     else
83       return false;
84   }
85 
86   // Reset the event.
clear(conditionally_enabled_mutex::scoped_lock & lock)87   void clear(conditionally_enabled_mutex::scoped_lock& lock)
88   {
89     if (lock.mutex_.enabled_)
90       event_.clear(lock);
91   }
92 
93   // Wait for the event to become signalled.
wait(conditionally_enabled_mutex::scoped_lock & lock)94   void wait(conditionally_enabled_mutex::scoped_lock& lock)
95   {
96     if (lock.mutex_.enabled_)
97       event_.wait(lock);
98     else
99       null_event().wait(lock);
100   }
101 
102   // Timed wait for the event to become signalled.
wait_for_usec(conditionally_enabled_mutex::scoped_lock & lock,long usec)103   bool wait_for_usec(
104       conditionally_enabled_mutex::scoped_lock& lock, long usec)
105   {
106     if (lock.mutex_.enabled_)
107       return event_.wait_for_usec(lock, usec);
108     else
109       return null_event().wait_for_usec(lock, usec);
110   }
111 
112 private:
113   boost::asio::detail::event event_;
114 };
115 
116 } // namespace detail
117 } // namespace asio
118 } // namespace boost
119 
120 #include <boost/asio/detail/pop_options.hpp>
121 
122 #endif // BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
123