1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2012-2013. 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_SYNC_DETAIL_COMMON_ALGORITHMS_HPP 12 #define BOOST_INTERPROCESS_SYNC_DETAIL_COMMON_ALGORITHMS_HPP 13 14 #ifndef BOOST_CONFIG_HPP 15 # include <boost/config.hpp> 16 #endif 17 # 18 #if defined(BOOST_HAS_PRAGMA_ONCE) 19 # pragma once 20 #endif 21 22 #include <boost/interprocess/detail/config_begin.hpp> 23 #include <boost/interprocess/detail/workaround.hpp> 24 25 #include <boost/interprocess/sync/spin/wait.hpp> 26 27 namespace boost { 28 namespace interprocess { 29 namespace ipcdetail { 30 31 template<class MutexType> try_based_timed_lock(MutexType & m,const boost::posix_time::ptime & abs_time)32bool try_based_timed_lock(MutexType &m, const boost::posix_time::ptime &abs_time) 33 { 34 //Same as lock() 35 if(abs_time.is_pos_infinity()){ 36 m.lock(); 37 return true; 38 } 39 //Always try to lock to achieve POSIX guarantees: 40 // "Under no circumstance shall the function fail with a timeout if the mutex 41 // can be locked immediately. The validity of the abs_timeout parameter need not 42 // be checked if the mutex can be locked immediately." 43 else if(m.try_lock()){ 44 return true; 45 } 46 else{ 47 spin_wait swait; 48 while(microsec_clock::universal_time() < abs_time){ 49 if(m.try_lock()){ 50 return true; 51 } 52 swait.yield(); 53 } 54 return false; 55 } 56 } 57 58 template<class MutexType> try_based_lock(MutexType & m)59void try_based_lock(MutexType &m) 60 { 61 if(!m.try_lock()){ 62 spin_wait swait; 63 do{ 64 if(m.try_lock()){ 65 break; 66 } 67 else{ 68 swait.yield(); 69 } 70 } 71 while(1); 72 } 73 } 74 75 template<class MutexType> timeout_when_locking_aware_lock(MutexType & m)76void timeout_when_locking_aware_lock(MutexType &m) 77 { 78 #ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING 79 boost::posix_time::ptime wait_time 80 = microsec_clock::universal_time() 81 + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS); 82 if (!m.timed_lock(wait_time)) 83 { 84 throw interprocess_exception(timeout_when_locking_error 85 , "Interprocess mutex timeout when locking. Possible deadlock: " 86 "owner died without unlocking?"); 87 } 88 #else 89 m.lock(); 90 #endif 91 } 92 93 } //namespace ipcdetail 94 } //namespace interprocess 95 } //namespace boost 96 97 #include <boost/interprocess/detail/config_end.hpp> 98 99 #endif //BOOST_INTERPROCESS_SYNC_DETAIL_COMMON_ALGORITHMS_HPP 100