interprocess_semaphore.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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/detail/posix_time_types_wrk.hpp>
  25. #include <boost/interprocess/sync/detail/locks.hpp>
  26. #include <boost/interprocess/sync/detail/common_algorithms.hpp>
  27. #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \
  28. defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && \
  29. defined(BOOST_INTERPROCESS_POSIX_UNNAMED_SEMAPHORES)
  30. #include <boost/interprocess/sync/posix/semaphore.hpp>
  31. #define BOOST_INTERPROCESS_SEMAPHORE_USE_POSIX
  32. #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
  33. //Experimental...
  34. #include <boost/interprocess/sync/windows/semaphore.hpp>
  35. #define BOOST_INTERPROCESS_SEMAPHORE_USE_WINAPI
  36. #else
  37. //spin_semaphore is used
  38. #include <boost/interprocess/sync/spin/semaphore.hpp>
  39. #endif
  40. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  41. //!\file
  42. //!Describes a interprocess_semaphore class for inter-process synchronization
  43. namespace boost {
  44. namespace interprocess {
  45. //!Wraps a interprocess_semaphore that can be placed in shared memory and can be
  46. //!shared between processes. Allows timed lock tries
  47. class interprocess_semaphore
  48. {
  49. #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  50. //Non-copyable
  51. interprocess_semaphore(const interprocess_semaphore &);
  52. interprocess_semaphore &operator=(const interprocess_semaphore &);
  53. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  54. public:
  55. //!Creates a interprocess_semaphore with the given initial count.
  56. //!interprocess_exception if there is an error.*/
  57. interprocess_semaphore(unsigned int initialCount);
  58. //!Destroys the interprocess_semaphore.
  59. //!Does not throw
  60. ~interprocess_semaphore();
  61. //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
  62. //!for the interprocess_semaphore, then one of these processes will return successfully from
  63. //!its wait function. If there is an error an interprocess_exception exception is thrown.
  64. void post();
  65. //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
  66. //!then the calling process/thread blocks until it can decrement the counter.
  67. //!If there is an error an interprocess_exception exception is thrown.
  68. void wait();
  69. //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
  70. //!and returns true. If the value is not greater than zero returns false.
  71. //!If there is an error an interprocess_exception exception is thrown.
  72. bool try_wait();
  73. //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
  74. //!than zero and returns true. Otherwise, waits for the interprocess_semaphore
  75. //!to the posted or the timeout expires. If the timeout expires, the
  76. //!function returns false. If the interprocess_semaphore is posted the function
  77. //!returns true. If there is an error throws sem_exception
  78. bool timed_wait(const boost::posix_time::ptime &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. inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
  109. { return m_sem.timed_wait(abs_time); }
  110. inline void interprocess_semaphore::post()
  111. { m_sem.post(); }
  112. } //namespace interprocess {
  113. } //namespace boost {
  114. #include <boost/interprocess/detail/config_end.hpp>
  115. #endif //BOOST_INTERPROCESS_SEMAPHORE_HPP