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.

236 lines
7.1KB

  1. //
  2. // thread_pool.hpp
  3. // ~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 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_THREAD_POOL_HPP
  11. #define ASIO_THREAD_POOL_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/detail/noncopyable.hpp"
  17. #include "asio/detail/scheduler.hpp"
  18. #include "asio/detail/thread_group.hpp"
  19. #include "asio/execution_context.hpp"
  20. #include "asio/detail/push_options.hpp"
  21. namespace asio {
  22. /// A simple fixed-size thread pool.
  23. /**
  24. * The thread pool class is an execution context where functions are permitted
  25. * to run on one of a fixed number of threads.
  26. *
  27. * @par Submitting tasks to the pool
  28. *
  29. * To submit functions to the thread_pool, use the @ref asio::dispatch,
  30. * @ref asio::post or @ref asio::defer free functions.
  31. *
  32. * For example:
  33. *
  34. * @code void my_task()
  35. * {
  36. * ...
  37. * }
  38. *
  39. * ...
  40. *
  41. * // Launch the pool with four threads.
  42. * asio::thread_pool pool(4);
  43. *
  44. * // Submit a function to the pool.
  45. * asio::post(pool, my_task);
  46. *
  47. * // Submit a lambda object to the pool.
  48. * asio::post(pool,
  49. * []()
  50. * {
  51. * ...
  52. * });
  53. *
  54. * // Wait for all tasks in the pool to complete.
  55. * pool.join(); @endcode
  56. */
  57. class thread_pool
  58. : public execution_context
  59. {
  60. public:
  61. class executor_type;
  62. /// Constructs a pool with an automatically determined number of threads.
  63. ASIO_DECL thread_pool();
  64. /// Constructs a pool with a specified number of threads.
  65. ASIO_DECL thread_pool(std::size_t num_threads);
  66. /// Destructor.
  67. /**
  68. * Automatically stops and joins the pool, if not explicitly done beforehand.
  69. */
  70. ASIO_DECL ~thread_pool();
  71. /// Obtains the executor associated with the pool.
  72. executor_type get_executor() ASIO_NOEXCEPT;
  73. /// Stops the threads.
  74. /**
  75. * This function stops the threads as soon as possible. As a result of calling
  76. * @c stop(), pending function objects may be never be invoked.
  77. */
  78. ASIO_DECL void stop();
  79. /// Joins the threads.
  80. /**
  81. * This function blocks until the threads in the pool have completed. If @c
  82. * stop() is not called prior to @c join(), the @c join() call will wait
  83. * until the pool has no more outstanding work.
  84. */
  85. ASIO_DECL void join();
  86. private:
  87. friend class executor_type;
  88. struct thread_function;
  89. // Helper function to create the underlying scheduler.
  90. ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s);
  91. // The underlying scheduler.
  92. detail::scheduler& scheduler_;
  93. // The threads in the pool.
  94. detail::thread_group threads_;
  95. };
  96. /// Executor used to submit functions to a thread pool.
  97. class thread_pool::executor_type
  98. {
  99. public:
  100. /// Obtain the underlying execution context.
  101. thread_pool& context() const ASIO_NOEXCEPT;
  102. /// Inform the thread pool that it has some outstanding work to do.
  103. /**
  104. * This function is used to inform the thread pool that some work has begun.
  105. * This ensures that the thread pool's join() function will not return while
  106. * the work is underway.
  107. */
  108. void on_work_started() const ASIO_NOEXCEPT;
  109. /// Inform the thread pool that some work is no longer outstanding.
  110. /**
  111. * This function is used to inform the thread pool that some work has
  112. * finished. Once the count of unfinished work reaches zero, the thread
  113. * pool's join() function is permitted to exit.
  114. */
  115. void on_work_finished() const ASIO_NOEXCEPT;
  116. /// Request the thread pool to invoke the given function object.
  117. /**
  118. * This function is used to ask the thread pool to execute the given function
  119. * object. If the current thread belongs to the pool, @c dispatch() executes
  120. * the function before returning. Otherwise, the function will be scheduled
  121. * to run on the thread pool.
  122. *
  123. * @param f The function object to be called. The executor will make
  124. * a copy of the handler object as required. The function signature of the
  125. * function object must be: @code void function(); @endcode
  126. *
  127. * @param a An allocator that may be used by the executor to allocate the
  128. * internal storage needed for function invocation.
  129. */
  130. template <typename Function, typename Allocator>
  131. void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
  132. /// Request the thread pool to invoke the given function object.
  133. /**
  134. * This function is used to ask the thread pool to execute the given function
  135. * object. The function object will never be executed inside @c post().
  136. * Instead, it will be scheduled to run on the thread pool.
  137. *
  138. * @param f The function object to be called. The executor will make
  139. * a copy of the handler object as required. The function signature of the
  140. * function object must be: @code void function(); @endcode
  141. *
  142. * @param a An allocator that may be used by the executor to allocate the
  143. * internal storage needed for function invocation.
  144. */
  145. template <typename Function, typename Allocator>
  146. void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
  147. /// Request the thread pool to invoke the given function object.
  148. /**
  149. * This function is used to ask the thread pool to execute the given function
  150. * object. The function object will never be executed inside @c defer().
  151. * Instead, it will be scheduled to run on the thread pool.
  152. *
  153. * If the current thread belongs to the thread pool, @c defer() will delay
  154. * scheduling the function object until the current thread returns control to
  155. * the pool.
  156. *
  157. * @param f The function object to be called. The executor will make
  158. * a copy of the handler object as required. The function signature of the
  159. * function object must be: @code void function(); @endcode
  160. *
  161. * @param a An allocator that may be used by the executor to allocate the
  162. * internal storage needed for function invocation.
  163. */
  164. template <typename Function, typename Allocator>
  165. void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
  166. /// Determine whether the thread pool is running in the current thread.
  167. /**
  168. * @return @c true if the current thread belongs to the pool. Otherwise
  169. * returns @c false.
  170. */
  171. bool running_in_this_thread() const ASIO_NOEXCEPT;
  172. /// Compare two executors for equality.
  173. /**
  174. * Two executors are equal if they refer to the same underlying thread pool.
  175. */
  176. friend bool operator==(const executor_type& a,
  177. const executor_type& b) ASIO_NOEXCEPT
  178. {
  179. return &a.pool_ == &b.pool_;
  180. }
  181. /// Compare two executors for inequality.
  182. /**
  183. * Two executors are equal if they refer to the same underlying thread pool.
  184. */
  185. friend bool operator!=(const executor_type& a,
  186. const executor_type& b) ASIO_NOEXCEPT
  187. {
  188. return &a.pool_ != &b.pool_;
  189. }
  190. private:
  191. friend class thread_pool;
  192. // Constructor.
  193. explicit executor_type(thread_pool& p) : pool_(p) {}
  194. // The underlying thread pool.
  195. thread_pool& pool_;
  196. };
  197. } // namespace asio
  198. #include "asio/detail/pop_options.hpp"
  199. #include "asio/impl/thread_pool.hpp"
  200. #if defined(ASIO_HEADER_ONLY)
  201. # include "asio/impl/thread_pool.ipp"
  202. #endif // defined(ASIO_HEADER_ONLY)
  203. #endif // ASIO_THREAD_POOL_HPP