basic_descriptor.hpp 8.7 KB

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