summaryrefslogtreecommitdiff
path: root/res/stasis/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'res/stasis/control.c')
-rw-r--r--res/stasis/control.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/res/stasis/control.c b/res/stasis/control.c
index a1004248f..86f94423d 100644
--- a/res/stasis/control.c
+++ b/res/stasis/control.c
@@ -251,6 +251,11 @@ static struct stasis_app_command *exec_command_on_condition(
}
ao2_lock(control->command_queue);
+ if (control->is_done) {
+ ao2_unlock(control->command_queue);
+ ao2_ref(command, -1);
+ return NULL;
+ }
if (can_exec_fn && (retval = can_exec_fn(control))) {
ao2_unlock(control->command_queue);
command_complete(command, retval);
@@ -402,7 +407,10 @@ int control_is_done(struct stasis_app_control *control)
void control_mark_done(struct stasis_app_control *control)
{
+ /* Locking necessary to sync with other threads adding commands to the queue. */
+ ao2_lock(control->command_queue);
control->is_done = 1;
+ ao2_unlock(control->command_queue);
}
struct stasis_app_control_continue_data {
@@ -427,7 +435,7 @@ static int app_control_continue(struct stasis_app_control *control,
/* Called from stasis_app_exec thread; no lock needed */
ast_explicit_goto(control->channel, continue_data->context, continue_data->extension, continue_data->priority);
- control->is_done = 1;
+ control_mark_done(control);
return 0;
}
@@ -1115,24 +1123,36 @@ int stasis_app_control_queue_control(struct stasis_app_control *control,
return ast_queue_control(control->channel, frame_type);
}
+void control_flush_queue(struct stasis_app_control *control)
+{
+ struct ao2_iterator iter;
+ struct stasis_app_command *command;
+
+ iter = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK);
+ while ((command = ao2_iterator_next(&iter))) {
+ command_complete(command, -1);
+ ao2_ref(command, -1);
+ }
+ ao2_iterator_destroy(&iter);
+}
+
int control_dispatch_all(struct stasis_app_control *control,
struct ast_channel *chan)
{
int count = 0;
- struct ao2_iterator i;
- void *obj;
+ struct ao2_iterator iter;
+ struct stasis_app_command *command;
ast_assert(control->channel == chan);
- i = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK);
-
- while ((obj = ao2_iterator_next(&i))) {
- RAII_VAR(struct stasis_app_command *, command, obj, ao2_cleanup);
+ iter = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK);
+ while ((command = ao2_iterator_next(&iter))) {
command_invoke(command, control, chan);
+ ao2_ref(command, -1);
++count;
}
+ ao2_iterator_destroy(&iter);
- ao2_iterator_destroy(&i);
return count;
}