basic_descriptor.hpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. //
  2. // basic_descriptor.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_POSIX_BASIC_DESCRIPTOR_HPP
  11. #define BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_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/detail/push_options.hpp>
  17. #include <boost/config.hpp>
  18. #include <boost/asio/detail/pop_options.hpp>
  19. #include <boost/asio/basic_io_object.hpp>
  20. #include <boost/asio/error.hpp>
  21. #include <boost/asio/posix/descriptor_base.hpp>
  22. #include <boost/asio/detail/throw_error.hpp>
  23. namespace boost {
  24. namespace asio {
  25. namespace posix {
  26. /// Provides POSIX descriptor functionality.
  27. /**
  28. * The posix::basic_descriptor class template provides the ability to wrap a
  29. * POSIX descriptor.
  30. *
  31. * @par Thread Safety
  32. * @e Distinct @e objects: Safe.@n
  33. * @e Shared @e objects: Unsafe.
  34. */
  35. template <typename DescriptorService>
  36. class basic_descriptor
  37. : public basic_io_object<DescriptorService>,
  38. public descriptor_base
  39. {
  40. public:
  41. /// The native representation of a descriptor.
  42. typedef typename DescriptorService::native_type native_type;
  43. /// A basic_descriptor is always the lowest layer.
  44. typedef basic_descriptor<DescriptorService> lowest_layer_type;
  45. /// Construct a basic_descriptor without opening it.
  46. /**
  47. * This constructor creates a descriptor without opening it.
  48. *
  49. * @param io_service The io_service object that the descriptor will use to
  50. * dispatch handlers for any asynchronous operations performed on the
  51. * descriptor.
  52. */
  53. explicit basic_descriptor(boost::asio::io_service& io_service)
  54. : basic_io_object<DescriptorService>(io_service)
  55. {
  56. }
  57. /// Construct a basic_descriptor on an existing native descriptor.
  58. /**
  59. * This constructor creates a descriptor object to hold an existing native
  60. * descriptor.
  61. *
  62. * @param io_service The io_service object that the descriptor will use to
  63. * dispatch handlers for any asynchronous operations performed on the
  64. * descriptor.
  65. *
  66. * @param native_descriptor A native descriptor.
  67. *
  68. * @throws boost::system::system_error Thrown on failure.
  69. */
  70. basic_descriptor(boost::asio::io_service& io_service,
  71. const native_type& native_descriptor)
  72. : basic_io_object<DescriptorService>(io_service)
  73. {
  74. boost::system::error_code ec;
  75. this->service.assign(this->implementation, native_descriptor, ec);
  76. boost::asio::detail::throw_error(ec);
  77. }
  78. /// Get a reference to the lowest layer.
  79. /**
  80. * This function returns a reference to the lowest layer in a stack of
  81. * layers. Since a basic_descriptor cannot contain any further layers, it
  82. * simply returns a reference to itself.
  83. *
  84. * @return A reference to the lowest layer in the stack of layers. Ownership
  85. * is not transferred to the caller.
  86. */
  87. lowest_layer_type& lowest_layer()
  88. {
  89. return *this;
  90. }
  91. /// Get a const reference to the lowest layer.
  92. /**
  93. * This function returns a const reference to the lowest layer in a stack of
  94. * layers. Since a basic_descriptor cannot contain any further layers, it
  95. * simply returns a reference to itself.
  96. *
  97. * @return A const reference to the lowest layer in the stack of layers.
  98. * Ownership is not transferred to the caller.
  99. */
  100. const lowest_layer_type& lowest_layer() const
  101. {
  102. return *this;
  103. }
  104. /// Assign an existing native descriptor to the descriptor.
  105. /*
  106. * This function opens the descriptor to hold an existing native descriptor.
  107. *
  108. * @param native_descriptor A native descriptor.
  109. *
  110. * @throws boost::system::system_error Thrown on failure.
  111. */
  112. void assign(const native_type& native_descriptor)
  113. {
  114. boost::system::error_code ec;
  115. this->service.assign(this->implementation, native_descriptor, ec);
  116. boost::asio::detail::throw_error(ec);
  117. }
  118. /// Assign an existing native descriptor to the descriptor.
  119. /*
  120. * This function opens the descriptor to hold an existing native descriptor.
  121. *
  122. * @param native_descriptor A native descriptor.
  123. *
  124. * @param ec Set to indicate what error occurred, if any.
  125. */
  126. boost::system::error_code assign(const native_type& native_descriptor,
  127. boost::system::error_code& ec)
  128. {
  129. return this->service.assign(this->implementation, native_descriptor, ec);
  130. }
  131. /// Determine whether the descriptor is open.
  132. bool is_open() const
  133. {
  134. return this->service.is_open(this->implementation);
  135. }
  136. /// Close the descriptor.
  137. /**
  138. * This function is used to close the descriptor. Any asynchronous read or
  139. * write operations will be cancelled immediately, and will complete with the
  140. * boost::asio::error::operation_aborted error.
  141. *
  142. * @throws boost::system::system_error Thrown on failure.
  143. */
  144. void close()
  145. {
  146. boost::system::error_code ec;
  147. this->service.close(this->implementation, ec);
  148. boost::asio::detail::throw_error(ec);
  149. }
  150. /// Close the descriptor.
  151. /**
  152. * This function is used to close the descriptor. Any asynchronous read or
  153. * write operations will be cancelled immediately, and will complete with the
  154. * boost::asio::error::operation_aborted error.
  155. *
  156. * @param ec Set to indicate what error occurred, if any.
  157. */
  158. boost::system::error_code close(boost::system::error_code& ec)
  159. {
  160. return this->service.close(this->implementation, ec);
  161. }
  162. /// Get the native descriptor representation.
  163. /**
  164. * This function may be used to obtain the underlying representation of the
  165. * descriptor. This is intended to allow access to native descriptor
  166. * functionality that is not otherwise provided.
  167. */
  168. native_type native()
  169. {
  170. return this->service.native(this->implementation);
  171. }
  172. /// Cancel all asynchronous operations associated with the descriptor.
  173. /**
  174. * This function causes all outstanding asynchronous read or write operations
  175. * to finish immediately, and the handlers for cancelled operations will be
  176. * passed the boost::asio::error::operation_aborted error.
  177. *
  178. * @throws boost::system::system_error Thrown on failure.
  179. */
  180. void cancel()
  181. {
  182. boost::system::error_code ec;
  183. this->service.cancel(this->implementation, ec);
  184. boost::asio::detail::throw_error(ec);
  185. }
  186. /// Cancel all asynchronous operations associated with the descriptor.
  187. /**
  188. * This function causes all outstanding asynchronous read or write operations
  189. * to finish immediately, and the handlers for cancelled operations will be
  190. * passed the boost::asio::error::operation_aborted error.
  191. *
  192. * @param ec Set to indicate what error occurred, if any.
  193. */
  194. boost::system::error_code cancel(boost::system::error_code& ec)
  195. {
  196. return this->service.cancel(this->implementation, ec);
  197. }
  198. /// Perform an IO control command on the descriptor.
  199. /**
  200. * This function is used to execute an IO control command on the descriptor.
  201. *
  202. * @param command The IO control command to be performed on the descriptor.
  203. *
  204. * @throws boost::system::system_error Thrown on failure.
  205. *
  206. * @sa IoControlCommand @n
  207. * boost::asio::posix::descriptor_base::bytes_readable @n
  208. * boost::asio::posix::descriptor_base::non_blocking_io
  209. *
  210. * @par Example
  211. * Getting the number of bytes ready to read:
  212. * @code
  213. * boost::asio::posix::stream_descriptor descriptor(io_service);
  214. * ...
  215. * boost::asio::posix::stream_descriptor::bytes_readable command;
  216. * descriptor.io_control(command);
  217. * std::size_t bytes_readable = command.get();
  218. * @endcode
  219. */
  220. template <typename IoControlCommand>
  221. void io_control(IoControlCommand& command)
  222. {
  223. boost::system::error_code ec;
  224. this->service.io_control(this->implementation, command, ec);
  225. boost::asio::detail::throw_error(ec);
  226. }
  227. /// Perform an IO control command on the descriptor.
  228. /**
  229. * This function is used to execute an IO control command on the descriptor.
  230. *
  231. * @param command The IO control command to be performed on the descriptor.
  232. *
  233. * @param ec Set to indicate what error occurred, if any.
  234. *
  235. * @sa IoControlCommand @n
  236. * boost::asio::posix::descriptor_base::bytes_readable @n
  237. * boost::asio::posix::descriptor_base::non_blocking_io
  238. *
  239. * @par Example
  240. * Getting the number of bytes ready to read:
  241. * @code
  242. * boost::asio::posix::stream_descriptor descriptor(io_service);
  243. * ...
  244. * boost::asio::posix::stream_descriptor::bytes_readable command;
  245. * boost::system::error_code ec;
  246. * descriptor.io_control(command, ec);
  247. * if (ec)
  248. * {
  249. * // An error occurred.
  250. * }
  251. * std::size_t bytes_readable = command.get();
  252. * @endcode
  253. */
  254. template <typename IoControlCommand>
  255. boost::system::error_code io_control(IoControlCommand& command,
  256. boost::system::error_code& ec)
  257. {
  258. return this->service.io_control(this->implementation, command, ec);
  259. }
  260. protected:
  261. /// Protected destructor to prevent deletion through this type.
  262. ~basic_descriptor()
  263. {
  264. }
  265. };
  266. } // namespace posix
  267. } // namespace asio
  268. } // namespace boost
  269. #include <boost/asio/detail/pop_options.hpp>
  270. #endif // BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP