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.

basic_signal_set.hpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. //
  2. // basic_signal_set.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_BASIC_SIGNAL_SET_HPP
  11. #define ASIO_BASIC_SIGNAL_SET_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. #include "asio/basic_io_object.hpp"
  17. #include "asio/detail/handler_type_requirements.hpp"
  18. #include "asio/detail/throw_error.hpp"
  19. #include "asio/error.hpp"
  20. #include "asio/signal_set_service.hpp"
  21. #include "asio/detail/push_options.hpp"
  22. namespace asio {
  23. /// Provides signal functionality.
  24. /**
  25. * The basic_signal_set class template provides the ability to perform an
  26. * asynchronous wait for one or more signals to occur.
  27. *
  28. * Most applications will use the asio::signal_set typedef.
  29. *
  30. * @par Thread Safety
  31. * @e Distinct @e objects: Safe.@n
  32. * @e Shared @e objects: Unsafe.
  33. *
  34. * @par Example
  35. * Performing an asynchronous wait:
  36. * @code
  37. * void handler(
  38. * const asio::error_code& error,
  39. * int signal_number)
  40. * {
  41. * if (!error)
  42. * {
  43. * // A signal occurred.
  44. * }
  45. * }
  46. *
  47. * ...
  48. *
  49. * // Construct a signal set registered for process termination.
  50. * asio::signal_set signals(io_context, SIGINT, SIGTERM);
  51. *
  52. * // Start an asynchronous wait for one of the signals to occur.
  53. * signals.async_wait(handler);
  54. * @endcode
  55. *
  56. * @par Queueing of signal notifications
  57. *
  58. * If a signal is registered with a signal_set, and the signal occurs when
  59. * there are no waiting handlers, then the signal notification is queued. The
  60. * next async_wait operation on that signal_set will dequeue the notification.
  61. * If multiple notifications are queued, subsequent async_wait operations
  62. * dequeue them one at a time. Signal notifications are dequeued in order of
  63. * ascending signal number.
  64. *
  65. * If a signal number is removed from a signal_set (using the @c remove or @c
  66. * erase member functions) then any queued notifications for that signal are
  67. * discarded.
  68. *
  69. * @par Multiple registration of signals
  70. *
  71. * The same signal number may be registered with different signal_set objects.
  72. * When the signal occurs, one handler is called for each signal_set object.
  73. *
  74. * Note that multiple registration only works for signals that are registered
  75. * using Asio. The application must not also register a signal handler using
  76. * functions such as @c signal() or @c sigaction().
  77. *
  78. * @par Signal masking on POSIX platforms
  79. *
  80. * POSIX allows signals to be blocked using functions such as @c sigprocmask()
  81. * and @c pthread_sigmask(). For signals to be delivered, programs must ensure
  82. * that any signals registered using signal_set objects are unblocked in at
  83. * least one thread.
  84. */
  85. template <typename SignalSetService = signal_set_service>
  86. class basic_signal_set
  87. : public basic_io_object<SignalSetService>
  88. {
  89. public:
  90. /// Construct a signal set without adding any signals.
  91. /**
  92. * This constructor creates a signal set without registering for any signals.
  93. *
  94. * @param io_context The io_context object that the signal set will use to
  95. * dispatch handlers for any asynchronous operations performed on the set.
  96. */
  97. explicit basic_signal_set(asio::io_context& io_context)
  98. : basic_io_object<SignalSetService>(io_context)
  99. {
  100. }
  101. /// Construct a signal set and add one signal.
  102. /**
  103. * This constructor creates a signal set and registers for one signal.
  104. *
  105. * @param io_context The io_context object that the signal set will use to
  106. * dispatch handlers for any asynchronous operations performed on the set.
  107. *
  108. * @param signal_number_1 The signal number to be added.
  109. *
  110. * @note This constructor is equivalent to performing:
  111. * @code asio::signal_set signals(io_context);
  112. * signals.add(signal_number_1); @endcode
  113. */
  114. basic_signal_set(asio::io_context& io_context, int signal_number_1)
  115. : basic_io_object<SignalSetService>(io_context)
  116. {
  117. asio::error_code ec;
  118. this->get_service().add(this->get_implementation(), signal_number_1, ec);
  119. asio::detail::throw_error(ec, "add");
  120. }
  121. /// Construct a signal set and add two signals.
  122. /**
  123. * This constructor creates a signal set and registers for two signals.
  124. *
  125. * @param io_context The io_context object that the signal set will use to
  126. * dispatch handlers for any asynchronous operations performed on the set.
  127. *
  128. * @param signal_number_1 The first signal number to be added.
  129. *
  130. * @param signal_number_2 The second signal number to be added.
  131. *
  132. * @note This constructor is equivalent to performing:
  133. * @code asio::signal_set signals(io_context);
  134. * signals.add(signal_number_1);
  135. * signals.add(signal_number_2); @endcode
  136. */
  137. basic_signal_set(asio::io_context& io_context, int signal_number_1,
  138. int signal_number_2)
  139. : basic_io_object<SignalSetService>(io_context)
  140. {
  141. asio::error_code ec;
  142. this->get_service().add(this->get_implementation(), signal_number_1, ec);
  143. asio::detail::throw_error(ec, "add");
  144. this->get_service().add(this->get_implementation(), signal_number_2, ec);
  145. asio::detail::throw_error(ec, "add");
  146. }
  147. /// Construct a signal set and add three signals.
  148. /**
  149. * This constructor creates a signal set and registers for three signals.
  150. *
  151. * @param io_context The io_context object that the signal set will use to
  152. * dispatch handlers for any asynchronous operations performed on the set.
  153. *
  154. * @param signal_number_1 The first signal number to be added.
  155. *
  156. * @param signal_number_2 The second signal number to be added.
  157. *
  158. * @param signal_number_3 The third signal number to be added.
  159. *
  160. * @note This constructor is equivalent to performing:
  161. * @code asio::signal_set signals(io_context);
  162. * signals.add(signal_number_1);
  163. * signals.add(signal_number_2);
  164. * signals.add(signal_number_3); @endcode
  165. */
  166. basic_signal_set(asio::io_context& io_context, int signal_number_1,
  167. int signal_number_2, int signal_number_3)
  168. : basic_io_object<SignalSetService>(io_context)
  169. {
  170. asio::error_code ec;
  171. this->get_service().add(this->get_implementation(), signal_number_1, ec);
  172. asio::detail::throw_error(ec, "add");
  173. this->get_service().add(this->get_implementation(), signal_number_2, ec);
  174. asio::detail::throw_error(ec, "add");
  175. this->get_service().add(this->get_implementation(), signal_number_3, ec);
  176. asio::detail::throw_error(ec, "add");
  177. }
  178. /// Add a signal to a signal_set.
  179. /**
  180. * This function adds the specified signal to the set. It has no effect if the
  181. * signal is already in the set.
  182. *
  183. * @param signal_number The signal to be added to the set.
  184. *
  185. * @throws asio::system_error Thrown on failure.
  186. */
  187. void add(int signal_number)
  188. {
  189. asio::error_code ec;
  190. this->get_service().add(this->get_implementation(), signal_number, ec);
  191. asio::detail::throw_error(ec, "add");
  192. }
  193. /// Add a signal to a signal_set.
  194. /**
  195. * This function adds the specified signal to the set. It has no effect if the
  196. * signal is already in the set.
  197. *
  198. * @param signal_number The signal to be added to the set.
  199. *
  200. * @param ec Set to indicate what error occurred, if any.
  201. */
  202. asio::error_code add(int signal_number,
  203. asio::error_code& ec)
  204. {
  205. return this->get_service().add(
  206. this->get_implementation(), signal_number, ec);
  207. }
  208. /// Remove a signal from a signal_set.
  209. /**
  210. * This function removes the specified signal from the set. It has no effect
  211. * if the signal is not in the set.
  212. *
  213. * @param signal_number The signal to be removed from the set.
  214. *
  215. * @throws asio::system_error Thrown on failure.
  216. *
  217. * @note Removes any notifications that have been queued for the specified
  218. * signal number.
  219. */
  220. void remove(int signal_number)
  221. {
  222. asio::error_code ec;
  223. this->get_service().remove(this->get_implementation(), signal_number, ec);
  224. asio::detail::throw_error(ec, "remove");
  225. }
  226. /// Remove a signal from a signal_set.
  227. /**
  228. * This function removes the specified signal from the set. It has no effect
  229. * if the signal is not in the set.
  230. *
  231. * @param signal_number The signal to be removed from the set.
  232. *
  233. * @param ec Set to indicate what error occurred, if any.
  234. *
  235. * @note Removes any notifications that have been queued for the specified
  236. * signal number.
  237. */
  238. asio::error_code remove(int signal_number,
  239. asio::error_code& ec)
  240. {
  241. return this->get_service().remove(
  242. this->get_implementation(), signal_number, ec);
  243. }
  244. /// Remove all signals from a signal_set.
  245. /**
  246. * This function removes all signals from the set. It has no effect if the set
  247. * is already empty.
  248. *
  249. * @throws asio::system_error Thrown on failure.
  250. *
  251. * @note Removes all queued notifications.
  252. */
  253. void clear()
  254. {
  255. asio::error_code ec;
  256. this->get_service().clear(this->get_implementation(), ec);
  257. asio::detail::throw_error(ec, "clear");
  258. }
  259. /// Remove all signals from a signal_set.
  260. /**
  261. * This function removes all signals from the set. It has no effect if the set
  262. * is already empty.
  263. *
  264. * @param ec Set to indicate what error occurred, if any.
  265. *
  266. * @note Removes all queued notifications.
  267. */
  268. asio::error_code clear(asio::error_code& ec)
  269. {
  270. return this->get_service().clear(this->get_implementation(), ec);
  271. }
  272. /// Cancel all operations associated with the signal set.
  273. /**
  274. * This function forces the completion of any pending asynchronous wait
  275. * operations against the signal set. The handler for each cancelled
  276. * operation will be invoked with the asio::error::operation_aborted
  277. * error code.
  278. *
  279. * Cancellation does not alter the set of registered signals.
  280. *
  281. * @throws asio::system_error Thrown on failure.
  282. *
  283. * @note If a registered signal occurred before cancel() is called, then the
  284. * handlers for asynchronous wait operations will:
  285. *
  286. * @li have already been invoked; or
  287. *
  288. * @li have been queued for invocation in the near future.
  289. *
  290. * These handlers can no longer be cancelled, and therefore are passed an
  291. * error code that indicates the successful completion of the wait operation.
  292. */
  293. void cancel()
  294. {
  295. asio::error_code ec;
  296. this->get_service().cancel(this->get_implementation(), ec);
  297. asio::detail::throw_error(ec, "cancel");
  298. }
  299. /// Cancel all operations associated with the signal set.
  300. /**
  301. * This function forces the completion of any pending asynchronous wait
  302. * operations against the signal set. The handler for each cancelled
  303. * operation will be invoked with the asio::error::operation_aborted
  304. * error code.
  305. *
  306. * Cancellation does not alter the set of registered signals.
  307. *
  308. * @param ec Set to indicate what error occurred, if any.
  309. *
  310. * @note If a registered signal occurred before cancel() is called, then the
  311. * handlers for asynchronous wait operations will:
  312. *
  313. * @li have already been invoked; or
  314. *
  315. * @li have been queued for invocation in the near future.
  316. *
  317. * These handlers can no longer be cancelled, and therefore are passed an
  318. * error code that indicates the successful completion of the wait operation.
  319. */
  320. asio::error_code cancel(asio::error_code& ec)
  321. {
  322. return this->get_service().cancel(this->get_implementation(), ec);
  323. }
  324. /// Start an asynchronous operation to wait for a signal to be delivered.
  325. /**
  326. * This function may be used to initiate an asynchronous wait against the
  327. * signal set. It always returns immediately.
  328. *
  329. * For each call to async_wait(), the supplied handler will be called exactly
  330. * once. The handler will be called when:
  331. *
  332. * @li One of the registered signals in the signal set occurs; or
  333. *
  334. * @li The signal set was cancelled, in which case the handler is passed the
  335. * error code asio::error::operation_aborted.
  336. *
  337. * @param handler The handler to be called when the signal occurs. Copies
  338. * will be made of the handler as required. The function signature of the
  339. * handler must be:
  340. * @code void handler(
  341. * const asio::error_code& error, // Result of operation.
  342. * int signal_number // Indicates which signal occurred.
  343. * ); @endcode
  344. * Regardless of whether the asynchronous operation completes immediately or
  345. * not, the handler will not be invoked from within this function. Invocation
  346. * of the handler will be performed in a manner equivalent to using
  347. * asio::io_context::post().
  348. */
  349. template <typename SignalHandler>
  350. ASIO_INITFN_RESULT_TYPE(SignalHandler,
  351. void (asio::error_code, int))
  352. async_wait(ASIO_MOVE_ARG(SignalHandler) handler)
  353. {
  354. // If you get an error on the following line it means that your handler does
  355. // not meet the documented type requirements for a SignalHandler.
  356. ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
  357. return this->get_service().async_wait(this->get_implementation(),
  358. ASIO_MOVE_CAST(SignalHandler)(handler));
  359. }
  360. };
  361. } // namespace asio
  362. #include "asio/detail/pop_options.hpp"
  363. #endif // ASIO_BASIC_SIGNAL_SET_HPP