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