basic_descriptor.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. //
  2. // posix/basic_descriptor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 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/config.hpp"
  16. #if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
  17. || defined(GENERATING_DOCUMENTATION)
  18. #include "asio/basic_io_object.hpp"
  19. #include "asio/detail/throw_error.hpp"
  20. #include "asio/error.hpp"
  21. #include "asio/posix/descriptor_base.hpp"
  22. #include "asio/detail/push_options.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. /// (Deprecated: Use native_handle_type.) The native representation of a
  41. /// descriptor.
  42. typedef typename DescriptorService::native_handle_type native_type;
  43. /// The native representation of a descriptor.
  44. typedef typename DescriptorService::native_handle_type native_handle_type;
  45. /// A basic_descriptor is always the lowest layer.
  46. typedef basic_descriptor<DescriptorService> lowest_layer_type;
  47. /// Construct a basic_descriptor without opening it.
  48. /**
  49. * This constructor creates a descriptor without opening it.
  50. *
  51. * @param io_service The io_service object that the descriptor will use to
  52. * dispatch handlers for any asynchronous operations performed on the
  53. * descriptor.
  54. */
  55. explicit basic_descriptor(asio::io_service& io_service)
  56. : basic_io_object<DescriptorService>(io_service)
  57. {
  58. }
  59. /// Construct a basic_descriptor on an existing native descriptor.
  60. /**
  61. * This constructor creates a descriptor object to hold an existing native
  62. * descriptor.
  63. *
  64. * @param io_service The io_service object that the descriptor will use to
  65. * dispatch handlers for any asynchronous operations performed on the
  66. * descriptor.
  67. *
  68. * @param native_descriptor A native descriptor.
  69. *
  70. * @throws asio::system_error Thrown on failure.
  71. */
  72. basic_descriptor(asio::io_service& io_service,
  73. const native_handle_type& native_descriptor)
  74. : basic_io_object<DescriptorService>(io_service)
  75. {
  76. asio::error_code ec;
  77. this->get_service().assign(this->get_implementation(),
  78. native_descriptor, ec);
  79. asio::detail::throw_error(ec, "assign");
  80. }
  81. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  82. /// Move-construct a basic_descriptor from another.
  83. /**
  84. * This constructor moves a descriptor from one object to another.
  85. *
  86. * @param other The other basic_descriptor object from which the move will
  87. * occur.
  88. *
  89. * @note Following the move, the moved-from object is in the same state as if
  90. * constructed using the @c basic_descriptor(io_service&) constructor.
  91. */
  92. basic_descriptor(basic_descriptor&& other)
  93. : basic_io_object<DescriptorService>(
  94. ASIO_MOVE_CAST(basic_descriptor)(other))
  95. {
  96. }
  97. /// Move-assign a basic_descriptor from another.
  98. /**
  99. * This assignment operator moves a descriptor from one object to another.
  100. *
  101. * @param other The other basic_descriptor object from which the move will
  102. * occur.
  103. *
  104. * @note Following the move, the moved-from object is in the same state as if
  105. * constructed using the @c basic_descriptor(io_service&) constructor.
  106. */
  107. basic_descriptor& operator=(basic_descriptor&& other)
  108. {
  109. basic_io_object<DescriptorService>::operator=(
  110. ASIO_MOVE_CAST(basic_descriptor)(other));
  111. return *this;
  112. }
  113. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  114. /// Get a reference to the lowest layer.
  115. /**
  116. * This function returns a reference to the lowest layer in a stack of
  117. * layers. Since a basic_descriptor cannot contain any further layers, it
  118. * simply returns a reference to itself.
  119. *
  120. * @return A reference to the lowest layer in the stack of layers. Ownership
  121. * is not transferred to the caller.
  122. */
  123. lowest_layer_type& lowest_layer()
  124. {
  125. return *this;
  126. }
  127. /// Get a const reference to the lowest layer.
  128. /**
  129. * This function returns a const reference to the lowest layer in a stack of
  130. * layers. Since a basic_descriptor cannot contain any further layers, it
  131. * simply returns a reference to itself.
  132. *
  133. * @return A const reference to the lowest layer in the stack of layers.
  134. * Ownership is not transferred to the caller.
  135. */
  136. const lowest_layer_type& lowest_layer() const
  137. {
  138. return *this;
  139. }
  140. /// Assign an existing native descriptor to the descriptor.
  141. /*
  142. * This function opens the descriptor to hold an existing native descriptor.
  143. *
  144. * @param native_descriptor A native descriptor.
  145. *
  146. * @throws asio::system_error Thrown on failure.
  147. */
  148. void assign(const native_handle_type& native_descriptor)
  149. {
  150. asio::error_code ec;
  151. this->get_service().assign(this->get_implementation(),
  152. native_descriptor, ec);
  153. asio::detail::throw_error(ec, "assign");
  154. }
  155. /// Assign an existing native descriptor to the descriptor.
  156. /*
  157. * This function opens the descriptor to hold an existing native descriptor.
  158. *
  159. * @param native_descriptor A native descriptor.
  160. *
  161. * @param ec Set to indicate what error occurred, if any.
  162. */
  163. asio::error_code assign(const native_handle_type& native_descriptor,
  164. asio::error_code& ec)
  165. {
  166. return this->get_service().assign(
  167. this->get_implementation(), native_descriptor, ec);
  168. }
  169. /// Determine whether the descriptor is open.
  170. bool is_open() const
  171. {
  172. return this->get_service().is_open(this->implementation);
  173. }
  174. /// Close the descriptor.
  175. /**
  176. * This function is used to close the descriptor. Any asynchronous read or
  177. * write operations will be cancelled immediately, and will complete with the
  178. * asio::error::operation_aborted error.
  179. *
  180. * @throws asio::system_error Thrown on failure. Note that, even if
  181. * the function indicates an error, the underlying descriptor is closed.
  182. */
  183. void close()
  184. {
  185. asio::error_code ec;
  186. this->get_service().close(this->get_implementation(), ec);
  187. asio::detail::throw_error(ec, "close");
  188. }
  189. /// Close the descriptor.
  190. /**
  191. * This function is used to close the descriptor. Any asynchronous read or
  192. * write operations will be cancelled immediately, and will complete with the
  193. * asio::error::operation_aborted error.
  194. *
  195. * @param ec Set to indicate what error occurred, if any. Note that, even if
  196. * the function indicates an error, the underlying descriptor is closed.
  197. */
  198. asio::error_code close(asio::error_code& ec)
  199. {
  200. return this->get_service().close(this->get_implementation(), ec);
  201. }
  202. /// (Deprecated: Use native_handle().) Get the native descriptor
  203. /// representation.
  204. /**
  205. * This function may be used to obtain the underlying representation of the
  206. * descriptor. This is intended to allow access to native descriptor
  207. * functionality that is not otherwise provided.
  208. */
  209. native_type native()
  210. {
  211. return this->get_service().native_handle(this->implementation);
  212. }
  213. /// Get the native descriptor representation.
  214. /**
  215. * This function may be used to obtain the underlying representation of the
  216. * descriptor. This is intended to allow access to native descriptor
  217. * functionality that is not otherwise provided.
  218. */
  219. native_handle_type native_handle()
  220. {
  221. return this->get_service().native_handle(this->implementation);
  222. }
  223. /// Release ownership of the native descriptor implementation.
  224. /**
  225. * This function may be used to obtain the underlying representation of the
  226. * descriptor. After calling this function, @c is_open() returns false. The
  227. * caller is responsible for closing the descriptor.
  228. *
  229. * All outstanding asynchronous read or write operations will finish
  230. * immediately, and the handlers for cancelled operations will be passed the
  231. * asio::error::operation_aborted error.
  232. */
  233. native_handle_type release()
  234. {
  235. return this->get_service().release(this->implementation);
  236. }
  237. /// Cancel all asynchronous operations associated with the descriptor.
  238. /**
  239. * This function causes all outstanding asynchronous read or write operations
  240. * to finish immediately, and the handlers for cancelled operations will be
  241. * passed the asio::error::operation_aborted error.
  242. *
  243. * @throws asio::system_error Thrown on failure.
  244. */
  245. void cancel()
  246. {
  247. asio::error_code ec;
  248. this->get_service().cancel(this->get_implementation(), ec);
  249. asio::detail::throw_error(ec, "cancel");
  250. }
  251. /// Cancel all asynchronous operations associated with the descriptor.
  252. /**
  253. * This function causes all outstanding asynchronous read or write operations
  254. * to finish immediately, and the handlers for cancelled operations will be
  255. * passed the asio::error::operation_aborted error.
  256. *
  257. * @param ec Set to indicate what error occurred, if any.
  258. */
  259. asio::error_code cancel(asio::error_code& ec)
  260. {
  261. return this->get_service().cancel(this->get_implementation(), ec);
  262. }
  263. /// Perform an IO control command on the descriptor.
  264. /**
  265. * This function is used to execute an IO control command on the descriptor.
  266. *
  267. * @param command The IO control command to be performed on the descriptor.
  268. *
  269. * @throws asio::system_error Thrown on failure.
  270. *
  271. * @sa IoControlCommand @n
  272. * asio::posix::descriptor_base::bytes_readable @n
  273. * asio::posix::descriptor_base::non_blocking_io
  274. *
  275. * @par Example
  276. * Getting the number of bytes ready to read:
  277. * @code
  278. * asio::posix::stream_descriptor descriptor(io_service);
  279. * ...
  280. * asio::posix::stream_descriptor::bytes_readable command;
  281. * descriptor.io_control(command);
  282. * std::size_t bytes_readable = command.get();
  283. * @endcode
  284. */
  285. template <typename IoControlCommand>
  286. void io_control(IoControlCommand& command)
  287. {
  288. asio::error_code ec;
  289. this->get_service().io_control(this->get_implementation(), command, ec);
  290. asio::detail::throw_error(ec, "io_control");
  291. }
  292. /// Perform an IO control command on the descriptor.
  293. /**
  294. * This function is used to execute an IO control command on the descriptor.
  295. *
  296. * @param command The IO control command to be performed on the descriptor.
  297. *
  298. * @param ec Set to indicate what error occurred, if any.
  299. *
  300. * @sa IoControlCommand @n
  301. * asio::posix::descriptor_base::bytes_readable @n
  302. * asio::posix::descriptor_base::non_blocking_io
  303. *
  304. * @par Example
  305. * Getting the number of bytes ready to read:
  306. * @code
  307. * asio::posix::stream_descriptor descriptor(io_service);
  308. * ...
  309. * asio::posix::stream_descriptor::bytes_readable command;
  310. * asio::error_code ec;
  311. * descriptor.io_control(command, ec);
  312. * if (ec)
  313. * {
  314. * // An error occurred.
  315. * }
  316. * std::size_t bytes_readable = command.get();
  317. * @endcode
  318. */
  319. template <typename IoControlCommand>
  320. asio::error_code io_control(IoControlCommand& command,
  321. asio::error_code& ec)
  322. {
  323. return this->get_service().io_control(
  324. this->get_implementation(), command, ec);
  325. }
  326. /// Gets the non-blocking mode of the descriptor.
  327. /**
  328. * @returns @c true if the descriptor's synchronous operations will fail with
  329. * asio::error::would_block if they are unable to perform the requested
  330. * operation immediately. If @c false, synchronous operations will block
  331. * until complete.
  332. *
  333. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  334. * operations. Asynchronous operations will never fail with the error
  335. * asio::error::would_block.
  336. */
  337. bool non_blocking() const
  338. {
  339. return this->get_service().non_blocking(this->implementation);
  340. }
  341. /// Sets the non-blocking mode of the descriptor.
  342. /**
  343. * @param mode If @c true, the descriptor's synchronous operations will fail
  344. * with asio::error::would_block if they are unable to perform the
  345. * requested operation immediately. If @c false, synchronous operations will
  346. * block until complete.
  347. *
  348. * @throws asio::system_error Thrown on failure.
  349. *
  350. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  351. * operations. Asynchronous operations will never fail with the error
  352. * asio::error::would_block.
  353. */
  354. void non_blocking(bool mode)
  355. {
  356. asio::error_code ec;
  357. this->get_service().non_blocking(this->get_implementation(), mode, ec);
  358. asio::detail::throw_error(ec, "non_blocking");
  359. }
  360. /// Sets the non-blocking mode of the descriptor.
  361. /**
  362. * @param mode If @c true, the descriptor's synchronous operations will fail
  363. * with asio::error::would_block if they are unable to perform the
  364. * requested operation immediately. If @c false, synchronous operations will
  365. * block until complete.
  366. *
  367. * @param ec Set to indicate what error occurred, if any.
  368. *
  369. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  370. * operations. Asynchronous operations will never fail with the error
  371. * asio::error::would_block.
  372. */
  373. asio::error_code non_blocking(
  374. bool mode, asio::error_code& ec)
  375. {
  376. return this->get_service().non_blocking(
  377. this->get_implementation(), mode, ec);
  378. }
  379. /// Gets the non-blocking mode of the native descriptor implementation.
  380. /**
  381. * This function is used to retrieve the non-blocking mode of the underlying
  382. * native descriptor. This mode has no effect on the behaviour of the
  383. * descriptor object's synchronous operations.
  384. *
  385. * @returns @c true if the underlying descriptor is in non-blocking mode and
  386. * direct system calls may fail with asio::error::would_block (or the
  387. * equivalent system error).
  388. *
  389. * @note The current non-blocking mode is cached by the descriptor object.
  390. * Consequently, the return value may be incorrect if the non-blocking mode
  391. * was set directly on the native descriptor.
  392. */
  393. bool native_non_blocking() const
  394. {
  395. return this->get_service().native_non_blocking(this->implementation);
  396. }
  397. /// Sets the non-blocking mode of the native descriptor implementation.
  398. /**
  399. * This function is used to modify the non-blocking mode of the underlying
  400. * native descriptor. It has no effect on the behaviour of the descriptor
  401. * object's synchronous operations.
  402. *
  403. * @param mode If @c true, the underlying descriptor is put into non-blocking
  404. * mode and direct system calls may fail with asio::error::would_block
  405. * (or the equivalent system error).
  406. *
  407. * @throws asio::system_error Thrown on failure. If the @c mode is
  408. * @c false, but the current value of @c non_blocking() is @c true, this
  409. * function fails with asio::error::invalid_argument, as the
  410. * combination does not make sense.
  411. */
  412. void native_non_blocking(bool mode)
  413. {
  414. asio::error_code ec;
  415. this->get_service().native_non_blocking(
  416. this->get_implementation(), mode, ec);
  417. asio::detail::throw_error(ec, "native_non_blocking");
  418. }
  419. /// Sets the non-blocking mode of the native descriptor implementation.
  420. /**
  421. * This function is used to modify the non-blocking mode of the underlying
  422. * native descriptor. It has no effect on the behaviour of the descriptor
  423. * object's synchronous operations.
  424. *
  425. * @param mode If @c true, the underlying descriptor is put into non-blocking
  426. * mode and direct system calls may fail with asio::error::would_block
  427. * (or the equivalent system error).
  428. *
  429. * @param ec Set to indicate what error occurred, if any. If the @c mode is
  430. * @c false, but the current value of @c non_blocking() is @c true, this
  431. * function fails with asio::error::invalid_argument, as the
  432. * combination does not make sense.
  433. */
  434. asio::error_code native_non_blocking(
  435. bool mode, asio::error_code& ec)
  436. {
  437. return this->get_service().native_non_blocking(
  438. this->get_implementation(), mode, ec);
  439. }
  440. protected:
  441. /// Protected destructor to prevent deletion through this type.
  442. ~basic_descriptor()
  443. {
  444. }
  445. };
  446. } // namespace posix
  447. } // namespace asio
  448. #include "asio/detail/pop_options.hpp"
  449. #endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
  450. // || defined(GENERATING_DOCUMENTATION)
  451. #endif // ASIO_POSIX_BASIC_DESCRIPTOR_HPP