strand.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //
  2. // strand.hpp
  3. // ~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_STRAND_HPP
  11. #define BOOST_ASIO_STRAND_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/push_options.hpp>
  16. #include <boost/asio/io_service.hpp>
  17. #include <boost/asio/detail/strand_service.hpp>
  18. #include <boost/asio/detail/wrapped_handler.hpp>
  19. namespace boost {
  20. namespace asio {
  21. /// Provides serialised handler execution.
  22. /**
  23. * The io_service::strand class provides the ability to post and dispatch
  24. * handlers with the guarantee that none of those handlers will execute
  25. * concurrently.
  26. *
  27. * @par Thread Safety
  28. * @e Distinct @e objects: Safe.@n
  29. * @e Shared @e objects: Safe.
  30. *
  31. * @par Concepts:
  32. * Dispatcher.
  33. */
  34. class io_service::strand
  35. {
  36. public:
  37. /// Constructor.
  38. /**
  39. * Constructs the strand.
  40. *
  41. * @param io_service The io_service object that the strand will use to
  42. * dispatch handlers that are ready to be run.
  43. */
  44. explicit strand(boost::asio::io_service& io_service)
  45. : service_(boost::asio::use_service<
  46. boost::asio::detail::strand_service>(io_service))
  47. {
  48. service_.construct(impl_);
  49. }
  50. /// Destructor.
  51. /**
  52. * Destroys a strand.
  53. *
  54. * Handlers posted through the strand that have not yet been invoked will
  55. * still be dispatched in a way that meets the guarantee of non-concurrency.
  56. */
  57. ~strand()
  58. {
  59. service_.destroy(impl_);
  60. }
  61. /// (Deprecated: use get_io_service().) Get the io_service associated with
  62. /// the strand.
  63. /**
  64. * This function may be used to obtain the io_service object that the strand
  65. * uses to dispatch handlers for asynchronous operations.
  66. *
  67. * @return A reference to the io_service object that the strand will use to
  68. * dispatch handlers. Ownership is not transferred to the caller.
  69. */
  70. boost::asio::io_service& io_service()
  71. {
  72. return service_.get_io_service();
  73. }
  74. /// Get the io_service associated with the strand.
  75. /**
  76. * This function may be used to obtain the io_service object that the strand
  77. * uses to dispatch handlers for asynchronous operations.
  78. *
  79. * @return A reference to the io_service object that the strand will use to
  80. * dispatch handlers. Ownership is not transferred to the caller.
  81. */
  82. boost::asio::io_service& get_io_service()
  83. {
  84. return service_.get_io_service();
  85. }
  86. /// Request the strand to invoke the given handler.
  87. /**
  88. * This function is used to ask the strand to execute the given handler.
  89. *
  90. * The strand object guarantees that handlers posted or dispatched through
  91. * the strand will not be executed concurrently. The handler may be executed
  92. * inside this function if the guarantee can be met. If this function is
  93. * called from within a handler that was posted or dispatched through the same
  94. * strand, then the new handler will be executed immediately.
  95. *
  96. * The strand's guarantee is in addition to the guarantee provided by the
  97. * underlying io_service. The io_service guarantees that the handler will only
  98. * be called in a thread in which the io_service's run member function is
  99. * currently being invoked.
  100. *
  101. * @param handler The handler to be called. The strand will make a copy of the
  102. * handler object as required. The function signature of the handler must be:
  103. * @code void handler(); @endcode
  104. */
  105. template <typename Handler>
  106. void dispatch(Handler handler)
  107. {
  108. service_.dispatch(impl_, handler);
  109. }
  110. /// Request the strand to invoke the given handler and return
  111. /// immediately.
  112. /**
  113. * This function is used to ask the strand to execute the given handler, but
  114. * without allowing the strand to call the handler from inside this function.
  115. *
  116. * The strand object guarantees that handlers posted or dispatched through
  117. * the strand will not be executed concurrently. The strand's guarantee is in
  118. * addition to the guarantee provided by the underlying io_service. The
  119. * io_service guarantees that the handler will only be called in a thread in
  120. * which the io_service's run member function is currently being invoked.
  121. *
  122. * @param handler The handler to be called. The strand will make a copy of the
  123. * handler object as required. The function signature of the handler must be:
  124. * @code void handler(); @endcode
  125. */
  126. template <typename Handler>
  127. void post(Handler handler)
  128. {
  129. service_.post(impl_, handler);
  130. }
  131. /// Create a new handler that automatically dispatches the wrapped handler
  132. /// on the strand.
  133. /**
  134. * This function is used to create a new handler function object that, when
  135. * invoked, will automatically pass the wrapped handler to the strand's
  136. * dispatch function.
  137. *
  138. * @param handler The handler to be wrapped. The strand will make a copy of
  139. * the handler object as required. The function signature of the handler must
  140. * be: @code void handler(A1 a1, ... An an); @endcode
  141. *
  142. * @return A function object that, when invoked, passes the wrapped handler to
  143. * the strand's dispatch function. Given a function object with the signature:
  144. * @code R f(A1 a1, ... An an); @endcode
  145. * If this function object is passed to the wrap function like so:
  146. * @code strand.wrap(f); @endcode
  147. * then the return value is a function object with the signature
  148. * @code void g(A1 a1, ... An an); @endcode
  149. * that, when invoked, executes code equivalent to:
  150. * @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode
  151. */
  152. template <typename Handler>
  153. #if defined(GENERATING_DOCUMENTATION)
  154. unspecified
  155. #else
  156. detail::wrapped_handler<strand, Handler>
  157. #endif
  158. wrap(Handler handler)
  159. {
  160. return detail::wrapped_handler<io_service::strand, Handler>(*this, handler);
  161. }
  162. private:
  163. boost::asio::detail::strand_service& service_;
  164. boost::asio::detail::strand_service::implementation_type impl_;
  165. };
  166. /// Typedef for backwards compatibility.
  167. typedef boost::asio::io_service::strand strand;
  168. } // namespace asio
  169. } // namespace boost
  170. #include <boost/asio/detail/pop_options.hpp>
  171. #endif // BOOST_ASIO_STRAND_HPP