Merge the pimp_my_sip branch into trunk.
[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          * \brief Function to call when a thread starts
113          *
114          * This is useful if there is something common that all threads
115          * in a threadpool need to do when they start.
116          */
117         void (*thread_start)(void);
118         /*!
119          * \brief Function to call when a thread ends
120          *
121          * This is useful if there is common cleanup to execute when
122          * a thread completes
123          */
124         void (*thread_end)(void);
125 };
126
127 /*!
128  * \brief Allocate a threadpool listener
129  *
130  * This function will call back into the alloc callback for the
131  * listener.
132  *
133  * \param callbacks Listener callbacks to assign to the listener
134  * \param user_data User data to be stored in the threadpool listener
135  * \retval NULL Failed to allocate the listener
136  * \retval non-NULL The newly-created threadpool listener
137  */
138 struct ast_threadpool_listener *ast_threadpool_listener_alloc(
139                 const struct ast_threadpool_listener_callbacks *callbacks, void *user_data);
140
141 /*!
142  * \brief Get the threadpool listener's user data
143  * \param listener The threadpool listener
144  * \return The user data
145  */
146 void *ast_threadpool_listener_get_user_data(const struct ast_threadpool_listener *listener);
147
148 /*!
149  * \brief Create a new threadpool
150  *
151  * This function creates a threadpool. Tasks may be pushed onto this thread pool
152  * and will be automatically acted upon by threads within the pool.
153  *
154  * Only a single threadpool with a given name may exist. This function will fail
155  * if a threadpool with the given name already exists.
156  *
157  * \param name The unique name for the threadpool
158  * \param listener The listener the threadpool will notify of changes. Can be NULL.
159  * \param options The behavioral options for this threadpool
160  * \retval NULL Failed to create the threadpool
161  * \retval non-NULL The newly-created threadpool
162  */
163 struct ast_threadpool *ast_threadpool_create(const char *name,
164                 struct ast_threadpool_listener *listener,
165                 const struct ast_threadpool_options *options);
166
167 /*!
168  * \brief Set the number of threads for the thread pool
169  *
170  * This number may be more or less than the current number of
171  * threads in the threadpool.
172  *
173  * \param threadpool The threadpool to adjust
174  * \param size The new desired size of the threadpool
175  */
176 void ast_threadpool_set_size(struct ast_threadpool *threadpool, unsigned int size);
177
178 /*!
179  * \brief Push a task to the threadpool
180  *
181  * Tasks pushed into the threadpool will be automatically taken by
182  * one of the threads within
183  * \param pool The threadpool to add the task to
184  * \param task The task to add
185  * \param data The parameter for the task
186  * \retval 0 success
187  * \retval -1 failure
188  */
189 int ast_threadpool_push(struct ast_threadpool *pool, int (*task)(void *data), void *data);
190
191 /*!
192  * \brief Shut down a threadpool and destroy it
193  *
194  * \param pool The pool to shut down
195  */
196 void ast_threadpool_shutdown(struct ast_threadpool *pool);
197
198 /*!
199  * \brief Serialized execution of tasks within a \ref ast_threadpool.
200  *
201  * \since 12.0.0
202  *
203  * A \ref ast_taskprocessor with the same contract as a default taskprocessor
204  * (tasks execute serially) except instead of executing out of a dedicated
205  * thread, execution occurs in a thread from a \ref ast_threadpool. Think of it
206  * as a lightweight thread.
207  *
208  * While it guarantees that each task will complete before executing the next,
209  * there is no guarantee as to which thread from the \c pool individual tasks
210  * will execute. This normally only matters if your code relys on thread
211  * specific information, such as thread locals.
212  *
213  * Use ast_taskprocessor_unreference() to dispose of the returned \ref
214  * ast_taskprocessor.
215  *
216  * Only a single taskprocessor with a given name may exist. This function will fail
217  * if a taskprocessor with the given name already exists.
218  *
219  * \param name Name of the serializer. (must be unique)
220  * \param pool \ref ast_threadpool for execution.
221  * \return \ref ast_taskprocessor for enqueuing work.
222  * \return \c NULL on error.
223  */
224 struct ast_taskprocessor *ast_threadpool_serializer(const char *name, struct ast_threadpool *pool);
225
226 #endif /* ASTERISK_THREADPOOL_H */