Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // See http://www.boost.org/libs/interprocess for documentation.
|
Chris@16
|
8 //
|
Chris@16
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_INTERPROCESS_CONDITION_HPP
|
Chris@16
|
12 #define BOOST_INTERPROCESS_CONDITION_HPP
|
Chris@16
|
13
|
Chris@101
|
14 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
15 # include <boost/config.hpp>
|
Chris@101
|
16 #endif
|
Chris@101
|
17 #
|
Chris@101
|
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@16
|
19 # pragma once
|
Chris@16
|
20 #endif
|
Chris@16
|
21
|
Chris@101
|
22 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/interprocess/detail/config_begin.hpp>
|
Chris@16
|
25 #include <boost/interprocess/detail/workaround.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
|
Chris@16
|
28 #include <boost/interprocess/sync/interprocess_mutex.hpp>
|
Chris@16
|
29 #include <boost/interprocess/sync/detail/locks.hpp>
|
Chris@16
|
30 #include <boost/interprocess/exceptions.hpp>
|
Chris@16
|
31 #include <boost/limits.hpp>
|
Chris@16
|
32 #include <boost/assert.hpp>
|
Chris@16
|
33
|
Chris@16
|
34 #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
|
Chris@16
|
35 #include <boost/interprocess/sync/posix/condition.hpp>
|
Chris@16
|
36 #define BOOST_INTERPROCESS_USE_POSIX
|
Chris@16
|
37 //Experimental...
|
Chris@16
|
38 #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
|
Chris@16
|
39 #include <boost/interprocess/sync/windows/condition.hpp>
|
Chris@16
|
40 #define BOOST_INTERPROCESS_USE_WINDOWS
|
Chris@16
|
41 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
42 #include <boost/interprocess/sync/spin/condition.hpp>
|
Chris@16
|
43 #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
|
Chris@16
|
44 #endif
|
Chris@16
|
45
|
Chris@101
|
46 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
47
|
Chris@16
|
48 //!\file
|
Chris@16
|
49 //!Describes process-shared variables interprocess_condition class
|
Chris@16
|
50
|
Chris@16
|
51 namespace boost {
|
Chris@16
|
52
|
Chris@101
|
53 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@101
|
54
|
Chris@16
|
55 namespace posix_time
|
Chris@16
|
56 { class ptime; }
|
Chris@16
|
57
|
Chris@101
|
58 #endif //#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@101
|
59
|
Chris@16
|
60 namespace interprocess {
|
Chris@16
|
61
|
Chris@16
|
62 class named_condition;
|
Chris@16
|
63
|
Chris@16
|
64 //!This class is a condition variable that can be placed in shared memory or
|
Chris@16
|
65 //!memory mapped files.
|
Chris@16
|
66 //!Destroys the object of type std::condition_variable_any
|
Chris@16
|
67 //!
|
Chris@16
|
68 //!Unlike std::condition_variable in C++11, it is NOT safe to invoke the destructor if all
|
Chris@16
|
69 //!threads have been only notified. It is required that they have exited their respective wait
|
Chris@101
|
70 //!functions.
|
Chris@16
|
71 class interprocess_condition
|
Chris@16
|
72 {
|
Chris@101
|
73 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
74 //Non-copyable
|
Chris@16
|
75 interprocess_condition(const interprocess_condition &);
|
Chris@16
|
76 interprocess_condition &operator=(const interprocess_condition &);
|
Chris@16
|
77 friend class named_condition;
|
Chris@101
|
78 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
79
|
Chris@16
|
80 public:
|
Chris@16
|
81 //!Constructs a interprocess_condition. On error throws interprocess_exception.
|
Chris@16
|
82 interprocess_condition()
|
Chris@16
|
83 {}
|
Chris@16
|
84
|
Chris@16
|
85 //!Destroys *this
|
Chris@16
|
86 //!liberating system resources.
|
Chris@16
|
87 ~interprocess_condition()
|
Chris@16
|
88 {}
|
Chris@16
|
89
|
Chris@16
|
90 //!If there is a thread waiting on *this, change that
|
Chris@16
|
91 //!thread's state to ready. Otherwise there is no effect.
|
Chris@16
|
92 void notify_one()
|
Chris@16
|
93 { m_condition.notify_one(); }
|
Chris@16
|
94
|
Chris@16
|
95 //!Change the state of all threads waiting on *this to ready.
|
Chris@16
|
96 //!If there are no waiting threads, notify_all() has no effect.
|
Chris@16
|
97 void notify_all()
|
Chris@16
|
98 { m_condition.notify_all(); }
|
Chris@16
|
99
|
Chris@16
|
100 //!Releases the lock on the interprocess_mutex object associated with lock, blocks
|
Chris@16
|
101 //!the current thread of execution until readied by a call to
|
Chris@16
|
102 //!this->notify_one() or this->notify_all(), and then reacquires the lock.
|
Chris@16
|
103 template <typename L>
|
Chris@16
|
104 void wait(L& lock)
|
Chris@101
|
105 {
|
Chris@16
|
106 ipcdetail::internal_mutex_lock<L> internal_lock(lock);
|
Chris@16
|
107 m_condition.wait(internal_lock);
|
Chris@16
|
108 }
|
Chris@16
|
109
|
Chris@16
|
110 //!The same as:
|
Chris@16
|
111 //!while (!pred()) wait(lock)
|
Chris@16
|
112 template <typename L, typename Pr>
|
Chris@16
|
113 void wait(L& lock, Pr pred)
|
Chris@16
|
114 {
|
Chris@16
|
115 ipcdetail::internal_mutex_lock<L> internal_lock(lock);
|
Chris@16
|
116 m_condition.wait(internal_lock, pred);
|
Chris@16
|
117 }
|
Chris@16
|
118
|
Chris@16
|
119 //!Releases the lock on the interprocess_mutex object associated with lock, blocks
|
Chris@16
|
120 //!the current thread of execution until readied by a call to
|
Chris@16
|
121 //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
|
Chris@16
|
122 //!and then reacquires the lock.
|
Chris@16
|
123 //!Returns: false if time abs_time is reached, otherwise true.
|
Chris@16
|
124 template <typename L>
|
Chris@16
|
125 bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
|
Chris@16
|
126 {
|
Chris@16
|
127 ipcdetail::internal_mutex_lock<L> internal_lock(lock);
|
Chris@16
|
128 return m_condition.timed_wait(internal_lock, abs_time);
|
Chris@16
|
129 }
|
Chris@16
|
130
|
Chris@16
|
131 //!The same as: while (!pred()) {
|
Chris@16
|
132 //! if (!timed_wait(lock, abs_time)) return pred();
|
Chris@16
|
133 //! } return true;
|
Chris@16
|
134 template <typename L, typename Pr>
|
Chris@16
|
135 bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
|
Chris@16
|
136 {
|
Chris@16
|
137 ipcdetail::internal_mutex_lock<L> internal_lock(lock);
|
Chris@16
|
138 return m_condition.timed_wait(internal_lock, abs_time, pred);
|
Chris@16
|
139 }
|
Chris@16
|
140
|
Chris@101
|
141 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
142
|
Chris@16
|
143 private:
|
Chris@16
|
144 #if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
|
Chris@16
|
145 #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
|
Chris@16
|
146 ipcdetail::spin_condition m_condition;
|
Chris@16
|
147 #elif defined(BOOST_INTERPROCESS_USE_POSIX)
|
Chris@16
|
148 #undef BOOST_INTERPROCESS_USE_POSIX
|
Chris@16
|
149 ipcdetail::posix_condition m_condition;
|
Chris@16
|
150 #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
|
Chris@16
|
151 #undef BOOST_INTERPROCESS_USE_WINDOWS
|
Chris@16
|
152 ipcdetail::windows_condition m_condition;
|
Chris@16
|
153 #else
|
Chris@16
|
154 #error "Unknown platform for interprocess_mutex"
|
Chris@16
|
155 #endif
|
Chris@101
|
156 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
157 };
|
Chris@16
|
158
|
Chris@16
|
159 } //namespace interprocess
|
Chris@16
|
160 } // namespace boost
|
Chris@16
|
161
|
Chris@16
|
162 #include <boost/interprocess/detail/config_end.hpp>
|
Chris@16
|
163
|
Chris@16
|
164 #endif // BOOST_INTERPROCESS_CONDITION_HPP
|