diff options
Diffstat (limited to 'boost/interprocess/detail/robust_emulation.hpp')
-rw-r--r-- | boost/interprocess/detail/robust_emulation.hpp | 96 |
1 files changed, 19 insertions, 77 deletions
diff --git a/boost/interprocess/detail/robust_emulation.hpp b/boost/interprocess/detail/robust_emulation.hpp index 1feb42dc35..d586db5071 100644 --- a/boost/interprocess/detail/robust_emulation.hpp +++ b/boost/interprocess/detail/robust_emulation.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2010-2011. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2010-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,7 +11,7 @@ #ifndef BOOST_INTERPROCESS_ROBUST_EMULATION_HPP #define BOOST_INTERPROCESS_ROBUST_EMULATION_HPP -#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#if defined(_MSC_VER) #pragma once #endif @@ -21,9 +21,12 @@ #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp> #include <boost/interprocess/detail/atomic.hpp> #include <boost/interprocess/detail/os_file_functions.hpp> -#include <boost/interprocess/detail/tmp_dir_helpers.hpp> +#include <boost/interprocess/detail/shared_dir_helpers.hpp> #include <boost/interprocess/detail/intermodule_singleton.hpp> +#include <boost/interprocess/detail/portable_intermodule_singleton.hpp> #include <boost/interprocess/exceptions.hpp> +#include <boost/interprocess/sync/spin/wait.hpp> +#include <boost/interprocess/sync/detail/common_algorithms.hpp> #include <string> namespace boost{ @@ -61,7 +64,7 @@ inline const char *robust_lock_prefix() inline void robust_lock_path(std::string &s) { - tmp_folder(s); + get_shared_dir(s); s += "/"; s += robust_lock_subdir_path(); } @@ -132,7 +135,7 @@ class robust_mutex_lock_file throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: create_file filed with unexpected error"); } } - } + } ~robust_mutex_lock_file() { @@ -197,8 +200,8 @@ class robust_spin_mutex bool lock_own_unique_file(); bool robust_check(); bool check_if_owner_dead_and_take_ownership_atomically(); - bool is_owner_dead(boost::uint32_t owner); - void owner_to_filename(boost::uint32_t owner, std::string &s); + bool is_owner_dead(boost::uint32_t own); + void owner_to_filename(boost::uint32_t own, std::string &s); //The real mutex Mutex mtx; //The pid of the owner @@ -214,42 +217,7 @@ inline robust_spin_mutex<Mutex>::robust_spin_mutex() template<class Mutex> inline void robust_spin_mutex<Mutex>::lock() -{ - //If the mutex is broken (recovery didn't call consistent()), - //then throw an exception - if(atomic_read32(&this->state) == broken_state){ - throw interprocess_exception(lock_error, "Broken id"); - } - - //This function provokes intermodule_singleton instantiation - if(!this->lock_own_unique_file()){ - throw interprocess_exception(lock_error, "Broken id"); - } - - //Now the logic. Try to lock, if successful mark the owner - //if it fails, start recovery logic - unsigned int spin_count = 0; - while(1){ - if (mtx.try_lock()){ - atomic_write32(&this->owner, get_current_process_id()); - break; - } - else{ - //Do the dead owner checking each spin_threshold lock tries - ipcdetail::thread_yield(); - ++spin_count; - if(spin_count > spin_threshold){ - //Check if owner dead and take ownership if possible - if(!this->robust_check()){ - spin_count = 0; - } - else{ - break; - } - } - } - } -} +{ try_based_lock(*this); } template<class Mutex> inline bool robust_spin_mutex<Mutex>::try_lock() @@ -280,38 +248,12 @@ inline bool robust_spin_mutex<Mutex>::try_lock() template<class Mutex> inline bool robust_spin_mutex<Mutex>::timed_lock (const boost::posix_time::ptime &abs_time) -{ - //Same as lock() but with an additional timeout - if(abs_time == boost::posix_time::pos_infin){ - this->lock(); - return true; - } - //Obtain current count and target time - boost::posix_time::ptime now = microsec_clock::universal_time(); - - if(now >= abs_time) - return this->try_lock(); - - do{ - if(this->try_lock()){ - break; - } - now = microsec_clock::universal_time(); - - if(now >= abs_time){ - return this->try_lock(); - } - // relinquish current time slice - ipcdetail::thread_yield(); - }while (true); - - return true; -} +{ return try_based_timed_lock(*this, abs_time); } template<class Mutex> -inline void robust_spin_mutex<Mutex>::owner_to_filename(boost::uint32_t owner, std::string &s) +inline void robust_spin_mutex<Mutex>::owner_to_filename(boost::uint32_t own, std::string &s) { - robust_emulation_helpers::create_and_get_robust_lock_file_path(s, owner); + robust_emulation_helpers::create_and_get_robust_lock_file_path(s, own); } template<class Mutex> @@ -324,7 +266,7 @@ inline bool robust_spin_mutex<Mutex>::robust_check() return false; } atomic_write32(&this->state, fixing_state); - return true; + return true; } template<class Mutex> @@ -349,16 +291,16 @@ inline bool robust_spin_mutex<Mutex>::check_if_owner_dead_and_take_ownership_ato } template<class Mutex> -inline bool robust_spin_mutex<Mutex>::is_owner_dead(boost::uint32_t owner) +inline bool robust_spin_mutex<Mutex>::is_owner_dead(boost::uint32_t own) { //If owner is an invalid id, then it's clear it's dead - if(owner == (boost::uint32_t)get_invalid_process_id()){ + if(own == (boost::uint32_t)get_invalid_process_id()){ return true; } //Obtain the lock filename of the owner field std::string file; - this->owner_to_filename(owner, file); + this->owner_to_filename(own, file); //Now the logic is to open and lock it file_handle_t fhnd = open_existing_file(file.c_str(), read_write); @@ -404,7 +346,7 @@ inline bool robust_spin_mutex<Mutex>::previous_owner_dead() { //Notifies if a owner recovery has been performed in the last lock() return atomic_read32(&this->state) == fixing_state; -}; +} template<class Mutex> inline void robust_spin_mutex<Mutex>::unlock() |