interprocess_semaphore.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2012. 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_SEMAPHORE_HPP
  11. #define BOOST_INTERPROCESS_SEMAPHORE_HPP
  12. /// @cond
  13. #if (defined _MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif
  16. #include <boost/interprocess/detail/config_begin.hpp>
  17. #include <boost/interprocess/detail/workaround.hpp>
  18. #include <boost/interprocess/creation_tags.hpp>
  19. #include <boost/interprocess/exceptions.hpp>
  20. #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
  21. #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \
  22. (defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES))
  23. #include <boost/interprocess/sync/posix/semaphore.hpp>
  24. #define BOOST_INTERPROCESS_USE_POSIX
  25. //Experimental...
  26. #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
  27. #include <boost/interprocess/sync/windows/semaphore.hpp>
  28. #define BOOST_INTERPROCESS_USE_WINDOWS
  29. #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  30. #include <boost/interprocess/sync/spin/semaphore.hpp>
  31. #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
  32. #endif
  33. /// @endcond
  34. //!\file
  35. //!Describes a interprocess_semaphore class for inter-process synchronization
  36. namespace boost {
  37. namespace interprocess {
  38. //!Wraps a interprocess_semaphore that can be placed in shared memory and can be
  39. //!shared between processes. Allows timed lock tries
  40. class interprocess_semaphore
  41. {
  42. /// @cond
  43. //Non-copyable
  44. interprocess_semaphore(const interprocess_semaphore &);
  45. interprocess_semaphore &operator=(const interprocess_semaphore &);
  46. /// @endcond
  47. public:
  48. //!Creates a interprocess_semaphore with the given initial count.
  49. //!interprocess_exception if there is an error.*/
  50. interprocess_semaphore(unsigned int initialCount);
  51. //!Destroys the interprocess_semaphore.
  52. //!Does not throw
  53. ~interprocess_semaphore();
  54. //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
  55. //!for the interprocess_semaphore, then one of these processes will return successfully from
  56. //!its wait function. If there is an error an interprocess_exception exception is thrown.
  57. void post();
  58. //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
  59. //!then the calling process/thread blocks until it can decrement the counter.
  60. //!If there is an error an interprocess_exception exception is thrown.
  61. void wait();
  62. //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
  63. //!and returns true. If the value is not greater than zero returns false.
  64. //!If there is an error an interprocess_exception exception is thrown.
  65. bool try_wait();
  66. //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
  67. //!than zero and returns true. Otherwise, waits for the interprocess_semaphore
  68. //!to the posted or the timeout expires. If the timeout expires, the
  69. //!function returns false. If the interprocess_semaphore is posted the function
  70. //!returns true. If there is an error throws sem_exception
  71. bool timed_wait(const boost::posix_time::ptime &abs_time);
  72. //!Returns the interprocess_semaphore count
  73. // int get_count() const;
  74. /// @cond
  75. private:
  76. #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
  77. #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
  78. ipcdetail::spin_semaphore m_sem;
  79. #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
  80. #undef BOOST_INTERPROCESS_USE_WINDOWS
  81. ipcdetail::windows_semaphore m_sem;
  82. #else
  83. #undef BOOST_INTERPROCESS_USE_POSIX
  84. ipcdetail::posix_semaphore m_sem;
  85. #endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
  86. /// @endcond
  87. };
  88. } //namespace interprocess {
  89. } //namespace boost {
  90. namespace boost {
  91. namespace interprocess {
  92. inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount)
  93. : m_sem(initialCount)
  94. {}
  95. inline interprocess_semaphore::~interprocess_semaphore(){}
  96. inline void interprocess_semaphore::wait()
  97. {
  98. #ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
  99. boost::posix_time::ptime wait_time
  100. = boost::posix_time::microsec_clock::universal_time()
  101. + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
  102. if (!m_sem.timed_wait(wait_time))
  103. {
  104. throw interprocess_exception(timeout_when_waiting_error, "Interprocess semaphore timeout when waiting. Possible deadlock: owner died without posting?");
  105. }
  106. #else
  107. m_sem.wait();
  108. #endif
  109. }
  110. inline bool interprocess_semaphore::try_wait()
  111. { return m_sem.try_wait(); }
  112. inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
  113. { return m_sem.timed_wait(abs_time); }
  114. inline void interprocess_semaphore::post()
  115. { m_sem.post(); }
  116. } //namespace interprocess {
  117. } //namespace boost {
  118. #include <boost/interprocess/detail/config_end.hpp>
  119. #endif //BOOST_INTERPROCESS_SEMAPHORE_HPP