common_algorithms.hpp 2.7 KB

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