1 // semaphore.hpp, mutex/condition_varibale 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_SEMAPHORE_SEMAPHORE_EMULATION_HPP_INCLUDED_ 11 #define BOOST_SYNC_DETAIL_SEMAPHORE_SEMAPHORE_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_SEMAPHORE_EMULATED 27 28 namespace boost { 29 30 namespace sync { 31 32 BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE { 33 34 class semaphore 35 { 36 BOOST_DELETED_FUNCTION(semaphore(semaphore const&)) 37 BOOST_DELETED_FUNCTION(semaphore& operator=(semaphore const&)) 38 39 public: 40 explicit semaphore(unsigned int i = 0) : m_count(i) 41 { 42 } 43 44 void post() 45 { 46 sync::lock_guard< sync::mutex > lock(m_mutex); 47 ++m_count; 48 m_cond.notify_one(); 49 } 50 51 void wait() 52 { 53 sync::unique_lock< sync::mutex > lock(m_mutex); 54 while (m_count == 0) 55 m_cond.wait(lock); 56 57 --m_count; 58 } 59 60 bool try_wait() 61 { 62 sync::lock_guard< sync::mutex > lock(m_mutex); 63 if (m_count == 0) 64 return false; 65 66 --m_count; 67 return true; 68 } 69 70 template< typename Time > 71 typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type timed_wait(Time const& timeout) 72 { 73 sync::unique_lock< sync::mutex > lock(m_mutex); 74 while (m_count == 0) 75 { 76 if (!m_cond.timed_wait(lock, timeout)) 77 { 78 if (m_count == 0) 79 return false; 80 else 81 break; 82 } 83 } 84 85 --m_count; 86 return true; 87 } 88 89 template< typename Duration > 90 typename enable_if< detail::is_time_tag_of< Duration, detail::time_duration_tag >, bool >::type wait_for(Duration const& duration) 91 { 92 return timed_wait(duration); 93 } 94 95 template< typename TimePoint > 96 typename enable_if< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, bool >::type wait_until(TimePoint const& abs_time) 97 { 98 return timed_wait(abs_time); 99 } 100 101 private: 102 sync::mutex m_mutex; 103 sync::condition_variable m_cond; 104 unsigned int m_count; 105 }; 106 107 } // namespace abi 108 109 } // namespace sync 110 111 } // namespace boost 112 113 #include <boost/sync/detail/footer.hpp> 114 115 #endif // BOOST_SYNC_DETAIL_SEMAPHORE_SEMAPHORE_EMULATION_HPP_INCLUDED_ 116