89076265e1d5be02766600601e689b12d613dfc0
[asterisk/asterisk.git] / include / asterisk / threadpool.h
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
19
20 #ifndef _ASTERISK_THREADPOOL_H
21 #define _ASTERISK_THREADPOOL_H
22
23 struct ast_threadpool;
24 struct ast_taskprocessor;
25 struct ast_threadpool_listener;
26
27 struct ast_threadpool_listener_callbacks {
28         /*!
29          * \brief Indicates that the state of threads in the pool has changed
30          *
31          * \param pool The pool whose state has changed
32          * \param listener The threadpool listener
33          * \param active_threads The number of active threads in the pool
34          * \param idle_threads The number of idle threads in the pool
35          */
36         void (*state_changed)(struct ast_threadpool *pool,
37                         struct ast_threadpool_listener *listener,
38                         int active_threads,
39                         int idle_threads);
40         /*!
41          * \brief Indicates that a task was pushed to the threadpool
42          *
43          * \param pool The pool that had a task pushed
44          * \param listener The threadpool listener
45          * \param was_empty Indicates whether there were any tasks prior to adding the new one.
46          */
47         void (*task_pushed)(struct ast_threadpool *pool,
48                         struct ast_threadpool_listener *listener,
49                         int was_empty);
50         /*!
51          * \brief Indicates the threadpool's taskprocessor has become empty
52          *
53          * \param pool The pool that has become empty
54          * \param listener The threadpool's listener
55          */
56         void (*emptied)(struct ast_threadpool *pool, struct ast_threadpool_listener *listener);
57
58         /*!
59          * \brief The threadpool is shutting down
60          *
61          * This would be an opportune time to free the listener's user data
62          * if one wishes. However, it is acceptable to not do so if the user data
63          * should persist beyond the lifetime of the pool.
64          *
65          * \param listener The threadpool's listener
66          */
67         void (*shutdown)(struct ast_threadpool_listener *listener);
68 };
69
70 struct ast_threadpool_options {
71 #define AST_THREADPOOL_OPTIONS_VERSION 1
72         /*! Version of threadpool options in use */
73         int version;
74         /*!
75          * \brief Time limit in seconds for idle threads
76          *
77          * A time of 0 or less will mean no timeout.
78          */
79         int idle_timeout;
80         /*!
81          * \brief Number of threads to increment pool by
82          *
83          * If a task is added into a pool and no idle thread is
84          * available to activate, then the pool can automatically
85          * grow by the given amount.
86          *
87          * Zero is a perfectly valid value to give here if you want
88          * to control threadpool growth yourself via your listener.
89          */
90         int auto_increment;
91         /*!
92          * \brief Number of threads the pool will start with
93          *
94          * When the threadpool is allocated, it will immediately size
95          * itself to have this number of threads in it.
96          *
97          * Zero is a valid value if the threadpool should start
98          * without any threads allocated.
99          */
100         int initial_size;
101         /*!
102          * \brief Maximum number of threads a pool may have
103          *
104          * When the threadpool's size increases, it can never increase
105          * beyond this number of threads.
106          *
107          * Zero is a valid value if the threadpool does not have a
108          * maximum size.
109          */
110         int max_size;
111 };
112
113 /*!
114  * \brief Allocate a threadpool listener
115  *
116  * This function will call back into the alloc callback for the
117  * listener.
118  *
119  * \param callbacks Listener callbacks to assign to the listener
120  * \param user_data User data to be stored in the threadpool listener
121  * \retval NULL Failed to allocate the listener
122  * \retval non-NULL The newly-created threadpool listener
123  */
124 struct ast_threadpool_listener *ast_threadpool_listener_alloc(
125                 const struct ast_threadpool_listener_callbacks *callbacks, void *user_data);
126
127 /*!
128  * \brief Get the threadpool listener's user data
129  * \param listener The threadpool listener
130  * \return The user data
131  */
132 void *ast_threadpool_listener_get_user_data(const struct ast_threadpool_listener *listener);
133
134 /*!
135  * \brief Create a new threadpool
136  *
137  * This function creates a threadpool. Tasks may be pushed onto this thread pool
138  * and will be automatically acted upon by threads within the pool.
139  *
140  * Only a single threadpool with a given name may exist. This function will fail
141  * if a threadpool with the given name already exists.
142  *
143  * \param name The unique name for the threadpool
144  * \param listener The listener the threadpool will notify of changes. Can be NULL.
145  * \param options The behavioral options for this threadpool
146  * \retval NULL Failed to create the threadpool
147  * \retval non-NULL The newly-created threadpool
148  */
149 struct ast_threadpool *ast_threadpool_create(const char *name,
150                 struct ast_threadpool_listener *listener,
151                 const struct ast_threadpool_options *options);
152
153 /*!
154  * \brief Set the number of threads for the thread pool
155  *
156  * This number may be more or less than the current number of
157  * threads in the threadpool.
158  *
159  * \param threadpool The threadpool to adjust
160  * \param size The new desired size of the threadpool
161  */
162 void ast_threadpool_set_size(struct ast_threadpool *threadpool, unsigned int size);
163
164 /*!
165  * \brief Push a task to the threadpool
166  *
167  * Tasks pushed into the threadpool will be automatically taken by
168  * one of the threads within
169  * \param pool The threadpool to add the task to
170  * \param task The task to add
171  * \param data The parameter for the task
172  * \retval 0 success
173  * \retval -1 failure
174  */
175 int ast_threadpool_push(struct ast_threadpool *pool, int (*task)(void *data), void *data);
176
177 /*!
178  * \brief Shut down a threadpool and destroy it
179  *
180  * \param pool The pool to shut down
181  */
182 void ast_threadpool_shutdown(struct ast_threadpool *pool);
183
184 /*!
185  * \brief Serialized execution of tasks within a \ref ast_threadpool.
186  *
187  * \since 12.0.0
188  *
189  * A \ref ast_taskprocessor with the same contract as a default taskprocessor
190  * (tasks execute serially) except instead of executing out of a dedicated
191  * thread, execution occurs in a thread from a \ref ast_threadpool. Think of it
192  * as a lightweight thread.
193  *
194  * While it guarantees that each task will complete before executing the next,
195  * there is no guarantee as to which thread from the \c pool individual tasks
196  * will execute. This normally only matters if your code relys on thread
197  * specific information, such as thread locals.
198  *
199  * Use ast_taskprocessor_unreference() to dispose of the returned \ref
200  * ast_taskprocessor.
201  *
202  * Only a single taskprocessor with a given name may exist. This function will fail
203  * if a taskprocessor with the given name already exists.
204  *
205  * \param name Name of the serializer. (must be unique)
206  * \param pool \ref ast_threadpool for execution.
207  * \return \ref ast_taskprocessor for enqueuing work.
208  * \return \c NULL on error.
209  */
210 struct ast_taskprocessor *ast_threadpool_serializer(const char *name, struct ast_threadpool *pool);
211
212 #endif /* ASTERISK_THREADPOOL_H */