comparison DEPENDENCIES/generic/include/boost/interprocess/detail/robust_emulation.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
9 ////////////////////////////////////////////////////////////////////////////// 9 //////////////////////////////////////////////////////////////////////////////
10 10
11 #ifndef BOOST_INTERPROCESS_ROBUST_EMULATION_HPP 11 #ifndef BOOST_INTERPROCESS_ROBUST_EMULATION_HPP
12 #define BOOST_INTERPROCESS_ROBUST_EMULATION_HPP 12 #define BOOST_INTERPROCESS_ROBUST_EMULATION_HPP
13 13
14 #if defined(_MSC_VER)&&(_MSC_VER>=1200) 14 #ifndef BOOST_CONFIG_HPP
15 # include <boost/config.hpp>
16 #endif
17 #
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
15 #pragma once 19 #pragma once
16 #endif 20 #endif
17 21
18 #include <boost/interprocess/detail/config_begin.hpp> 22 #include <boost/interprocess/detail/config_begin.hpp>
19 #include <boost/interprocess/detail/workaround.hpp> 23 #include <boost/interprocess/detail/workaround.hpp>
20 #include <boost/interprocess/sync/interprocess_mutex.hpp> 24 #include <boost/interprocess/sync/interprocess_mutex.hpp>
21 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp> 25 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
22 #include <boost/interprocess/detail/atomic.hpp> 26 #include <boost/interprocess/detail/atomic.hpp>
23 #include <boost/interprocess/detail/os_file_functions.hpp> 27 #include <boost/interprocess/detail/os_file_functions.hpp>
24 #include <boost/interprocess/detail/tmp_dir_helpers.hpp> 28 #include <boost/interprocess/detail/shared_dir_helpers.hpp>
25 #include <boost/interprocess/detail/intermodule_singleton.hpp> 29 #include <boost/interprocess/detail/intermodule_singleton.hpp>
30 #include <boost/interprocess/detail/portable_intermodule_singleton.hpp>
26 #include <boost/interprocess/exceptions.hpp> 31 #include <boost/interprocess/exceptions.hpp>
27 #include <boost/interprocess/sync/spin/wait.hpp> 32 #include <boost/interprocess/sync/spin/wait.hpp>
33 #include <boost/interprocess/sync/detail/common_algorithms.hpp>
28 #include <string> 34 #include <string>
29 35
30 namespace boost{ 36 namespace boost{
31 namespace interprocess{ 37 namespace interprocess{
32 namespace ipcdetail{ 38 namespace ipcdetail{
60 inline const char *robust_lock_prefix() 66 inline const char *robust_lock_prefix()
61 { return "lck"; } 67 { return "lck"; }
62 68
63 inline void robust_lock_path(std::string &s) 69 inline void robust_lock_path(std::string &s)
64 { 70 {
65 tmp_folder(s); 71 get_shared_dir(s);
66 s += "/"; 72 s += "/";
67 s += robust_lock_subdir_path(); 73 s += robust_lock_subdir_path();
68 } 74 }
69 75
70 inline void create_and_get_robust_lock_file_path(std::string &s, OS_process_id_t pid) 76 inline void create_and_get_robust_lock_file_path(std::string &s, OS_process_id_t pid)
213 : mtx(), owner(get_invalid_process_id()), state(correct_state) 219 : mtx(), owner(get_invalid_process_id()), state(correct_state)
214 {} 220 {}
215 221
216 template<class Mutex> 222 template<class Mutex>
217 inline void robust_spin_mutex<Mutex>::lock() 223 inline void robust_spin_mutex<Mutex>::lock()
218 { 224 { try_based_lock(*this); }
219 //If the mutex is broken (recovery didn't call consistent()),
220 //then throw an exception
221 if(atomic_read32(&this->state) == broken_state){
222 throw interprocess_exception(lock_error, "Broken id");
223 }
224
225 //This function provokes intermodule_singleton instantiation
226 if(!this->lock_own_unique_file()){
227 throw interprocess_exception(lock_error, "Broken id");
228 }
229
230 //Now the logic. Try to lock, if successful mark the owner
231 //if it fails, start recovery logic
232 spin_wait swait;
233 while(1){
234 if (mtx.try_lock()){
235 atomic_write32(&this->owner, get_current_process_id());
236 break;
237 }
238 else{
239 //Do the dead owner checking each spin_threshold lock tries
240 swait.yield();
241 if(0 == (swait.count() & 255u)){
242 //Check if owner dead and take ownership if possible
243 if(this->robust_check()){
244 break;
245 }
246 }
247 }
248 }
249 }
250 225
251 template<class Mutex> 226 template<class Mutex>
252 inline bool robust_spin_mutex<Mutex>::try_lock() 227 inline bool robust_spin_mutex<Mutex>::try_lock()
253 { 228 {
254 //Same as lock() but without spinning 229 //Same as lock() but without spinning
275 } 250 }
276 251
277 template<class Mutex> 252 template<class Mutex>
278 inline bool robust_spin_mutex<Mutex>::timed_lock 253 inline bool robust_spin_mutex<Mutex>::timed_lock
279 (const boost::posix_time::ptime &abs_time) 254 (const boost::posix_time::ptime &abs_time)
280 { 255 { return try_based_timed_lock(*this, abs_time); }
281 //Same as lock() but with an additional timeout
282 if(abs_time == boost::posix_time::pos_infin){
283 this->lock();
284 return true;
285 }
286 //Obtain current count and target time
287 boost::posix_time::ptime now = microsec_clock::universal_time();
288
289 if(now >= abs_time)
290 return this->try_lock();
291
292 spin_wait swait;
293 do{
294 if(this->try_lock()){
295 break;
296 }
297 now = microsec_clock::universal_time();
298
299 if(now >= abs_time){
300 return this->try_lock();
301 }
302 // relinquish current time slice
303 swait.yield();
304 }while (true);
305
306 return true;
307 }
308 256
309 template<class Mutex> 257 template<class Mutex>
310 inline void robust_spin_mutex<Mutex>::owner_to_filename(boost::uint32_t own, std::string &s) 258 inline void robust_spin_mutex<Mutex>::owner_to_filename(boost::uint32_t own, std::string &s)
311 { 259 {
312 robust_emulation_helpers::create_and_get_robust_lock_file_path(s, own); 260 robust_emulation_helpers::create_and_get_robust_lock_file_path(s, own);
400 template<class Mutex> 348 template<class Mutex>
401 inline bool robust_spin_mutex<Mutex>::previous_owner_dead() 349 inline bool robust_spin_mutex<Mutex>::previous_owner_dead()
402 { 350 {
403 //Notifies if a owner recovery has been performed in the last lock() 351 //Notifies if a owner recovery has been performed in the last lock()
404 return atomic_read32(&this->state) == fixing_state; 352 return atomic_read32(&this->state) == fixing_state;
405 }; 353 }
406 354
407 template<class Mutex> 355 template<class Mutex>
408 inline void robust_spin_mutex<Mutex>::unlock() 356 inline void robust_spin_mutex<Mutex>::unlock()
409 { 357 {
410 //If in "fixing" state, unlock and mark the mutex as unrecoverable 358 //If in "fixing" state, unlock and mark the mutex as unrecoverable