Asterisk - The Open Source Telephony Project GIT-master-f36a736
command.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2013, Digium, Inc.
5 *
6 * David M. Lee, II <dlee@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/*! \file
20 *
21 * \brief Stasis application command support.
22 *
23 * \author David M. Lee, II <dlee@digium.com>
24 */
25
26#include "asterisk.h"
27
28#include "command.h"
29
30#include "asterisk/lock.h"
32
37 void *data;
39 int retval;
40 unsigned int is_done:1;
41};
42
43static void command_dtor(void *obj)
44{
45 struct stasis_app_command *command = obj;
46
47 if (command->data_destructor) {
48 command->data_destructor(command->data);
49 }
50
51 ast_mutex_destroy(&command->lock);
52 ast_cond_destroy(&command->condition);
53}
54
57{
58 struct stasis_app_command *command;
59
60 command = ao2_alloc(sizeof(*command), command_dtor);
61 if (!command) {
62 if (data_destructor) {
64 }
65 return NULL;
66 }
67
68 ast_mutex_init(&command->lock);
69 ast_cond_init(&command->condition, 0);
70 command->callback = callback;
71 command->data = data;
73
74 return command;
75}
76
77void command_complete(struct stasis_app_command *command, int retval)
78{
79 ast_mutex_lock(&command->lock);
80 command->is_done = 1;
81 command->retval = retval;
82 ast_cond_signal(&command->condition);
83 ast_mutex_unlock(&command->lock);
84}
85
86int command_join(struct stasis_app_command *command)
87{
88 int ret;
89
90 ast_mutex_lock(&command->lock);
91 while (!command->is_done) {
92 ast_cond_wait(&command->condition, &command->lock);
93 }
94
95 ret = command->retval;
96 ast_mutex_unlock(&command->lock);
97
98 return ret;
99}
100
102 struct stasis_app_control *control, struct ast_channel *chan)
103{
104 int retval = command->callback(control, chan, command->data);
105 if (command->data_destructor) {
106 command->data_destructor(command->data);
107 command->data_destructor = NULL;
108 }
109 command_complete(command, retval);
110}
111
112static void command_queue_prestart_destroy(void *obj)
113{
114 /* Clean up the container */
115 ao2_cleanup(obj);
116}
117
119 .type = "stasis-command-prestart-queue",
121};
122
124 stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
125{
126 struct ast_datastore *datastore;
127 struct ao2_container *command_queue;
128 RAII_VAR(struct stasis_app_command *, command,
129 command_create(command_fn, data, data_destructor), ao2_cleanup);
130
131 if (!command) {
132 return -1;
133 }
134
136 if (datastore) {
137 command_queue = datastore->data;
138 ao2_link(command_queue, command);
139 return 0;
140 }
141
143 if (!command_queue) {
144 return -1;
145 }
146
148 if (!datastore) {
149 ao2_cleanup(command_queue);
150 return -1;
151 }
152 ast_channel_datastore_add(chan, datastore);
153
154 datastore->data = command_queue;
155 ao2_link(command_queue, command);
156
157 return 0;
158}
159
161{
163
164 if (!datastore) {
165 return NULL;
166 }
167
168 return ao2_bump(datastore->data);
169}
Asterisk main include file. File version handling, generic pbx functions.
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2404
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2418
struct ao2_container * command_prestart_get_container(struct ast_channel *chan)
Get the Stasis() prestart commands for a channel.
Definition: command.c:160
struct stasis_app_command * command_create(stasis_app_command_cb callback, void *data, command_data_destructor_fn data_destructor)
Definition: command.c:55
void command_invoke(struct stasis_app_command *command, struct stasis_app_control *control, struct ast_channel *chan)
Definition: command.c:101
static void command_dtor(void *obj)
Definition: command.c:43
int command_prestart_queue_command(struct ast_channel *chan, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Queue a Stasis() prestart command for a channel.
Definition: command.c:123
static void command_queue_prestart_destroy(void *obj)
Definition: command.c:112
void command_complete(struct stasis_app_command *command, int retval)
Definition: command.c:77
int command_join(struct stasis_app_command *command)
Definition: command.c:86
static const struct ast_datastore_info command_queue_prestart
Definition: command.c:118
Internal API for the Stasis application commands.
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
static ENTRY retval
Definition: hsearch.c:50
Asterisk locking-related definitions:
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_mutex_unlock(a)
Definition: lock.h:190
pthread_cond_t ast_cond_t
Definition: lock.h:178
#define ast_mutex_destroy(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:189
#define ast_cond_signal(cond)
Definition: lock.h:203
#define NULL
Definition: resample.c:96
Backend API for implementing components of res_stasis.
void(* command_data_destructor_fn)(void *data)
Typedef for data destructor for stasis app commands.
int(* stasis_app_command_cb)(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Generic container type.
Main Channel structure associated with a channel.
Structure for a data store type.
Definition: datastore.h:31
const char * type
Definition: datastore.h:32
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
Structure for mutex and tracking information.
Definition: lock.h:135
stasis_app_command_cb callback
Definition: command.c:36
ast_cond_t condition
Definition: command.c:35
command_data_destructor_fn data_destructor
Definition: command.c:38
unsigned int is_done
Definition: command.c:40
ast_mutex_t lock
Definition: command.c:34
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941