1 // manual_reset_event_emulation.hpp, event emulation
2 //
3 // Copyright (C) 2013 Tim Blechmann
4 // Copyright (C) 2013 Andrey Semashev
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 #ifndef BOOST_SYNC_DETAIL_EVENTS_MANUAL_RESET_EVENT_EMULATION_HPP_INCLUDED_
11 #define BOOST_SYNC_DETAIL_EVENTS_MANUAL_RESET_EVENT_EMULATION_HPP_INCLUDED_
12 
13 #include <boost/utility/enable_if.hpp>
14 #include <boost/sync/detail/config.hpp>
15 #include <boost/sync/detail/time_traits.hpp>
16 #include <boost/sync/locks/lock_guard.hpp>
17 #include <boost/sync/locks/unique_lock.hpp>
18 #include <boost/sync/mutexes/mutex.hpp>
19 #include <boost/sync/condition_variables/condition_variable.hpp>
20 #include <boost/sync/detail/header.hpp>
21 
22 #ifdef BOOST_HAS_PRAGMA_ONCE
23 #pragma once
24 #endif
25 
26 #define BOOST_SYNC_MANUAL_RESET_EVENT_EMULATED
27 
28 namespace boost {
29 
30 namespace sync {
31 
32 BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
33 
34 class manual_reset_event
35 {
36     BOOST_DELETED_FUNCTION(manual_reset_event(manual_reset_event const&));
37     BOOST_DELETED_FUNCTION(manual_reset_event& operator= (manual_reset_event const&));
38 
39 public:
40     manual_reset_event() : m_is_set(false)
41     {
42     }
43 
44     void set()
45     {
46         sync::lock_guard< sync::mutex > lock(m_mutex);
47         const bool already_signaled = m_is_set;
48         if (!already_signaled)
49         {
50             m_is_set = true;
51             m_cond.notify_all();
52         }
53     }
54 
55     void reset()
56     {
57         sync::lock_guard< sync::mutex > lock(m_mutex);
58         m_is_set = false;
59     }
60 
61     void wait()
62     {
63         sync::unique_lock< sync::mutex > lock(m_mutex);
64 
65         while (!m_is_set)
66             m_cond.wait(lock);
67     }
68 
69     bool try_wait()
70     {
71         sync::lock_guard< sync::mutex > lock(m_mutex);
72         return m_is_set;
73     }
74 
75     template< typename Time >
76     typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type timed_wait(Time const& timeout)
77     {
78         sync::unique_lock< sync::mutex > lock(m_mutex);
79         while (!m_is_set)
80         {
81             if (!m_cond.timed_wait(lock, timeout))
82             {
83                 if (!m_is_set)
84                     return false;
85                 else
86                     break;
87             }
88         }
89 
90         return true;
91     }
92 
93     template< typename Duration >
94     typename enable_if< detail::is_time_tag_of< Duration, detail::time_duration_tag >, bool >::type wait_for(Duration const& duration)
95     {
96         return timed_wait(duration);
97     }
98 
99     template< typename TimePoint >
100     typename enable_if< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, bool >::type wait_until(TimePoint const& abs_time)
101     {
102         return timed_wait(abs_time);
103     }
104 
105 private:
106     sync::mutex m_mutex;
107     sync::condition_variable m_cond;
108     bool m_is_set;
109 };
110 
111 } // namespace abi
112 
113 } // namespace sync
114 
115 } // namespace boost
116 
117 #include <boost/sync/detail/footer.hpp>
118 
119 #endif // BOOST_SYNC_DETAIL_EVENTS_MANUAL_RESET_EVENT_EMULATION_HPP_INCLUDED_
120