File indexing completed on 2025-01-18 09:38:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
0012 #define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024
0025 #include <boost/interprocess/sync/cv_status.hpp>
0026 #include <boost/interprocess/creation_tags.hpp>
0027 #include <boost/interprocess/permissions.hpp>
0028 #include <boost/interprocess/detail/interprocess_tester.hpp>
0029 #include <boost/interprocess/sync/windows/named_sync.hpp>
0030 #include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
0031 #include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
0032
0033 namespace boost {
0034 namespace interprocess {
0035 namespace ipcdetail {
0036
0037 template<class CharT>
0038 struct named_cond_callbacks_str;
0039
0040 template<>
0041 struct named_cond_callbacks_str<char>
0042 {
0043 static const char* ipc_cond()
0044 { return "Global\\bipc.cond."; }
0045
0046 static const char* bq()
0047 { return "_bq"; }
0048
0049 static const char* bl()
0050 { return "_bl"; }
0051
0052 static const char* ul()
0053 { return "_ul"; }
0054 };
0055
0056 template<>
0057 struct named_cond_callbacks_str<wchar_t>
0058 {
0059 static const wchar_t* ipc_cond()
0060 { return L"Global\\bipc.cond."; }
0061
0062 static const wchar_t* bq()
0063 { return L"_bq"; }
0064
0065 static const wchar_t* bl()
0066 { return L"_bl"; }
0067
0068 static const wchar_t* ul()
0069 { return L"_ul"; }
0070 };
0071
0072 class winapi_named_condition_any
0073 {
0074 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0075
0076
0077 winapi_named_condition_any();
0078 winapi_named_condition_any(const winapi_named_condition_any &);
0079 winapi_named_condition_any &operator=(const winapi_named_condition_any &);
0080 #endif
0081
0082 public:
0083 winapi_named_condition_any
0084 (create_only_t, const char *name, const permissions &perm = permissions())
0085 : m_condition_data()
0086 {
0087 named_cond_callbacks callbacks(m_condition_data.get_members());
0088 m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
0089 }
0090
0091 winapi_named_condition_any
0092 (open_or_create_t, const char *name, const permissions &perm = permissions())
0093 : m_condition_data()
0094 {
0095 named_cond_callbacks callbacks(m_condition_data.get_members());
0096 m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
0097 }
0098
0099 winapi_named_condition_any(open_only_t, const char *name)
0100 : m_condition_data()
0101 {
0102 named_cond_callbacks callbacks(m_condition_data.get_members());
0103 m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
0104 }
0105
0106 #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0107
0108 winapi_named_condition_any
0109 (create_only_t, const wchar_t *name, const permissions &perm = permissions())
0110 : m_condition_data()
0111 {
0112 named_cond_callbacks callbacks(m_condition_data.get_members());
0113 m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
0114 }
0115
0116 winapi_named_condition_any
0117 (open_or_create_t, const wchar_t *name, const permissions &perm = permissions())
0118 : m_condition_data()
0119 {
0120 named_cond_callbacks callbacks(m_condition_data.get_members());
0121 m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
0122 }
0123
0124 winapi_named_condition_any(open_only_t, const wchar_t *name)
0125 : m_condition_data()
0126 {
0127 named_cond_callbacks callbacks(m_condition_data.get_members());
0128 m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
0129 }
0130
0131 #endif
0132
0133 ~winapi_named_condition_any()
0134 {
0135 named_cond_callbacks callbacks(m_condition_data.get_members());
0136 m_named_sync.close(callbacks);
0137 }
0138
0139 void notify_one()
0140 { m_condition_data.notify_one(); }
0141
0142 void notify_all()
0143 { m_condition_data.notify_all(); }
0144
0145 template <typename L, typename TimePoint>
0146 bool timed_wait(L& lock, const TimePoint &abs_time)
0147 { return m_condition_data.timed_wait(lock, abs_time); }
0148
0149 template <typename L, typename TimePoint, typename Pr>
0150 bool timed_wait(L& lock, const TimePoint &abs_time, Pr pred)
0151 { return m_condition_data.timed_wait(lock, abs_time, pred); }
0152
0153 template <typename L>
0154 void wait(L& lock)
0155 { m_condition_data.wait(lock); }
0156
0157 template <typename L, typename Pr>
0158 void wait(L& lock, Pr pred)
0159 { m_condition_data.wait(lock, pred); }
0160
0161 template <typename L, class TimePoint>
0162 cv_status wait_until(L& lock, const TimePoint &abs_time)
0163 { return this->timed_wait(lock, abs_time) ? cv_status::no_timeout : cv_status::timeout; }
0164
0165 template <typename L, class TimePoint, typename Pr>
0166 bool wait_until(L& lock, const TimePoint &abs_time, Pr pred)
0167 { return this->timed_wait(lock, abs_time, pred); }
0168
0169 template <typename L, class Duration>
0170 cv_status wait_for(L& lock, const Duration &dur)
0171 { return this->wait_until(lock, ipcdetail::duration_to_ustime(dur)); }
0172
0173 template <typename L, class Duration, typename Pr>
0174 bool wait_for(L& lock, const Duration &dur, Pr pred)
0175 { return this->wait_until(lock, ipcdetail::duration_to_ustime(dur), pred); }
0176
0177 static bool remove(const char *name)
0178 { return windows_named_sync::remove(name); }
0179
0180 static bool remove(const wchar_t *name)
0181 { return windows_named_sync::remove(name); }
0182
0183 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0184 private:
0185
0186 void dont_close_on_destruction()
0187 {}
0188
0189 friend class interprocess_tester;
0190
0191 struct condition_data
0192 {
0193 typedef boost::int32_t integer_type;
0194 typedef winapi_semaphore_wrapper semaphore_type;
0195 typedef winapi_mutex_wrapper mutex_type;
0196
0197 integer_type &get_nwaiters_blocked()
0198 { return m_nwaiters_blocked; }
0199
0200 integer_type &get_nwaiters_gone()
0201 { return m_nwaiters_gone; }
0202
0203 integer_type &get_nwaiters_to_unblock()
0204 { return m_nwaiters_to_unblock; }
0205
0206 semaphore_type &get_sem_block_queue()
0207 { return m_sem_block_queue; }
0208
0209 semaphore_type &get_sem_block_lock()
0210 { return m_sem_block_lock; }
0211
0212 mutex_type &get_mtx_unblock_lock()
0213 { return m_mtx_unblock_lock; }
0214
0215 integer_type m_nwaiters_blocked;
0216 integer_type m_nwaiters_gone;
0217 integer_type m_nwaiters_to_unblock;
0218 winapi_semaphore_wrapper m_sem_block_queue;
0219 winapi_semaphore_wrapper m_sem_block_lock;
0220 winapi_mutex_wrapper m_mtx_unblock_lock;
0221 };
0222
0223
0224 class named_cond_callbacks : public windows_named_sync_interface
0225 {
0226 typedef __int64 sem_count_t;
0227 mutable sem_count_t sem_counts [2];
0228
0229 public:
0230 named_cond_callbacks(condition_data &cond_data)
0231 : m_condition_data(cond_data)
0232 {}
0233
0234 virtual std::size_t get_data_size() const BOOST_OVERRIDE
0235 { return sizeof(sem_counts); }
0236
0237 virtual const void *buffer_with_final_data_to_file() BOOST_OVERRIDE
0238 {
0239 sem_counts[0] = m_condition_data.m_sem_block_queue.value();
0240 sem_counts[1] = m_condition_data.m_sem_block_lock.value();
0241 return &sem_counts;
0242 }
0243
0244 virtual const void *buffer_with_init_data_to_file() BOOST_OVERRIDE
0245 {
0246 sem_counts[0] = 0;
0247 sem_counts[1] = 1;
0248 return &sem_counts;
0249 }
0250
0251 virtual void *buffer_to_store_init_data_from_file() BOOST_OVERRIDE
0252 { return &sem_counts; }
0253
0254 virtual bool open(create_enum_t op, const char *id_name) BOOST_OVERRIDE
0255 { return this->open_impl(op, id_name); }
0256
0257 virtual bool open(create_enum_t op, const wchar_t *id_name) BOOST_OVERRIDE
0258 { return this->open_impl(op, id_name); }
0259
0260 virtual void close() BOOST_OVERRIDE
0261 {
0262 m_condition_data.m_sem_block_queue.close();
0263 m_condition_data.m_sem_block_lock.close();
0264 m_condition_data.m_mtx_unblock_lock.close();
0265 m_condition_data.m_nwaiters_blocked = 0;
0266 m_condition_data.m_nwaiters_gone = 0;
0267 m_condition_data.m_nwaiters_to_unblock = 0;
0268 }
0269
0270 virtual ~named_cond_callbacks() BOOST_OVERRIDE
0271 {}
0272
0273 private:
0274
0275 template<class CharT>
0276 bool open_impl(create_enum_t, const CharT *id_name)
0277 {
0278 typedef named_cond_callbacks_str<CharT> str_t;
0279 m_condition_data.m_nwaiters_blocked = 0;
0280 m_condition_data.m_nwaiters_gone = 0;
0281 m_condition_data.m_nwaiters_to_unblock = 0;
0282
0283
0284
0285
0286 permissions perm;
0287 perm.set_unrestricted();
0288 std::basic_string<CharT> aux_str = str_t::ipc_cond();
0289 aux_str += id_name;
0290 std::size_t pos = aux_str.size();
0291
0292
0293 aux_str += str_t::bq();
0294 winapi_semaphore_wrapper sem_block_queue;
0295 bool created;
0296 if(!sem_block_queue.open_or_create
0297 (aux_str.c_str(), static_cast<long>(sem_counts[0]), winapi_semaphore_wrapper::MaxCount, perm, created))
0298 return false;
0299 aux_str.erase(pos);
0300
0301
0302 aux_str += str_t::bl();
0303 winapi_semaphore_wrapper sem_block_lock;
0304 if(!sem_block_lock.open_or_create
0305 (aux_str.c_str(), static_cast<long>(sem_counts[1]), winapi_semaphore_wrapper::MaxCount, perm, created))
0306 return false;
0307 aux_str.erase(pos);
0308
0309
0310 aux_str += str_t::ul();
0311 winapi_mutex_wrapper mtx_unblock_lock;
0312 if(!mtx_unblock_lock.open_or_create(aux_str.c_str(), perm))
0313 return false;
0314
0315
0316 m_condition_data.m_sem_block_queue.swap(sem_block_queue);
0317 m_condition_data.m_sem_block_lock.swap(sem_block_lock);
0318 m_condition_data.m_mtx_unblock_lock.swap(mtx_unblock_lock);
0319 return true;
0320 }
0321
0322 condition_data &m_condition_data;
0323 };
0324
0325 windows_named_sync m_named_sync;
0326 ipcdetail::condition_8a_wrapper<condition_data> m_condition_data;
0327 #endif
0328 };
0329
0330 }
0331 }
0332 }
0333
0334 #include <boost/interprocess/detail/config_end.hpp>
0335
0336 #endif