7720547d681e818e1c83344e798cc7aa39eb8a21
[asterisk/asterisk.git] / include / asterisk / taskprocessor.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007-2008, Digium, Inc.
5  *
6  * Dwayne M. Hubbard <dhubbard@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  * \file taskprocessor.h
21  * \brief An API for managing task processing threads that can be shared across modules
22  *
23  * \author Dwayne M. Hubbard <dhubbard@digium.com>
24  *
25  * \note A taskprocessor is a named singleton containing a task queue that
26  * serializes tasks pushed into it by [a] module(s) that reference the taskprocessor.
27  * A taskprocessor is created the first time its name is requested via the
28  * ast_taskprocessor_get() function or the ast_taskprocessor_create_with_listener()
29  * function and destroyed when the taskprocessor reference count reaches zero. A
30  * taskprocessor also contains an accompanying listener that is notified when changes
31  * in the task queue occur.
32  *
33  * A task is a wrapper around a task-handling function pointer and a data
34  * pointer.  A task is pushed into a taskprocessor queue using the
35  * ast_taskprocessor_push(taskprocessor, taskhandler, taskdata) function and freed by the
36  * taskprocessor after the task handling function returns.  A module releases its
37  * reference to a taskprocessor using the ast_taskprocessor_unreference() function which
38  * may result in the destruction of the taskprocessor if the taskprocessor's reference
39  * count reaches zero. When the taskprocessor's reference count reaches zero, its
40  * listener's shutdown() callback will be called. Any further attempts to execute tasks
41  * will be denied.
42  *
43  * The taskprocessor listener has the flexibility of doling out tasks to best fit the
44  * module's needs. For instance, a taskprocessor listener may have a single dispatch
45  * thread that handles all tasks, or it may dispatch tasks to a thread pool.
46  *
47  * There is a default taskprocessor listener that will be used if a taskprocessor is
48  * created without any explicit listener. This default listener runs tasks sequentially
49  * in a single thread. The listener will execute tasks as long as there are tasks to be
50  * processed. When the taskprocessor is shut down, the default listener will stop
51  * processing tasks and join its execution thread.
52  */
53
54 #ifndef __AST_TASKPROCESSOR_H__
55 #define __AST_TASKPROCESSOR_H__
56
57 struct ast_taskprocessor;
58
59 /*!
60  * \brief ast_tps_options for specification of taskprocessor options
61  *
62  * Specify whether a taskprocessor should be created via ast_taskprocessor_get() if the taskprocessor
63  * does not already exist.  The default behavior is to create a taskprocessor if it does not already exist
64  * and provide its reference to the calling function.  To only return a reference to a taskprocessor if
65  * and only if it exists, use the TPS_REF_IF_EXISTS option in ast_taskprocessor_get().
66  */
67 enum ast_tps_options {
68         /*! \brief return a reference to a taskprocessor, create one if it does not exist */
69         TPS_REF_DEFAULT = 0,
70         /*! \brief return a reference to a taskprocessor ONLY if it already exists */
71         TPS_REF_IF_EXISTS = (1 << 0),
72 };
73
74 struct ast_taskprocessor_listener;
75
76 struct ast_taskprocessor_listener_callbacks {
77         /*!
78          * \brief Allocate the listener's private data
79          *
80          * This is called during taskprocesor creation.
81          * It is not necessary to assign the private data to the listener.
82          *
83          * \param listener The listener to which the private data belongs
84          * \retval NULL Error while attempting to initialize private data
85          * \retval non-NULL Allocated private data
86          */
87         void *(*alloc)(struct ast_taskprocessor_listener *listener);
88         /*!
89          * \brief The taskprocessor has started completely
90          *
91          * This indicates that the taskprocessor is fully set up and the listener
92          * can now start interacting with it.
93          *
94          * \param listener The listener to start
95          */
96         int (*start)(struct ast_taskprocessor_listener *listener);
97         /*!
98          * \brief Indicates a task was pushed to the processor
99          *
100          * \param listener The listener
101          * \param was_empty If non-zero, the taskprocessor was empty prior to the task being pushed
102          */
103         void (*task_pushed)(struct ast_taskprocessor_listener *listener, int was_empty);
104         /*!
105          * \brief Indicates the task processor has become empty
106          *
107          * \param listener The listener
108          */
109         void (*emptied)(struct ast_taskprocessor_listener *listener);
110         /*!
111          * \brief Indicates the taskprocessor wishes to die.
112          *
113          * All operations on the task processor must to be stopped in
114          * this callback.
115          *
116          * After this callback returns, it is NOT safe to operate on the
117          * listener's reference to the taskprocessor.
118          *
119          * \param listener The listener
120          */
121         void (*shutdown)(struct ast_taskprocessor_listener *listener);
122         /*!
123          * \brief Destroy the listener's private data
124          *
125          * It is required that you free the private data in this callback
126          * in addition to the private data's individual fields.
127          *
128          * \param private_data The listener's private data
129          */
130         void (*destroy)(void *private_data);
131 };
132
133 /*!
134  * \brief A listener for taskprocessors
135  *
136  * \since 12.0.0
137  *
138  * When a taskprocessor's state changes, the listener
139  * is notified of the change. This allows for tasks
140  * to be addressed in whatever way is appropriate for
141  * the module using the taskprocessor.
142  */
143 struct ast_taskprocessor_listener {
144         /*! The callbacks the taskprocessor calls into to notify of state changes */
145         const struct ast_taskprocessor_listener_callbacks *callbacks;
146         /*! The taskprocessor that the listener is listening to */
147         struct ast_taskprocessor *tps;
148         /*! Data private to the listener */
149         void *private_data;
150 };
151
152 /*!
153  * \brief Allocate a taskprocessor listener
154  *
155  * \since 12.0.0
156  *
157  * This will result in the listener being allocated with the specified
158  * callbacks.
159  *
160  * \param callbacks The callbacks to assign to the listener
161  * \retval NULL Failure
162  * \retval non-NULL The newly allocated taskprocessor listener
163  */
164 struct ast_taskprocessor_listener *ast_taskprocessor_listener_alloc(const struct ast_taskprocessor_listener_callbacks *callbacks);
165
166 /*!
167  * \brief Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary
168  *
169  * The default behavior of instantiating a taskprocessor if one does not already exist can be
170  * disabled by specifying the TPS_REF_IF_EXISTS ast_tps_options as the second argument to ast_taskprocessor_get().
171  * \param name The name of the taskprocessor
172  * \param create Use 0 by default or specify TPS_REF_IF_EXISTS to return NULL if the taskprocessor does
173  * not already exist
174  * return A pointer to a reference counted taskprocessor under normal conditions, or NULL if the
175  * TPS_REF_IF_EXISTS reference type is specified and the taskprocessor does not exist
176  * \since 1.6.1
177  */
178 struct ast_taskprocessor *ast_taskprocessor_get(const char *name, enum ast_tps_options create);
179
180 /*!
181  * \brief Create a taskprocessor with a custom listener
182  *
183  * \since 12.0.0
184  *
185  * The listener's alloc() and start() callbacks will be called during this function.
186  *
187  * \param name The name of the taskprocessor to create
188  * \param listener The listener for operations on this taskprocessor
189  * \retval NULL Failure
190  * \reval non-NULL success
191  */
192 struct ast_taskprocessor *ast_taskprocessor_create_with_listener(const char *name, struct ast_taskprocessor_listener *listener);
193
194 /*!
195  * \brief Unreference the specified taskprocessor and its reference count will decrement.
196  *
197  * Taskprocessors use astobj2 and will unlink from the taskprocessor singleton container and destroy
198  * themself when the taskprocessor reference count reaches zero.
199  * \param tps taskprocessor to unreference
200  * \return NULL
201  * \since 1.6.1
202  */
203 void *ast_taskprocessor_unreference(struct ast_taskprocessor *tps);
204
205 /*!
206  * \brief Push a task into the specified taskprocessor queue and signal the taskprocessor thread
207  * \param tps The taskprocessor structure
208  * \param task_exe The task handling function to push into the taskprocessor queue
209  * \param datap The data to be used by the task handling function
210  * \retval 0 success
211  * \retval -1 failure
212  * \since 1.6.1
213  */
214 int ast_taskprocessor_push(struct ast_taskprocessor *tps, int (*task_exe)(void *datap), void *datap);
215
216 /*!
217  * \brief Pop a task off the taskprocessor and execute it.
218  *
219  * \since 12.0.0
220  *
221  * \param tps The taskprocessor from which to execute.
222  * \retval 0 There is no further work to be done.
223  * \retval 1 Tasks still remain in the taskprocessor queue.
224  */
225 int ast_taskprocessor_execute(struct ast_taskprocessor *tps);
226
227 /*!
228  * \brief Return the name of the taskprocessor singleton
229  * \since 1.6.1
230  */
231 const char *ast_taskprocessor_name(struct ast_taskprocessor *tps);
232
233 #endif /* __AST_TASKPROCESSOR_H__ */