threadpool.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2012-2013, Digium, Inc.
  5. *
  6. * Mark Michelson <mmmichelson@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. #ifndef _ASTERISK_THREADPOOL_H
  19. #define _ASTERISK_THREADPOOL_H
  20. struct ast_threadpool;
  21. struct ast_taskprocessor;
  22. struct ast_threadpool_listener;
  23. struct ast_threadpool_listener_callbacks {
  24. /*!
  25. * \brief Indicates that the state of threads in the pool has changed
  26. *
  27. * \param pool The pool whose state has changed
  28. * \param listener The threadpool listener
  29. * \param active_threads The number of active threads in the pool
  30. * \param idle_threads The number of idle threads in the pool
  31. */
  32. void (*state_changed)(struct ast_threadpool *pool,
  33. struct ast_threadpool_listener *listener,
  34. int active_threads,
  35. int idle_threads);
  36. /*!
  37. * \brief Indicates that a task was pushed to the threadpool
  38. *
  39. * \param pool The pool that had a task pushed
  40. * \param listener The threadpool listener
  41. * \param was_empty Indicates whether there were any tasks prior to adding the new one.
  42. */
  43. void (*task_pushed)(struct ast_threadpool *pool,
  44. struct ast_threadpool_listener *listener,
  45. int was_empty);
  46. /*!
  47. * \brief Indicates the threadpool's taskprocessor has become empty
  48. *
  49. * \param pool The pool that has become empty
  50. * \param listener The threadpool's listener
  51. */
  52. void (*emptied)(struct ast_threadpool *pool, struct ast_threadpool_listener *listener);
  53. /*!
  54. * \brief The threadpool is shutting down
  55. *
  56. * This would be an opportune time to free the listener's user data
  57. * if one wishes. However, it is acceptable to not do so if the user data
  58. * should persist beyond the lifetime of the pool.
  59. *
  60. * \param listener The threadpool's listener
  61. */
  62. void (*shutdown)(struct ast_threadpool_listener *listener);
  63. };
  64. struct ast_threadpool_options {
  65. #define AST_THREADPOOL_OPTIONS_VERSION 1
  66. /*! Version of threadpool options in use */
  67. int version;
  68. /*!
  69. * \brief Time limit in seconds for idle threads
  70. *
  71. * A time of 0 or less will mean no timeout.
  72. */
  73. int idle_timeout;
  74. /*!
  75. * \brief Number of threads to increment pool by
  76. *
  77. * If a task is added into a pool and no idle thread is
  78. * available to activate, then the pool can automatically
  79. * grow by the given amount.
  80. *
  81. * Zero is a perfectly valid value to give here if you want
  82. * to control threadpool growth yourself via your listener.
  83. */
  84. int auto_increment;
  85. /*!
  86. * \brief Number of threads the pool will start with
  87. *
  88. * When the threadpool is allocated, it will immediately size
  89. * itself to have this number of threads in it.
  90. *
  91. * Zero is a valid value if the threadpool should start
  92. * without any threads allocated.
  93. */
  94. int initial_size;
  95. /*!
  96. * \brief Maximum number of threads a pool may have
  97. *
  98. * When the threadpool's size increases, it can never increase
  99. * beyond this number of threads.
  100. *
  101. * Zero is a valid value if the threadpool does not have a
  102. * maximum size.
  103. */
  104. int max_size;
  105. /*!
  106. * \brief Function to call when a thread starts
  107. *
  108. * This is useful if there is something common that all threads
  109. * in a threadpool need to do when they start.
  110. */
  111. void (*thread_start)(void);
  112. /*!
  113. * \brief Function to call when a thread ends
  114. *
  115. * This is useful if there is common cleanup to execute when
  116. * a thread completes
  117. */
  118. void (*thread_end)(void);
  119. };
  120. /*!
  121. * \brief Allocate a threadpool listener
  122. *
  123. * This function will call back into the alloc callback for the
  124. * listener.
  125. *
  126. * \param callbacks Listener callbacks to assign to the listener
  127. * \param user_data User data to be stored in the threadpool listener
  128. * \retval NULL Failed to allocate the listener
  129. * \retval non-NULL The newly-created threadpool listener
  130. */
  131. struct ast_threadpool_listener *ast_threadpool_listener_alloc(
  132. const struct ast_threadpool_listener_callbacks *callbacks, void *user_data);
  133. /*!
  134. * \brief Get the threadpool listener's user data
  135. * \param listener The threadpool listener
  136. * \return The user data
  137. */
  138. void *ast_threadpool_listener_get_user_data(const struct ast_threadpool_listener *listener);
  139. /*!
  140. * \brief Create a new threadpool
  141. *
  142. * This function creates a threadpool. Tasks may be pushed onto this thread pool
  143. * and will be automatically acted upon by threads within the pool.
  144. *
  145. * Only a single threadpool with a given name may exist. This function will fail
  146. * if a threadpool with the given name already exists.
  147. *
  148. * \param name The unique name for the threadpool
  149. * \param listener The listener the threadpool will notify of changes. Can be NULL.
  150. * \param options The behavioral options for this threadpool
  151. * \retval NULL Failed to create the threadpool
  152. * \retval non-NULL The newly-created threadpool
  153. */
  154. struct ast_threadpool *ast_threadpool_create(const char *name,
  155. struct ast_threadpool_listener *listener,
  156. const struct ast_threadpool_options *options);
  157. /*!
  158. * \brief Set the number of threads for the thread pool
  159. *
  160. * This number may be more or less than the current number of
  161. * threads in the threadpool.
  162. *
  163. * \param threadpool The threadpool to adjust
  164. * \param size The new desired size of the threadpool
  165. */
  166. void ast_threadpool_set_size(struct ast_threadpool *threadpool, unsigned int size);
  167. /*!
  168. * \brief Push a task to the threadpool
  169. *
  170. * Tasks pushed into the threadpool will be automatically taken by
  171. * one of the threads within
  172. * \param pool The threadpool to add the task to
  173. * \param task The task to add
  174. * \param data The parameter for the task
  175. * \retval 0 success
  176. * \retval -1 failure
  177. */
  178. int ast_threadpool_push(struct ast_threadpool *pool, int (*task)(void *data), void *data)
  179. attribute_warn_unused_result;
  180. /*!
  181. * \brief Shut down a threadpool and destroy it
  182. *
  183. * \param pool The pool to shut down
  184. */
  185. void ast_threadpool_shutdown(struct ast_threadpool *pool);
  186. struct ast_serializer_shutdown_group;
  187. /*!
  188. * \brief Create a serializer group shutdown control object.
  189. * \since 13.5.0
  190. *
  191. * \return ao2 object to control shutdown of a serializer group.
  192. */
  193. struct ast_serializer_shutdown_group *ast_serializer_shutdown_group_alloc(void);
  194. /*!
  195. * \brief Wait for the serializers in the group to shutdown with timeout.
  196. * \since 13.5.0
  197. *
  198. * \param shutdown_group Group shutdown controller. (Returns 0 immediately if NULL)
  199. * \param timeout Number of seconds to wait for the serializers in the group to shutdown.
  200. * Zero if the timeout is disabled.
  201. *
  202. * \return Number of seriaizers that did not get shutdown within the timeout.
  203. */
  204. int ast_serializer_shutdown_group_join(struct ast_serializer_shutdown_group *shutdown_group, int timeout);
  205. /*!
  206. * \brief Get the threadpool serializer currently associated with this thread.
  207. * \since 14.0.0
  208. *
  209. * \note The returned pointer is valid while the serializer
  210. * thread is running.
  211. *
  212. * \note Use ao2_ref() on serializer if you are going to keep it
  213. * for another thread. To unref it you must then use
  214. * ast_taskprocessor_unreference().
  215. *
  216. * \retval serializer on success.
  217. * \retval NULL on error or no serializer associated with the thread.
  218. */
  219. struct ast_taskprocessor *ast_threadpool_serializer_get_current(void);
  220. /*!
  221. * \brief Serialized execution of tasks within a \ref ast_threadpool.
  222. *
  223. * \since 12.0.0
  224. *
  225. * A \ref ast_taskprocessor with the same contract as a default taskprocessor
  226. * (tasks execute serially) except instead of executing out of a dedicated
  227. * thread, execution occurs in a thread from a \ref ast_threadpool. Think of it
  228. * as a lightweight thread.
  229. *
  230. * While it guarantees that each task will complete before executing the next,
  231. * there is no guarantee as to which thread from the \c pool individual tasks
  232. * will execute. This normally only matters if your code relys on thread
  233. * specific information, such as thread locals.
  234. *
  235. * Use ast_taskprocessor_unreference() to dispose of the returned \ref
  236. * ast_taskprocessor.
  237. *
  238. * Only a single taskprocessor with a given name may exist. This function will fail
  239. * if a taskprocessor with the given name already exists.
  240. *
  241. * \param name Name of the serializer. (must be unique)
  242. * \param pool \ref ast_threadpool for execution.
  243. *
  244. * \return \ref ast_taskprocessor for enqueuing work.
  245. * \return \c NULL on error.
  246. */
  247. struct ast_taskprocessor *ast_threadpool_serializer(const char *name, struct ast_threadpool *pool);
  248. /*!
  249. * \brief Serialized execution of tasks within a \ref ast_threadpool.
  250. * \since 13.5.0
  251. *
  252. * A \ref ast_taskprocessor with the same contract as a default taskprocessor
  253. * (tasks execute serially) except instead of executing out of a dedicated
  254. * thread, execution occurs in a thread from a \ref ast_threadpool. Think of it
  255. * as a lightweight thread.
  256. *
  257. * While it guarantees that each task will complete before executing the next,
  258. * there is no guarantee as to which thread from the \c pool individual tasks
  259. * will execute. This normally only matters if your code relys on thread
  260. * specific information, such as thread locals.
  261. *
  262. * Use ast_taskprocessor_unreference() to dispose of the returned \ref
  263. * ast_taskprocessor.
  264. *
  265. * Only a single taskprocessor with a given name may exist. This function will fail
  266. * if a taskprocessor with the given name already exists.
  267. *
  268. * \param name Name of the serializer. (must be unique)
  269. * \param pool \ref ast_threadpool for execution.
  270. * \param shutdown_group Group shutdown controller. (NULL if no group association)
  271. *
  272. * \return \ref ast_taskprocessor for enqueuing work.
  273. * \return \c NULL on error.
  274. */
  275. struct ast_taskprocessor *ast_threadpool_serializer_group(const char *name,
  276. struct ast_threadpool *pool, struct ast_serializer_shutdown_group *shutdown_group);
  277. /*!
  278. * \brief Return the size of the threadpool's task queue
  279. * \since 13.7.0
  280. */
  281. long ast_threadpool_queue_size(struct ast_threadpool *pool);
  282. #endif /* ASTERISK_THREADPOOL_H */