/Src/Dependencies/Boost/boost/asio/detail/impl/reactive_descriptor_service.ipp

http://hadesmem.googlecode.com/ · C++ Header · 205 lines · 149 code · 41 blank · 15 comment · 12 complexity · 310f71f117786e3695ff603510be46e0 MD5 · raw file

  1. //
  2. // detail/impl/reactive_descriptor_service.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2011 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_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP
  11. #define BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
  17. #include <boost/asio/error.hpp>
  18. #include <boost/asio/detail/reactive_descriptor_service.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. namespace detail {
  23. reactive_descriptor_service::reactive_descriptor_service(
  24. boost::asio::io_service& io_service)
  25. : reactor_(boost::asio::use_service<reactor>(io_service))
  26. {
  27. reactor_.init_task();
  28. }
  29. void reactive_descriptor_service::shutdown_service()
  30. {
  31. }
  32. void reactive_descriptor_service::construct(
  33. reactive_descriptor_service::implementation_type& impl)
  34. {
  35. impl.descriptor_ = -1;
  36. impl.state_ = 0;
  37. }
  38. void reactive_descriptor_service::move_construct(
  39. reactive_descriptor_service::implementation_type& impl,
  40. reactive_descriptor_service::implementation_type& other_impl)
  41. {
  42. impl.descriptor_ = other_impl.descriptor_;
  43. other_impl.descriptor_ = -1;
  44. impl.state_ = other_impl.state_;
  45. other_impl.state_ = 0;
  46. reactor_.move_descriptor(impl.descriptor_,
  47. impl.reactor_data_, other_impl.reactor_data_);
  48. }
  49. void reactive_descriptor_service::move_assign(
  50. reactive_descriptor_service::implementation_type& impl,
  51. reactive_descriptor_service& other_service,
  52. reactive_descriptor_service::implementation_type& other_impl)
  53. {
  54. destroy(impl);
  55. impl.descriptor_ = other_impl.descriptor_;
  56. other_impl.descriptor_ = -1;
  57. impl.state_ = other_impl.state_;
  58. other_impl.state_ = 0;
  59. other_service.reactor_.move_descriptor(impl.descriptor_,
  60. impl.reactor_data_, other_impl.reactor_data_);
  61. }
  62. void reactive_descriptor_service::destroy(
  63. reactive_descriptor_service::implementation_type& impl)
  64. {
  65. if (is_open(impl))
  66. {
  67. BOOST_ASIO_HANDLER_OPERATION(("descriptor", &impl, "close"));
  68. reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_,
  69. (impl.state_ & descriptor_ops::possible_dup) == 0);
  70. }
  71. boost::system::error_code ignored_ec;
  72. descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec);
  73. }
  74. boost::system::error_code reactive_descriptor_service::assign(
  75. reactive_descriptor_service::implementation_type& impl,
  76. const native_handle_type& native_descriptor, boost::system::error_code& ec)
  77. {
  78. if (is_open(impl))
  79. {
  80. ec = boost::asio::error::already_open;
  81. return ec;
  82. }
  83. if (int err = reactor_.register_descriptor(
  84. native_descriptor, impl.reactor_data_))
  85. {
  86. ec = boost::system::error_code(err,
  87. boost::asio::error::get_system_category());
  88. return ec;
  89. }
  90. impl.descriptor_ = native_descriptor;
  91. impl.state_ = descriptor_ops::possible_dup;
  92. ec = boost::system::error_code();
  93. return ec;
  94. }
  95. boost::system::error_code reactive_descriptor_service::close(
  96. reactive_descriptor_service::implementation_type& impl,
  97. boost::system::error_code& ec)
  98. {
  99. if (is_open(impl))
  100. {
  101. BOOST_ASIO_HANDLER_OPERATION(("descriptor", &impl, "close"));
  102. reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_,
  103. (impl.state_ & descriptor_ops::possible_dup) == 0);
  104. }
  105. descriptor_ops::close(impl.descriptor_, impl.state_, ec);
  106. // The descriptor is closed by the OS even if close() returns an error.
  107. //
  108. // (Actually, POSIX says the state of the descriptor is unspecified. On
  109. // Linux the descriptor is apparently closed anyway; e.g. see
  110. // http://lkml.org/lkml/2005/9/10/129
  111. // We'll just have to assume that other OSes follow the same behaviour.)
  112. construct(impl);
  113. return ec;
  114. }
  115. reactive_descriptor_service::native_handle_type
  116. reactive_descriptor_service::release(
  117. reactive_descriptor_service::implementation_type& impl)
  118. {
  119. native_handle_type descriptor = impl.descriptor_;
  120. if (is_open(impl))
  121. {
  122. BOOST_ASIO_HANDLER_OPERATION(("descriptor", &impl, "release"));
  123. reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, false);
  124. construct(impl);
  125. }
  126. return descriptor;
  127. }
  128. boost::system::error_code reactive_descriptor_service::cancel(
  129. reactive_descriptor_service::implementation_type& impl,
  130. boost::system::error_code& ec)
  131. {
  132. if (!is_open(impl))
  133. {
  134. ec = boost::asio::error::bad_descriptor;
  135. return ec;
  136. }
  137. BOOST_ASIO_HANDLER_OPERATION(("descriptor", &impl, "cancel"));
  138. reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_);
  139. ec = boost::system::error_code();
  140. return ec;
  141. }
  142. void reactive_descriptor_service::start_op(
  143. reactive_descriptor_service::implementation_type& impl,
  144. int op_type, reactor_op* op, bool is_non_blocking, bool noop)
  145. {
  146. if (!noop)
  147. {
  148. if ((impl.state_ & descriptor_ops::non_blocking) ||
  149. descriptor_ops::set_internal_non_blocking(
  150. impl.descriptor_, impl.state_, true, op->ec_))
  151. {
  152. reactor_.start_op(op_type, impl.descriptor_,
  153. impl.reactor_data_, op, is_non_blocking);
  154. return;
  155. }
  156. }
  157. reactor_.post_immediate_completion(op);
  158. }
  159. } // namespace detail
  160. } // namespace asio
  161. } // namespace boost
  162. #include <boost/asio/detail/pop_options.hpp>
  163. #endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
  164. #endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP