interprocess_semaphore.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  13. #ifndef BOOST_CONFIG_HPP
  14. # include <boost/config.hpp>
  15. #endif
  16. #
  17. #if defined(BOOST_HAS_PRAGMA_ONCE)
  18. # pragma once
  19. #endif
  20. #include <boost/interprocess/detail/config_begin.hpp>
  21. #include <boost/interprocess/detail/workaround.hpp>
  22. #include <boost/interprocess/creation_tags.hpp>
  23. #include <boost/interprocess/exceptions.hpp>
  24. #include <boost/interprocess/sync/detail/locks.hpp>
  25. #include <boost/interprocess/sync/detail/common_algorithms.hpp>
  26. #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \
  27. defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && \
  28. defined(BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES)
  29. #include <boost/interprocess/sync/posix/semaphore.hpp>
  30. #define BOOST_INTERPROCESS_SEMAPHORE_USE_POSIX
  31. #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
  32. //Experimental...
  33. #include <boost/interprocess/sync/windows/semaphore.hpp>
  34. #define BOOST_INTERPROCESS_SEMAPHORE_USE_WINAPI
  35. #else
  36. //spin_semaphore is used
  37. #include <boost/interprocess/sync/spin/semaphore.hpp>
  38. #endif
  39. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  40. //!\file
  41. //!Describes a interprocess_semaphore class for inter-process synchronization
  42. namespace boost {
  43. namespace interprocess {
  44. //!Wraps a interprocess_semaphore that can be placed in shared memory and can be
  45. //!shared between processes. Allows timed lock tries
  46. class interprocess_semaphore
  47. {
  48. #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  49. //Non-copyable
  50. interprocess_semaphore(const interprocess_semaphore &);
  51. interprocess_semaphore &operator=(const interprocess_semaphore &);
  52. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  53. public:
  54. //!Creates a interprocess_semaphore with the given initial count.
  55. //!interprocess_exception if there is an error.*/
  56. interprocess_semaphore(unsigned int initialCount);
  57. //!Destroys the interprocess_semaphore.
  58. //!Does not throw
  59. ~interprocess_semaphore();
  60. //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
  61. //!for the interprocess_semaphore, then one of these processes will return successfully from
  62. //!its wait function. If there is an error an interprocess_exception exception is thrown.
  63. void post();
  64. //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
  65. //!then the calling process/thread blocks until it can decrement the counter.
  66. //!If there is an error an interprocess_exception exception is thrown.
  67. void wait();
  68. //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
  69. //!and returns true. If the value is not greater than zero returns false.
  70. //!If there is an error an interprocess_exception exception is thrown.
  71. bool try_wait();
  72. //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
  73. //!than zero and returns true. Otherwise, waits for the interprocess_semaphore
  74. //!to the posted or the timeout expires. If the timeout expires, the
  75. //!function returns false. If the interprocess_semaphore is posted the function
  76. //!returns true. If there is an error throws sem_exception
  77. template<class TimePoint>
  78. bool timed_wait(const TimePoint &abs_time);
  79. //!Returns the interprocess_semaphore count
  80. // int get_count() const;
  81. #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  82. private:
  83. #if defined(BOOST_INTERPROCESS_SEMAPHORE_USE_POSIX)
  84. typedef ipcdetail::posix_semaphore internal_sem_t;
  85. #elif defined(BOOST_INTERPROCESS_SEMAPHORE_USE_WINAPI)
  86. typedef ipcdetail::winapi_semaphore internal_sem_t;
  87. #else
  88. typedef ipcdetail::spin_semaphore internal_sem_t;
  89. #endif //#if defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION)
  90. internal_sem_t m_sem;
  91. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  92. };
  93. } //namespace interprocess {
  94. } //namespace boost {
  95. namespace boost {
  96. namespace interprocess {
  97. inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount)
  98. : m_sem(initialCount)
  99. {}
  100. inline interprocess_semaphore::~interprocess_semaphore(){}
  101. inline void interprocess_semaphore::wait()
  102. {
  103. ipcdetail::lock_to_wait<internal_sem_t> ltw(m_sem);
  104. timeout_when_locking_aware_lock(ltw);
  105. }
  106. inline bool interprocess_semaphore::try_wait()
  107. { return m_sem.try_wait(); }
  108. template<class TimePoint>
  109. inline bool interprocess_semaphore::timed_wait(const TimePoint &abs_time)
  110. { return m_sem.timed_wait(abs_time); }
  111. inline void interprocess_semaphore::post()
  112. { m_sem.post(); }
  113. } //namespace interprocess {
  114. } //namespace boost {
  115. #include <boost/interprocess/detail/config_end.hpp>
  116. #endif //BOOST_INTERPROCESS_SEMAPHORE_HPP