1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_SHM_NAMED_CONDITION_ANY_HPP
12 #define BOOST_INTERPROCESS_SHM_NAMED_CONDITION_ANY_HPP
14 #ifndef BOOST_CONFIG_HPP
15 # include <boost/config.hpp>
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
22 #include <boost/interprocess/detail/config_begin.hpp>
23 #include <boost/interprocess/detail/workaround.hpp>
25 #include <boost/interprocess/sync/cv_status.hpp>
26 #include <boost/static_assert.hpp>
27 #include <boost/interprocess/detail/type_traits.hpp>
28 #include <boost/interprocess/creation_tags.hpp>
29 #include <boost/interprocess/exceptions.hpp>
30 #include <boost/interprocess/shared_memory_object.hpp>
31 #include <boost/interprocess/sync/interprocess_condition.hpp>
32 #include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
33 #include <boost/interprocess/sync/shm/named_creation_functor.hpp>
34 #include <boost/interprocess/sync/named_mutex.hpp>
35 #include <boost/interprocess/permissions.hpp>
36 #include <boost/interprocess/sync/interprocess_mutex.hpp>
37 #include <boost/interprocess/sync/scoped_lock.hpp>
38 #include <boost/interprocess/sync/detail/condition_any_algorithm.hpp>
41 //!Describes process-shared variables interprocess_condition class
44 namespace interprocess {
47 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
48 class interprocess_tester;
49 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
51 //! A global condition variable that can be created by name.
52 //! This condition variable is designed to work with named_mutex and
53 //! can't be placed in shared memory or memory mapped files.
54 class shm_named_condition_any
56 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
58 shm_named_condition_any();
59 shm_named_condition_any(const shm_named_condition_any &);
60 shm_named_condition_any &operator=(const shm_named_condition_any &);
61 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
63 //!Creates a global condition with a name.
64 //!If the condition can't be created throws interprocess_exception
65 template <class CharT>
66 shm_named_condition_any(create_only_t, const CharT *name, const permissions &perm = permissions())
67 : m_shmem (create_only_t()
69 ,sizeof(internal_condition) +
70 open_create_impl_t::ManagedOpenOrCreateUserOffset
73 ,construct_func_t(DoCreate)
77 //!Opens or creates a global condition with a name.
78 //!If the condition is created, this call is equivalent to
79 //!shm_named_condition_any(create_only_t, ... )
80 //!If the condition is already created, this call is equivalent
81 //!shm_named_condition_any(open_only_t, ... )
83 template <class CharT>
84 shm_named_condition_any(open_or_create_t, const CharT *name, const permissions &perm = permissions())
85 : m_shmem (open_or_create_t()
87 ,sizeof(internal_condition) +
88 open_create_impl_t::ManagedOpenOrCreateUserOffset
91 ,construct_func_t(DoOpenOrCreate)
95 //!Opens a global condition with a name if that condition is previously
96 //!created. If it is not previously created this function throws
97 //!interprocess_exception.
98 template <class CharT>
99 shm_named_condition_any(open_only_t, const CharT *name)
100 : m_shmem (open_only_t()
104 ,construct_func_t(DoOpen))
107 //!Destroys *this and indicates that the calling process is finished using
108 //!the resource. The destructor function will deallocate
109 //!any system resources allocated by the system for use by this process for
110 //!this resource. The resource can still be opened again calling
111 //!the open constructor overload. To erase the resource from the system
113 ~shm_named_condition_any()
116 //!If there is a thread waiting on *this, change that
117 //!thread's state to ready. Otherwise there is no effect.*/
119 { this->internal_cond().notify_one(); }
121 //!Change the state of all threads waiting on *this to ready.
122 //!If there are no waiting threads, notify_all() has no effect.
124 { this->internal_cond().notify_all(); }
126 //!Releases the lock on the named_mutex object associated with lock, blocks
127 //!the current thread of execution until readied by a call to
128 //!this->notify_one() or this->notify_all(), and then reacquires the lock.
129 template <typename L>
131 { this->internal_cond().wait(lock); }
134 //!while (!pred()) wait(lock)
135 template <typename L, typename Pr>
136 void wait(L& lock, Pr pred)
137 { this->internal_cond().wait(lock, pred); }
139 //!Releases the lock on the named_mutex object associated with lock, blocks
140 //!the current thread of execution until readied by a call to
141 //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
142 //!and then reacquires the lock.
143 //!Returns: false if time abs_time is reached, otherwise true.
144 template <typename L, typename TimePoint>
145 bool timed_wait(L& lock, const TimePoint &abs_time)
146 { return this->internal_cond().timed_wait(lock, abs_time); }
148 //!The same as: while (!pred()) {
149 //! if (!timed_wait(lock, abs_time)) return pred();
151 template <typename L, typename TimePoint, typename Pr>
152 bool timed_wait(L& lock, const TimePoint &abs_time, Pr pred)
153 { return this->internal_cond().timed_wait(lock, abs_time, pred); }
155 //!Same as `timed_wait`, but this function is modeled after the
156 //!standard library interface.
157 template <typename L, class TimePoint>
158 cv_status wait_until(L& lock, const TimePoint &abs_time)
159 { return this->timed_wait(lock, abs_time) ? cv_status::no_timeout : cv_status::timeout; }
161 //!Same as `timed_wait`, but this function is modeled after the
162 //!standard library interface.
163 template <typename L, class TimePoint, typename Pr>
164 bool wait_until(L& lock, const TimePoint &abs_time, Pr pred)
165 { return this->timed_wait(lock, abs_time, pred); }
167 //!Same as `timed_wait`, but this function is modeled after the
168 //!standard library interface and uses relative timeouts.
169 template <typename L, class Duration>
170 cv_status wait_for(L& lock, const Duration &dur)
171 { return this->wait_until(lock, ipcdetail::duration_to_ustime(dur)); }
173 //!Same as `timed_wait`, but this function is modeled after the
174 //!standard library interface and uses relative timeouts
175 template <typename L, class Duration, typename Pr>
176 bool wait_for(L& lock, const Duration &dur, Pr pred)
177 { return this->wait_until(lock, ipcdetail::duration_to_ustime(dur), pred); }
179 //!Erases a named condition from the system.
180 //!Returns false on error. Never throws.
181 template <class CharT>
182 static bool remove(const CharT *name)
183 { return shared_memory_object::remove(name); }
185 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
188 class internal_condition_members
191 typedef interprocess_mutex mutex_type;
192 typedef interprocess_condition condvar_type;
194 condvar_type& get_condvar() { return m_cond; }
195 mutex_type& get_mutex() { return m_mtx; }
202 typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition;
204 internal_condition &internal_cond()
205 { return *static_cast<internal_condition*>(m_shmem.get_user_address()); }
207 friend class boost::interprocess::ipcdetail::interprocess_tester;
208 void dont_close_on_destruction()
209 { interprocess_tester::dont_close_on_destruction(m_shmem); }
211 typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
212 open_create_impl_t m_shmem;
214 template <class T, class Arg> friend class boost::interprocess::ipcdetail::named_creation_functor;
215 typedef boost::interprocess::ipcdetail::named_creation_functor<internal_condition> construct_func_t;
216 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
219 } //namespace ipcdetail
220 } //namespace interprocess
223 #include <boost/interprocess/detail/config_end.hpp>
225 #endif // BOOST_INTERPROCESS_SHM_NAMED_CONDITION_ANY_HPP