Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

397 lines
12KB

  1. //
  2. // windows/basic_object_handle.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. // Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. #ifndef ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP
  12. #define ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include "asio/detail/config.hpp"
  17. #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \
  18. || defined(GENERATING_DOCUMENTATION)
  19. #include "asio/async_result.hpp"
  20. #include "asio/detail/io_object_impl.hpp"
  21. #include "asio/detail/throw_error.hpp"
  22. #include "asio/detail/win_object_handle_service.hpp"
  23. #include "asio/error.hpp"
  24. #include "asio/execution_context.hpp"
  25. #include "asio/executor.hpp"
  26. #if defined(ASIO_HAS_MOVE)
  27. # include <utility>
  28. #endif // defined(ASIO_HAS_MOVE)
  29. #include "asio/detail/push_options.hpp"
  30. namespace asio {
  31. namespace windows {
  32. /// Provides object-oriented handle functionality.
  33. /**
  34. * The windows::basic_object_handle class provides asynchronous and blocking
  35. * object-oriented handle functionality.
  36. *
  37. * @par Thread Safety
  38. * @e Distinct @e objects: Safe.@n
  39. * @e Shared @e objects: Unsafe.
  40. */
  41. template <typename Executor = executor>
  42. class basic_object_handle
  43. {
  44. public:
  45. /// The type of the executor associated with the object.
  46. typedef Executor executor_type;
  47. /// The native representation of a handle.
  48. #if defined(GENERATING_DOCUMENTATION)
  49. typedef implementation_defined native_handle_type;
  50. #else
  51. typedef asio::detail::win_object_handle_service::native_handle_type
  52. native_handle_type;
  53. #endif
  54. /// An object handle is always the lowest layer.
  55. typedef basic_object_handle lowest_layer_type;
  56. /// Construct an object handle without opening it.
  57. /**
  58. * This constructor creates an object handle without opening it.
  59. *
  60. * @param ex The I/O executor that the object handle will use, by default, to
  61. * dispatch handlers for any asynchronous operations performed on the
  62. * object handle.
  63. */
  64. explicit basic_object_handle(const executor_type& ex)
  65. : impl_(ex)
  66. {
  67. }
  68. /// Construct an object handle without opening it.
  69. /**
  70. * This constructor creates an object handle without opening it.
  71. *
  72. * @param context An execution context which provides the I/O executor that
  73. * the object handle will use, by default, to dispatch handlers for any
  74. * asynchronous operations performed on the object handle.
  75. */
  76. template <typename ExecutionContext>
  77. explicit basic_object_handle(ExecutionContext& context,
  78. typename enable_if<
  79. is_convertible<ExecutionContext&, execution_context&>::value,
  80. basic_object_handle
  81. >::type* = 0)
  82. : impl_(context)
  83. {
  84. }
  85. /// Construct an object handle on an existing native handle.
  86. /**
  87. * This constructor creates an object handle object to hold an existing native
  88. * handle.
  89. *
  90. * @param ex The I/O executor that the object handle will use, by default, to
  91. * dispatch handlers for any asynchronous operations performed on the
  92. * object handle.
  93. *
  94. * @param native_handle The new underlying handle implementation.
  95. *
  96. * @throws asio::system_error Thrown on failure.
  97. */
  98. basic_object_handle(const executor_type& ex,
  99. const native_handle_type& native_handle)
  100. : impl_(ex)
  101. {
  102. asio::error_code ec;
  103. impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
  104. asio::detail::throw_error(ec, "assign");
  105. }
  106. /// Construct an object handle on an existing native handle.
  107. /**
  108. * This constructor creates an object handle object to hold an existing native
  109. * handle.
  110. *
  111. * @param context An execution context which provides the I/O executor that
  112. * the object handle will use, by default, to dispatch handlers for any
  113. * asynchronous operations performed on the object handle.
  114. *
  115. * @param native_handle The new underlying handle implementation.
  116. *
  117. * @throws asio::system_error Thrown on failure.
  118. */
  119. template <typename ExecutionContext>
  120. basic_object_handle(ExecutionContext& context,
  121. const native_handle_type& native_handle,
  122. typename enable_if<
  123. is_convertible<ExecutionContext&, execution_context&>::value
  124. >::type* = 0)
  125. : impl_(context)
  126. {
  127. asio::error_code ec;
  128. impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
  129. asio::detail::throw_error(ec, "assign");
  130. }
  131. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  132. /// Move-construct an object handle from another.
  133. /**
  134. * This constructor moves an object handle from one object to another.
  135. *
  136. * @param other The other object handle object from which the move will
  137. * occur.
  138. *
  139. * @note Following the move, the moved-from object is in the same state as if
  140. * constructed using the @c basic_object_handle(const executor_type&)
  141. * constructor.
  142. */
  143. basic_object_handle(basic_object_handle&& other)
  144. : impl_(std::move(other.impl_))
  145. {
  146. }
  147. /// Move-assign an object handle from another.
  148. /**
  149. * This assignment operator moves an object handle from one object to another.
  150. *
  151. * @param other The other object handle object from which the move will
  152. * occur.
  153. *
  154. * @note Following the move, the moved-from object is in the same state as if
  155. * constructed using the @c basic_object_handle(const executor_type&)
  156. * constructor.
  157. */
  158. basic_object_handle& operator=(basic_object_handle&& other)
  159. {
  160. impl_ = std::move(other.impl_);
  161. return *this;
  162. }
  163. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  164. /// Get the executor associated with the object.
  165. executor_type get_executor() ASIO_NOEXCEPT
  166. {
  167. return impl_.get_executor();
  168. }
  169. /// Get a reference to the lowest layer.
  170. /**
  171. * This function returns a reference to the lowest layer in a stack of
  172. * layers. Since an object handle cannot contain any further layers, it simply
  173. * returns a reference to itself.
  174. *
  175. * @return A reference to the lowest layer in the stack of layers. Ownership
  176. * is not transferred to the caller.
  177. */
  178. lowest_layer_type& lowest_layer()
  179. {
  180. return *this;
  181. }
  182. /// Get a const reference to the lowest layer.
  183. /**
  184. * This function returns a const reference to the lowest layer in a stack of
  185. * layers. Since an object handle cannot contain any further layers, it simply
  186. * returns a reference to itself.
  187. *
  188. * @return A const reference to the lowest layer in the stack of layers.
  189. * Ownership is not transferred to the caller.
  190. */
  191. const lowest_layer_type& lowest_layer() const
  192. {
  193. return *this;
  194. }
  195. /// Assign an existing native handle to the handle.
  196. /*
  197. * This function opens the handle to hold an existing native handle.
  198. *
  199. * @param handle A native handle.
  200. *
  201. * @throws asio::system_error Thrown on failure.
  202. */
  203. void assign(const native_handle_type& handle)
  204. {
  205. asio::error_code ec;
  206. impl_.get_service().assign(impl_.get_implementation(), handle, ec);
  207. asio::detail::throw_error(ec, "assign");
  208. }
  209. /// Assign an existing native handle to the handle.
  210. /*
  211. * This function opens the handle to hold an existing native handle.
  212. *
  213. * @param handle A native handle.
  214. *
  215. * @param ec Set to indicate what error occurred, if any.
  216. */
  217. ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
  218. asio::error_code& ec)
  219. {
  220. impl_.get_service().assign(impl_.get_implementation(), handle, ec);
  221. ASIO_SYNC_OP_VOID_RETURN(ec);
  222. }
  223. /// Determine whether the handle is open.
  224. bool is_open() const
  225. {
  226. return impl_.get_service().is_open(impl_.get_implementation());
  227. }
  228. /// Close the handle.
  229. /**
  230. * This function is used to close the handle. Any asynchronous read or write
  231. * operations will be cancelled immediately, and will complete with the
  232. * asio::error::operation_aborted error.
  233. *
  234. * @throws asio::system_error Thrown on failure.
  235. */
  236. void close()
  237. {
  238. asio::error_code ec;
  239. impl_.get_service().close(impl_.get_implementation(), ec);
  240. asio::detail::throw_error(ec, "close");
  241. }
  242. /// Close the handle.
  243. /**
  244. * This function is used to close the handle. Any asynchronous read or write
  245. * operations will be cancelled immediately, and will complete with the
  246. * asio::error::operation_aborted error.
  247. *
  248. * @param ec Set to indicate what error occurred, if any.
  249. */
  250. ASIO_SYNC_OP_VOID close(asio::error_code& ec)
  251. {
  252. impl_.get_service().close(impl_.get_implementation(), ec);
  253. ASIO_SYNC_OP_VOID_RETURN(ec);
  254. }
  255. /// Get the native handle representation.
  256. /**
  257. * This function may be used to obtain the underlying representation of the
  258. * handle. This is intended to allow access to native handle functionality
  259. * that is not otherwise provided.
  260. */
  261. native_handle_type native_handle()
  262. {
  263. return impl_.get_service().native_handle(impl_.get_implementation());
  264. }
  265. /// Cancel all asynchronous operations associated with the handle.
  266. /**
  267. * This function causes all outstanding asynchronous read or write operations
  268. * to finish immediately, and the handlers for cancelled operations will be
  269. * passed the asio::error::operation_aborted error.
  270. *
  271. * @throws asio::system_error Thrown on failure.
  272. */
  273. void cancel()
  274. {
  275. asio::error_code ec;
  276. impl_.get_service().cancel(impl_.get_implementation(), ec);
  277. asio::detail::throw_error(ec, "cancel");
  278. }
  279. /// Cancel all asynchronous operations associated with the handle.
  280. /**
  281. * This function causes all outstanding asynchronous read or write operations
  282. * to finish immediately, and the handlers for cancelled operations will be
  283. * passed the asio::error::operation_aborted error.
  284. *
  285. * @param ec Set to indicate what error occurred, if any.
  286. */
  287. ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
  288. {
  289. impl_.get_service().cancel(impl_.get_implementation(), ec);
  290. ASIO_SYNC_OP_VOID_RETURN(ec);
  291. }
  292. /// Perform a blocking wait on the object handle.
  293. /**
  294. * This function is used to wait for the object handle to be set to the
  295. * signalled state. This function blocks and does not return until the object
  296. * handle has been set to the signalled state.
  297. *
  298. * @throws asio::system_error Thrown on failure.
  299. */
  300. void wait()
  301. {
  302. asio::error_code ec;
  303. impl_.get_service().wait(impl_.get_implementation(), ec);
  304. asio::detail::throw_error(ec, "wait");
  305. }
  306. /// Perform a blocking wait on the object handle.
  307. /**
  308. * This function is used to wait for the object handle to be set to the
  309. * signalled state. This function blocks and does not return until the object
  310. * handle has been set to the signalled state.
  311. *
  312. * @param ec Set to indicate what error occurred, if any.
  313. */
  314. void wait(asio::error_code& ec)
  315. {
  316. impl_.get_service().wait(impl_.get_implementation(), ec);
  317. }
  318. /// Start an asynchronous wait on the object handle.
  319. /**
  320. * This function is be used to initiate an asynchronous wait against the
  321. * object handle. It always returns immediately.
  322. *
  323. * @param handler The handler to be called when the object handle is set to
  324. * the signalled state. Copies will be made of the handler as required. The
  325. * function signature of the handler must be:
  326. * @code void handler(
  327. * const asio::error_code& error // Result of operation.
  328. * ); @endcode
  329. * Regardless of whether the asynchronous operation completes immediately or
  330. * not, the handler will not be invoked from within this function. On
  331. * immediate completion, invocation of the handler will be performed in a
  332. * manner equivalent to using asio::post().
  333. */
  334. template <typename WaitHandler>
  335. ASIO_INITFN_RESULT_TYPE(WaitHandler,
  336. void (asio::error_code))
  337. async_wait(ASIO_MOVE_ARG(WaitHandler) handler)
  338. {
  339. asio::async_completion<WaitHandler,
  340. void (asio::error_code)> init(handler);
  341. impl_.get_service().async_wait(impl_.get_implementation(),
  342. init.completion_handler, impl_.get_implementation_executor());
  343. return init.result.get();
  344. }
  345. private:
  346. // Disallow copying and assignment.
  347. basic_object_handle(const basic_object_handle&) ASIO_DELETED;
  348. basic_object_handle& operator=(const basic_object_handle&) ASIO_DELETED;
  349. asio::detail::io_object_impl<
  350. asio::detail::win_object_handle_service, Executor> impl_;
  351. };
  352. } // namespace windows
  353. } // namespace asio
  354. #include "asio/detail/pop_options.hpp"
  355. #endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)
  356. // || defined(GENERATING_DOCUMENTATION)
  357. #endif // ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP