e2ff280b7b390c6609aaaa805b01ab5e5f452898
[platform/upstream/boost.git] / boost / interprocess / sync / shm / named_condition.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
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)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
11 #ifndef BOOST_INTERPROCESS_SHM_NAMED_CONDITION_HPP
12 #define BOOST_INTERPROCESS_SHM_NAMED_CONDITION_HPP
13
14 #if defined(_MSC_VER)
15 #  pragma once
16 #endif
17
18 #include <boost/interprocess/detail/config_begin.hpp>
19 #include <boost/interprocess/detail/workaround.hpp>
20 #include <boost/static_assert.hpp>
21 #include <boost/interprocess/detail/type_traits.hpp>
22 #include <boost/interprocess/creation_tags.hpp>
23 #include <boost/interprocess/exceptions.hpp>
24 #include <boost/interprocess/shared_memory_object.hpp>
25 #include <boost/interprocess/sync/interprocess_condition.hpp>
26 #include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
27 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
28 #include <boost/interprocess/sync/shm/named_creation_functor.hpp>
29 #include <boost/interprocess/sync/named_mutex.hpp>
30 #include <boost/interprocess/permissions.hpp>
31 #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
32    #include <boost/interprocess/sync/interprocess_mutex.hpp>
33    #include <boost/interprocess/sync/scoped_lock.hpp>
34    #include <boost/interprocess/sync/detail/condition_any_algorithm.hpp>
35 #else
36    #include <boost/interprocess/sync/detail/locks.hpp>
37 #endif
38
39
40 //!\file
41 //!Describes process-shared variables interprocess_condition class
42
43 namespace boost {
44 namespace interprocess {
45 namespace ipcdetail {
46
47 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
48 class interprocess_tester;
49 #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
50
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
55 {
56    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
57    //Non-copyable
58    shm_named_condition();
59    shm_named_condition(const shm_named_condition &);
60    shm_named_condition &operator=(const shm_named_condition &);
61    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
62    public:
63    //!Creates a global condition with a name.
64    //!If the condition can't be created throws interprocess_exception
65    shm_named_condition(create_only_t create_only, const char *name, const permissions &perm = permissions());
66
67    //!Opens or creates a global condition with a name.
68    //!If the condition is created, this call is equivalent to
69    //!shm_named_condition(create_only_t, ... )
70    //!If the condition is already created, this call is equivalent
71    //!shm_named_condition(open_only_t, ... )
72    //!Does not throw
73    shm_named_condition(open_or_create_t open_or_create, const char *name, const permissions &perm = permissions());
74
75    //!Opens a global condition with a name if that condition is previously
76    //!created. If it is not previously created this function throws
77    //!interprocess_exception.
78    shm_named_condition(open_only_t open_only, const char *name);
79
80    //!Destroys *this and indicates that the calling process is finished using
81    //!the resource. The destructor function will deallocate
82    //!any system resources allocated by the system for use by this process for
83    //!this resource. The resource can still be opened again calling
84    //!the open constructor overload. To erase the resource from the system
85    //!use remove().
86    ~shm_named_condition();
87
88    //!If there is a thread waiting on *this, change that
89    //!thread's state to ready. Otherwise there is no effect.*/
90    void notify_one();
91
92    //!Change the state of all threads waiting on *this to ready.
93    //!If there are no waiting threads, notify_all() has no effect.
94    void notify_all();
95
96    //!Releases the lock on the named_mutex object associated with lock, blocks
97    //!the current thread of execution until readied by a call to
98    //!this->notify_one() or this->notify_all(), and then reacquires the lock.
99    template <typename L>
100    void wait(L& lock);
101
102    //!The same as:
103    //!while (!pred()) wait(lock)
104    template <typename L, typename Pr>
105    void wait(L& lock, Pr pred);
106
107    //!Releases the lock on the named_mutex object associated with lock, blocks
108    //!the current thread of execution until readied by a call to
109    //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
110    //!and then reacquires the lock.
111    //!Returns: false if time abs_time is reached, otherwise true.
112    template <typename L>
113    bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time);
114
115    //!The same as:   while (!pred()) {
116    //!                  if (!timed_wait(lock, abs_time)) return pred();
117    //!               } return true;
118    template <typename L, typename Pr>
119    bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred);
120
121    //!Erases a named condition from the system.
122    //!Returns false on error. Never throws.
123    static bool remove(const char *name);
124
125    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
126    private:
127
128    #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
129    class internal_condition_members
130    {
131       public:
132       typedef interprocess_mutex       mutex_type;
133       typedef interprocess_condition   condvar_type;
134
135       condvar_type&  get_condvar() {  return m_cond;  }
136       mutex_type&    get_mutex()   {  return m_mtx; }
137
138       private:
139       mutex_type     m_mtx;
140       condvar_type   m_cond;
141    };
142
143    typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition;
144    #else    //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
145    typedef interprocess_condition internal_condition;
146    #endif   //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
147
148    internal_condition &internal_cond()
149    {  return *static_cast<internal_condition*>(m_shmem.get_user_address()); }
150
151    friend class boost::interprocess::ipcdetail::interprocess_tester;
152    void dont_close_on_destruction();
153
154    typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
155    open_create_impl_t m_shmem;
156
157    template <class T, class Arg> friend class boost::interprocess::ipcdetail::named_creation_functor;
158    typedef boost::interprocess::ipcdetail::named_creation_functor<internal_condition> construct_func_t;
159    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
160 };
161
162 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
163
164 inline shm_named_condition::~shm_named_condition()
165 {}
166
167 inline shm_named_condition::shm_named_condition(create_only_t, const char *name, const permissions &perm)
168    :  m_shmem  (create_only
169                ,name
170                ,sizeof(internal_condition) +
171                   open_create_impl_t::ManagedOpenOrCreateUserOffset
172                ,read_write
173                ,0
174                ,construct_func_t(DoCreate)
175                ,perm)
176 {}
177
178 inline shm_named_condition::shm_named_condition(open_or_create_t, const char *name, const permissions &perm)
179    :  m_shmem  (open_or_create
180                ,name
181                ,sizeof(internal_condition) +
182                   open_create_impl_t::ManagedOpenOrCreateUserOffset
183                ,read_write
184                ,0
185                ,construct_func_t(DoOpenOrCreate)
186                ,perm)
187 {}
188
189 inline shm_named_condition::shm_named_condition(open_only_t, const char *name)
190    :  m_shmem  (open_only
191                ,name
192                ,read_write
193                ,0
194                ,construct_func_t(DoOpen))
195 {}
196
197 inline void shm_named_condition::dont_close_on_destruction()
198 {  interprocess_tester::dont_close_on_destruction(m_shmem);  }
199
200 inline void shm_named_condition::notify_one()
201 {  this->internal_cond().notify_one(); }
202
203 inline void shm_named_condition::notify_all()
204 {  this->internal_cond().notify_all(); }
205
206 template <typename L>
207 inline void shm_named_condition::wait(L& lock)
208 {  this->internal_cond().wait(lock); }
209
210 template <typename L, typename Pr>
211 inline void shm_named_condition::wait(L& lock, Pr pred)
212 {  this->internal_cond().wait(lock, pred); }
213
214 template <typename L>
215 inline bool shm_named_condition::timed_wait
216    (L& lock, const boost::posix_time::ptime &abs_time)
217 {  return this->internal_cond().timed_wait(lock, abs_time); }
218
219 template <typename L, typename Pr>
220 inline bool shm_named_condition::timed_wait
221    (L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
222 {  return this->internal_cond().timed_wait(lock, abs_time, pred); }
223
224 inline bool shm_named_condition::remove(const char *name)
225 {  return shared_memory_object::remove(name); }
226
227 #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
228
229 }  //namespace ipcdetail
230 }  //namespace interprocess
231 }  //namespace boost
232
233 #include <boost/interprocess/detail/config_end.hpp>
234
235 #endif // BOOST_INTERPROCESS_SHM_NAMED_CONDITION_HPP