1 /*
2  * Distributed under the Boost Software License, Version 1.0.
3  *    (See accompanying file LICENSE_1_0.txt or copy at
4  *          http://www.boost.org/LICENSE_1_0.txt)
5  *
6  * (C) Copyright 2007-2008 Anthony Williams
7  * (C) Copyright 2011-2012 Vicente J. Botet Escriba
8  * (C) Copyright 2013 Andrey Semashev
9  */
10 /*!
11  * \file   detail/condition_variables/condition_variable_any_windows.hpp
12  *
13  * \brief  This header is the Boost.Sync library implementation, see the library documentation
14  *         at http://www.boost.org/doc/libs/release/libs/sync/doc/html/index.html.
15  */
16 
17 #ifndef BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_WINDOWS_HPP_INCLUDED_
18 #define BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_WINDOWS_HPP_INCLUDED_
19 
20 #include <boost/utility/enable_if.hpp>
21 #include <boost/sync/detail/config.hpp>
22 #include <boost/sync/detail/time_traits.hpp>
23 #include <boost/sync/detail/time_units.hpp>
24 #include <boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp>
25 #include <boost/sync/condition_variables/cv_status.hpp>
26 #include <boost/sync/detail/header.hpp>
27 
28 #ifdef BOOST_HAS_PRAGMA_ONCE
29 #pragma once
30 #endif
31 
32 namespace boost {
33 
34 namespace sync {
35 
36 BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
37 
38 class condition_variable_any
39 {
40 private:
41     sync::detail::windows::basic_condition_variable m_cond;
42 
43 public:
44 #if !defined(BOOST_NO_CXX11_CONSTEXPR)
45 #define BOOST_SYNC_DEFINES_CONDITION_VARIABLE_ANY_CONSTEXPR_CONSTRUCTOR
46 #endif
47 
48     BOOST_CONSTEXPR condition_variable_any() BOOST_NOEXCEPT : m_cond()
49     {
50     }
51 
52     void notify_one() BOOST_NOEXCEPT
53     {
54         m_cond.notify_one();
55     }
56 
57     void notify_all() BOOST_NOEXCEPT
58     {
59         m_cond.notify_all();
60     }
61 
62     template< typename Lock >
63     void wait(Lock& lock)
64     {
65         m_cond.wait(lock);
66     }
67 
68     template< typename Lock, typename Predicate >
69     void wait(Lock& lock, Predicate pred)
70     {
71         while (!pred())
72             m_cond.wait(lock);
73     }
74 
75     template< typename Lock, typename Time >
76     typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type
77     timed_wait(Lock& lock, Time const& t)
78     {
79         return m_cond.timed_wait(lock, sync::detail::time_traits< Time >::to_sync_unit(t)) == sync::cv_status::no_timeout;
80     }
81 
82     template< typename Lock, typename TimePoint, typename Predicate >
83     typename detail::enable_if_tag< TimePoint, detail::time_point_tag, bool >::type
84     timed_wait(Lock& lock, TimePoint const& t, Predicate pred)
85     {
86         typedef typename sync::detail::time_traits< TimePoint >::unit_type unit_type;
87         unit_type abs_timeout = sync::detail::time_traits< TimePoint >::to_sync_unit(t);
88         while (!pred())
89         {
90             if (m_cond.timed_wait(lock, abs_timeout) != sync::cv_status::no_timeout)
91                 return pred();
92         }
93         return true;
94     }
95 
96     template< typename Lock, typename Duration, typename Predicate >
97     typename detail::enable_if_tag< Duration, detail::time_duration_tag, bool >::type
98     timed_wait(Lock& lock, Duration const& t, Predicate pred)
99     {
100         sync::detail::system_time_point abs_timeout = sync::detail::system_time_point::now() + sync::detail::time_traits< Duration >::to_sync_unit(t);
101         while (!pred())
102         {
103             if (m_cond.timed_wait(lock, abs_timeout) != sync::cv_status::no_timeout)
104                 return pred();
105         }
106         return true;
107     }
108 
109     template< typename Lock, typename TimePoint >
110     typename detail::enable_if_tag< TimePoint, detail::time_point_tag, sync::cv_status >::type
111     wait_until(Lock& lock, TimePoint const& abs_time)
112     {
113         return m_cond.timed_wait(lock, sync::detail::time_traits< TimePoint >::to_sync_unit(abs_time));
114     }
115 
116     template< typename Lock, typename TimePoint, typename Predicate >
117     typename detail::enable_if_tag< TimePoint, detail::time_point_tag, bool >::type
118     wait_until(Lock& lock, TimePoint const& abs_time, Predicate pred)
119     {
120         typedef typename sync::detail::time_traits< TimePoint >::unit_type unit_type;
121         unit_type abs_timeout = sync::detail::time_traits< TimePoint >::to_sync_unit(abs_time);
122         while (!pred())
123         {
124             if (m_cond.timed_wait(lock, abs_timeout) != sync::cv_status::no_timeout)
125                 return pred();
126         }
127         return true;
128     }
129 
130     template< typename Lock, typename Duration >
131     typename detail::enable_if_tag< Duration, detail::time_duration_tag, sync::cv_status >::type
132     wait_for(Lock& lock, Duration const& rel_time)
133     {
134         return m_cond.timed_wait(lock, sync::detail::time_traits< Duration >::to_sync_unit(rel_time));
135     }
136 
137     template< typename Lock, typename Duration, typename Predicate >
138     typename detail::enable_if_tag< Duration, detail::time_duration_tag, bool >::type
139     wait_for(Lock& lock, Duration const& rel_time, Predicate pred)
140     {
141         sync::detail::system_time_point abs_timeout = sync::detail::system_time_point::now() + sync::detail::time_traits< Duration >::to_sync_unit(rel_time);
142         while (!pred())
143         {
144             if (m_cond.timed_wait(lock, abs_timeout) != sync::cv_status::no_timeout)
145                 return pred();
146         }
147         return true;
148     }
149 
150     BOOST_DELETED_FUNCTION(condition_variable_any(condition_variable_any const&))
151     BOOST_DELETED_FUNCTION(condition_variable_any& operator= (condition_variable_any const&))
152 };
153 
154 } // namespace abi
155 
156 } // namespace sync
157 
158 } // namespace boost
159 
160 #include <boost/sync/detail/footer.hpp>
161 
162 #endif // BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_WINDOWS_HPP_INCLUDED_
163