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.

208 lines
6.6KB

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