1 // auto_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_AUTO_RESET_EVENT_EMULATION_HPP_INCLUDED_
11 #define BOOST_SYNC_DETAIL_EVENTS_AUTO_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_AUTO_RESET_EVENT_EMULATED
27 
28 namespace boost {
29 
30 namespace sync {
31 
32 BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
33 
34 class auto_reset_event
35 {
36     BOOST_DELETED_FUNCTION(auto_reset_event(auto_reset_event const&));
37     BOOST_DELETED_FUNCTION(auto_reset_event& operator= (auto_reset_event const&));
38 
39 public:
40     auto_reset_event() : m_is_set(false)
41     {
42     }
43 
44     void post()
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_one();
52         }
53     }
54 
55     void wait()
56     {
57         sync::unique_lock< sync::mutex > lock(m_mutex);
58 
59         while (!m_is_set)
60             m_cond.wait(lock);
61 
62         m_is_set = false;
63     }
64 
65     bool try_wait()
66     {
67         sync::lock_guard< sync::mutex > lock(m_mutex);
68         const bool res = m_is_set;
69         if (res)
70             m_is_set = false;
71         return res;
72     }
73 
74     template< typename Time >
75     typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type timed_wait(Time const& timeout)
76     {
77         sync::unique_lock< sync::mutex > lock(m_mutex);
78         while (!m_is_set)
79         {
80             if (!m_cond.timed_wait(lock, timeout))
81             {
82                 if (!m_is_set)
83                     return false;
84                 else
85                     break;
86             }
87         }
88 
89         m_is_set = false;
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_AUTO_RESET_EVENT_EMULATION_HPP_INCLUDED_
120