summaryrefslogtreecommitdiff
path: root/include/asterisk/taskprocessor.h
blob: df66f59f076d211589e3d4c19c2adde5204a5e96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Asterisk -- An open source telephony toolkit.
 *
 * Copyright (C) 2007-2008, Digium, Inc.
 *
 * Dwayne M. Hubbard <dhubbard@digium.com>
 *
 * See http://www.asterisk.org for more information about
 * the Asterisk project. Please do not directly contact
 * any of the maintainers of this project for assistance;
 * the project provides a web site, mailing lists and IRC
 * channels for your use.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License Version 2. See the LICENSE file
 * at the top of the source tree.
 */

/*!
 * \file taskprocessor.h
 * \brief An API for managing task processing threads that can be shared across modules
 *
 * \author Dwayne M. Hubbard <dhubbard@digium.com>
 *
 * \note A taskprocessor is a named singleton containing a processing thread and
 * a task queue that serializes tasks pushed into it by [a] module(s) that reference the taskprocessor.  
 * A taskprocessor is created the first time its name is requested via the ast_taskprocessor_get()
 * function and destroyed when the taskprocessor reference count reaches zero.
 *
 * Modules that obtain a reference to a taskprocessor can queue tasks into the taskprocessor
 * to be processed by the singleton processing thread when the task is popped off the front 
 * of the queue.  A task is a wrapper around a task-handling function pointer and a data
 * pointer.  It is the responsibility of the task handling function to free memory allocated for
 * the task data pointer.  A task is pushed into a taskprocessor queue using the 
 * ast_taskprocessor_push(taskprocessor, taskhandler, taskdata) function and freed by the
 * taskprocessor after the task handling function returns.  A module releases its reference to a
 * taskprocessor using the ast_taskprocessor_unreference() function which may result in the
 * destruction of the taskprocessor if the taskprocessor's reference count reaches zero.  Tasks waiting
 * to be processed in the taskprocessor queue when the taskprocessor reference count reaches zero
 * will be purged and released from the taskprocessor queue without being processed.
 */

#ifndef __AST_TASKPROCESSOR_H__
#define __AST_TASKPROCESSOR_H__

struct ast_taskprocessor;

/*!
 * \brief ast_tps_options for specification of taskprocessor options
 *
 * Specify whether a taskprocessor should be created via ast_taskprocessor_get() if the taskprocessor 
 * does not already exist.  The default behavior is to create a taskprocessor if it does not already exist 
 * and provide its reference to the calling function.  To only return a reference to a taskprocessor if 
 * and only if it exists, use the TPS_REF_IF_EXISTS option in ast_taskprocessor_get().
 */
enum ast_tps_options {
	/*! \brief return a reference to a taskprocessor, create one if it does not exist */
	TPS_REF_DEFAULT = 0,
	/*! \brief return a reference to a taskprocessor ONLY if it already exists */
	TPS_REF_IF_EXISTS = (1 << 0),
};

struct ast_taskprocessor_listener;

struct ast_taskprocessor_listener_callbacks {
	/*! Indicates a task was pushed to the processor */
	void (*task_pushed)(struct ast_taskprocessor_listener *listener, int was_empty);
	/*! Indicates the task processor has become empty */
	void (*emptied)(struct ast_taskprocessor_listener *listener);
};

struct ast_taskprocessor_listener {
	struct ast_taskprocessor_listener_callbacks *callbacks;
	struct ast_taskprocessor *tps;
	void *private_data;
};

/*!
 * \brief Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary
 *
 * The default behavior of instantiating a taskprocessor if one does not already exist can be
 * disabled by specifying the TPS_REF_IF_EXISTS ast_tps_options as the second argument to ast_taskprocessor_get().
 * \param name The name of the taskprocessor
 * \param create Use 0 by default or specify TPS_REF_IF_EXISTS to return NULL if the taskprocessor does 
 * not already exist
 * return A pointer to a reference counted taskprocessor under normal conditions, or NULL if the
 * TPS_REF_IF_EXISTS reference type is specified and the taskprocessor does not exist
 * \since 1.6.1
 */
struct ast_taskprocessor *ast_taskprocessor_get(const char *name, enum ast_tps_options create);

/*!
 * \brief Create a taskprocessor with a custom listener
 *
 * \param name The name of the taskprocessor to create
 * \param listener The listener for operations on this taskprocessor
 * \retval NULL Failure
 * \reval non-NULL success
 */
struct ast_taskprocessor *ast_taskprocessor_create_with_listener(const char *name, struct ast_taskprocessor_listener *listener);

/*!
 * \brief Unreference the specified taskprocessor and its reference count will decrement.
 *
 * Taskprocessors use astobj2 and will unlink from the taskprocessor singleton container and destroy
 * themself when the taskprocessor reference count reaches zero.
 * \param tps taskprocessor to unreference
 * \return NULL
 * \since 1.6.1
 */
void *ast_taskprocessor_unreference(struct ast_taskprocessor *tps);

/*!
 * \brief Push a task into the specified taskprocessor queue and signal the taskprocessor thread
 * \param tps The taskprocessor structure
 * \param task_exe The task handling function to push into the taskprocessor queue
 * \param datap The data to be used by the task handling function
 * \retval 0 success
 * \retval -1 failure
 * \since 1.6.1
 */
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int (*task_exe)(void *datap), void *datap);

/*!
 * \brief Pop a task off the taskprocessor and execute it.
 * \param tps The taskprocessor from which to execute.
 * \retval 0 There is no further work to be done.
 * \retval 1 Tasks still remain in the taskprocessor queue.
 */
int ast_taskprocessor_execute(struct ast_taskprocessor *tps);

/*!
 * \brief Return the name of the taskprocessor singleton
 * \since 1.6.1
 */
const char *ast_taskprocessor_name(struct ast_taskprocessor *tps);

#endif /* __AST_TASKPROCESSOR_H__ */