Asterisk - The Open Source Telephony Project GIT-master-2de1a68
Functions
control.h File Reference

Internal API for the Stasis application controller. More...

#include "asterisk/stasis_app.h"
Include dependency graph for control.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int control_add_channel_to_bridge (struct stasis_app_control *control, struct ast_channel *chan, void *data)
 Command callback for adding a channel to a bridge. More...
 
struct stasis_appcontrol_app (struct stasis_app_control *control)
 Returns the pointer (non-reffed) to the app associated with this control. More...
 
int control_command_count (struct stasis_app_control *control)
 Returns the count of items in a control's command queue. More...
 
struct stasis_app_controlcontrol_create (struct ast_channel *channel, struct stasis_app *app)
 Create a control object. More...
 
int control_dispatch_all (struct stasis_app_control *control, struct ast_channel *chan)
 Dispatch all commands enqueued to this control. More...
 
void control_flush_queue (struct stasis_app_control *control)
 Flush the control command queue. More...
 
int control_is_done (struct stasis_app_control *control)
 Returns true if control_continue() has been called on this control. More...
 
void control_mark_done (struct stasis_app_control *control)
 
void control_move_cleanup (struct stasis_app_control *control)
 Free any memory that was allocated for switching applications via /channels/{channelId}/move. More...
 
char * control_next_app (struct stasis_app_control *control)
 Returns the name of the application we are moving to. More...
 
char ** control_next_app_args (struct stasis_app_control *control)
 Returns the list of arguments to pass to the application we are moving to. More...
 
int control_next_app_args_size (struct stasis_app_control *control)
 Returns the number of arguments to be passed to the application we are moving to. More...
 
int control_prestart_dispatch_all (struct stasis_app_control *control, struct ast_channel *chan)
 Dispatch all queued prestart commands. More...
 
void control_set_app (struct stasis_app_control *control, struct stasis_app *app)
 Set the application the control object belongs to. More...
 
void control_set_thread (struct stasis_app_control *control, pthread_t threadid)
 set the control's thread id More...
 
void control_silence_stop_now (struct stasis_app_control *control)
 Stop playing silence to a channel right now. More...
 
int control_swap_channel_in_bridge (struct stasis_app_control *control, struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
 Command for swapping a channel in a bridge. More...
 
void control_wait (struct stasis_app_control *control)
 Blocks until control's command queue has a command available. More...
 

Detailed Description

Internal API for the Stasis application controller.

Author
David M. Lee, II dlee@.nosp@m.digi.nosp@m.um.co.nosp@m.m
Since
12

Definition in file control.h.

Function Documentation

◆ control_add_channel_to_bridge()

int control_add_channel_to_bridge ( struct stasis_app_control control,
struct ast_channel chan,
void *  data 
)

Command callback for adding a channel to a bridge.

Parameters
controlThe control for chan
chanThe channel on which commands should be executed
dataBridge to be passed to the callback

Definition at line 1398 of file control.c.

1399{
1400 return control_swap_channel_in_bridge(control, data, chan, NULL);
1401}
int control_swap_channel_in_bridge(struct stasis_app_control *control, struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
Command for swapping a channel in a bridge.
Definition: control.c:1304
#define NULL
Definition: resample.c:96

References control_swap_channel_in_bridge(), and NULL.

Referenced by stasis_app_control_add_channel_to_bridge().

◆ control_app()

struct stasis_app * control_app ( struct stasis_app_control control)

Returns the pointer (non-reffed) to the app associated with this control.

Parameters
controlControl to query.
Returns
A pointer to the associated stasis_app

Definition at line 1583 of file control.c.

1584{
1585 return control->app;
1586}
struct stasis_app * app
Definition: control.c:90

References stasis_app_control::app.

Referenced by bridge_stasis_moving(), bridge_stasis_push_peek(), channel_replaced_cb(), channel_stolen_cb(), and stasis_app_exec().

◆ control_command_count()

int control_command_count ( struct stasis_app_control control)

Returns the count of items in a control's command queue.

Parameters
controlControl to count commands on
Returns
number of commands in the command que

Definition at line 363 of file control.c.

364{
365 return ao2_container_count(control->command_queue);
366}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_container * command_queue
Definition: control.c:54

References ao2_container_count(), and stasis_app_control::command_queue.

Referenced by stasis_app_control_execute_until_exhausted().

◆ control_create()

struct stasis_app_control * control_create ( struct ast_channel channel,
struct stasis_app app 
)

Create a control object.

Parameters
channelChannel to control.
appstasis_app for which this control is being created.
Returns
New control object.
Return values
NULLon error.

Definition at line 127 of file control.c.

128{
129 struct stasis_app_control *control;
130 int res;
131
132 control = ao2_alloc(sizeof(*control), control_dtor);
133 if (!control) {
134 return NULL;
135 }
136
137 AST_LIST_HEAD_INIT(&control->add_rules);
139
140 res = ast_cond_init(&control->wait_cond, NULL);
141 if (res != 0) {
142 ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
143 strerror(errno));
144 ao2_ref(control, -1);
145 return NULL;
146 }
147
148 control->app = ao2_bump(app);
149
151 control->channel = channel;
152
155 if (!control->command_queue) {
156 ao2_ref(control, -1);
157 return NULL;
158 }
159
160 control->next_app = NULL;
161 AST_VECTOR_INIT(&control->next_app_args, 0);
162
164
165 return control;
166}
static const char app[]
Definition: app_adsiprog.c:56
#define ast_log
Definition: astobj2.c:42
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#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
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
void control_set_thread(struct stasis_app_control *control, pthread_t threadid)
set the control's thread id
Definition: control.c:194
static void control_dtor(void *obj)
Definition: control.c:109
#define LOG_ERROR
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_cond_init(cond, attr)
Definition: lock.h:201
int errno
struct ast_channel * channel
Definition: control.c:60
struct stasis_app_control::@489 next_app_args
struct app_control_rules remove_rules
Definition: control.c:80
char * next_app
Definition: control.c:94
struct app_control_rules add_rules
Definition: control.c:76
ast_cond_t wait_cond
Definition: control.c:52
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References stasis_app_control::add_rules, ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_bump, ao2_container_alloc_list, ao2_ref, app, stasis_app_control::app, ast_channel_ref, ast_cond_init, AST_LIST_HEAD_INIT, ast_log, AST_PTHREADT_NULL, AST_VECTOR_INIT, stasis_app_control::channel, stasis_app_control::command_queue, control_dtor(), control_set_thread(), errno, LOG_ERROR, stasis_app_control::next_app, stasis_app_control::next_app_args, NULL, stasis_app_control::remove_rules, and stasis_app_control::wait_cond.

Referenced by stasis_app_control_create(), and stasis_app_exec().

◆ control_dispatch_all()

int control_dispatch_all ( struct stasis_app_control control,
struct ast_channel chan 
)

Dispatch all commands enqueued to this control.

Parameters
controlControl object to dispatch.
chanAssociated channel.
Returns
Number of commands executed

Definition at line 1515 of file control.c.

1517{
1518 int count = 0;
1519 struct ao2_iterator iter;
1520 struct stasis_app_command *command;
1521
1522 ast_assert(control->channel == chan);
1523
1525 while ((command = ao2_iterator_next(&iter))) {
1526 command_invoke(command, control, chan);
1527 ao2_ref(command, -1);
1528 ++count;
1529 }
1530 ao2_iterator_destroy(&iter);
1531
1532 return count;
1533}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
@ AO2_ITERATOR_UNLINK
Definition: astobj2.h:1863
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
void command_invoke(struct stasis_app_command *command, struct stasis_app_control *control, struct ast_channel *chan)
Definition: command.c:101
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
#define ast_assert(a)
Definition: utils.h:739

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, AO2_ITERATOR_UNLINK, ao2_ref, ast_assert, stasis_app_control::channel, command_invoke(), and stasis_app_control::command_queue.

Referenced by stasis_app_control_execute_until_exhausted(), and stasis_app_exec().

◆ control_flush_queue()

void control_flush_queue ( struct stasis_app_control control)

Flush the control command queue.

Since
13.9.0
Parameters
controlControl object to flush command queue.

Definition at line 1502 of file control.c.

1503{
1504 struct ao2_iterator iter;
1505 struct stasis_app_command *command;
1506
1508 while ((command = ao2_iterator_next(&iter))) {
1509 command_complete(command, -1);
1510 ao2_ref(command, -1);
1511 }
1512 ao2_iterator_destroy(&iter);
1513}
void command_complete(struct stasis_app_command *command, int retval)
Definition: command.c:77

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, AO2_ITERATOR_UNLINK, ao2_ref, command_complete(), and stasis_app_control::command_queue.

Referenced by stasis_app_control_flush_queue(), and stasis_app_exec().

◆ control_is_done()

int control_is_done ( struct stasis_app_control control)

Returns true if control_continue() has been called on this control.

Parameters
controlControl to query.
Return values
True(non-zero) if control_continue() has been called.
False(zero) otherwise.

Definition at line 368 of file control.c.

369{
370 /* Called from stasis_app_exec thread; no lock needed */
371 return control->is_done;
372}
unsigned int is_done
Definition: control.c:106

References stasis_app_control::is_done.

Referenced by stasis_app_control_execute_until_exhausted(), stasis_app_control_is_done(), and stasis_app_exec().

◆ control_mark_done()

void control_mark_done ( struct stasis_app_control control)

Definition at line 374 of file control.c.

375{
376 /* Locking necessary to sync with other threads adding commands to the queue. */
377 ao2_lock(control->command_queue);
378 control->is_done = 1;
379 ao2_unlock(control->command_queue);
380}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717

References ao2_lock, ao2_unlock, stasis_app_control::command_queue, and stasis_app_control::is_done.

Referenced by app_control_continue(), stasis_app_control_execute_until_exhausted(), and stasis_app_exec().

◆ control_move_cleanup()

void control_move_cleanup ( struct stasis_app_control control)

Free any memory that was allocated for switching applications via /channels/{channelId}/move.

Parameters
controlThe control for the channel

Definition at line 1722 of file control.c.

1723{
1724 ast_free(control->next_app);
1725 control->next_app = NULL;
1726
1728}
#define ast_free(a)
Definition: astmm.h:180
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:625

References ast_free, ast_free_ptr(), AST_VECTOR_RESET, stasis_app_control::next_app, stasis_app_control::next_app_args, and NULL.

Referenced by app_control_move(), control_dtor(), and stasis_app_exec().

◆ control_next_app()

char * control_next_app ( struct stasis_app_control control)

Returns the name of the application we are moving to.

Parameters
controlThe control for the channel
Returns
The name of the application we are moving to

Definition at line 1717 of file control.c.

1718{
1719 return control->next_app;
1720}

References stasis_app_control::next_app.

Referenced by stasis_app_exec().

◆ control_next_app_args()

char ** control_next_app_args ( struct stasis_app_control control)

Returns the list of arguments to pass to the application we are moving to.

Note
If you wish to get the size of the list, control_next_app_args_size should be called before this, as this function will steal the elements from the string vector and set the size to 0.
Parameters
controlThe control for the channel
Returns
The arguments to pass to the application we are moving to

Definition at line 1730 of file control.c.

1731{
1732 return AST_VECTOR_STEAL_ELEMENTS(&control->next_app_args);
1733}
#define AST_VECTOR_STEAL_ELEMENTS(vec)
Steal the elements from a vector and reinitialize.
Definition: vector.h:140

References AST_VECTOR_STEAL_ELEMENTS, and stasis_app_control::next_app_args.

Referenced by stasis_app_exec().

◆ control_next_app_args_size()

int control_next_app_args_size ( struct stasis_app_control control)

Returns the number of arguments to be passed to the application we are moving to.

Note
This should always be called before control_next_app_args, as calling that function will steal all elements from the string vector and set the size to 0.
Parameters
controlThe control for the channel
Returns
The number of arguments to be passed to the application we are moving to

Definition at line 1735 of file control.c.

1736{
1737 return AST_VECTOR_SIZE(&control->next_app_args);
1738}
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609

References AST_VECTOR_SIZE, and stasis_app_control::next_app_args.

Referenced by stasis_app_exec().

◆ control_prestart_dispatch_all()

int control_prestart_dispatch_all ( struct stasis_app_control control,
struct ast_channel chan 
)

Dispatch all queued prestart commands.

Parameters
controlThe control for chan
chanThe channel on which commands should be executed
Returns
The number of commands executed

Definition at line 1555 of file control.c.

1557{
1558 struct ao2_container *command_queue;
1559 int count = 0;
1560 struct ao2_iterator iter;
1561 struct stasis_app_command *command;
1562
1563 ast_channel_lock(chan);
1564 command_queue = command_prestart_get_container(chan);
1565 ast_channel_unlock(chan);
1566 if (!command_queue) {
1567 return 0;
1568 }
1569
1570 iter = ao2_iterator_init(command_queue, AO2_ITERATOR_UNLINK);
1571
1572 while ((command = ao2_iterator_next(&iter))) {
1573 command_invoke(command, control, chan);
1574 ao2_cleanup(command);
1575 ++count;
1576 }
1577
1578 ao2_iterator_destroy(&iter);
1579 ao2_cleanup(command_queue);
1580 return count;
1581}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unlock(chan)
Definition: channel.h:2923
struct ao2_container * command_prestart_get_container(struct ast_channel *chan)
Get the Stasis() prestart commands for a channel.
Definition: command.c:160
Generic container type.

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, AO2_ITERATOR_UNLINK, ast_channel_lock, ast_channel_unlock, command_invoke(), and command_prestart_get_container().

Referenced by stasis_app_exec().

◆ control_set_app()

void control_set_app ( struct stasis_app_control control,
struct stasis_app app 
)

Set the application the control object belongs to.

Parameters
controlThe control for the channel
appThe application this control will now belong to
Note
This will unref control's previous app by 1, and bump app by 1

Definition at line 1711 of file control.c.

1712{
1713 ao2_cleanup(control->app);
1714 control->app = ao2_bump(app);
1715}

References ao2_bump, ao2_cleanup, app, and stasis_app_control::app.

Referenced by stasis_app_exec().

◆ control_set_thread()

void control_set_thread ( struct stasis_app_control control,
pthread_t  threadid 
)

set the control's thread id

Since
18
Parameters
controlControl object on which to set the thread id.
threadidid to set

Definition at line 194 of file control.c.

195{
196 ao2_lock(control->command_queue);
197 control->control_thread = threadid;
198 ao2_unlock(control->command_queue);
199}
pthread_t control_thread
Definition: control.c:98

References ao2_lock, ao2_unlock, stasis_app_control::command_queue, and stasis_app_control::control_thread.

Referenced by control_create(), and stasis_app_exec().

◆ control_silence_stop_now()

void control_silence_stop_now ( struct stasis_app_control control)

Stop playing silence to a channel right now.

Since
13.9.0
Parameters
controlThe control for chan

Definition at line 857 of file control.c.

858{
859 if (control->silgen) {
860 ast_debug(3, "%s: Stopping silence generator\n",
863 control->channel, control->silgen);
864 control->silgen = NULL;
865 }
866}
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
Stops a previously-started silence generator on the given channel.
Definition: channel.c:8209
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1450
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_silence_generator * silgen
Definition: control.c:84

References ast_channel_stop_silence_generator(), ast_debug, stasis_app_control::channel, NULL, stasis_app_control::silgen, and stasis_app_control_get_channel_id().

Referenced by app_control_silence_stop(), and stasis_app_exec().

◆ control_swap_channel_in_bridge()

int control_swap_channel_in_bridge ( struct stasis_app_control control,
struct ast_bridge bridge,
struct ast_channel chan,
struct ast_channel swap 
)

Command for swapping a channel in a bridge.

Parameters
controlThe control for chan
chanThe channel on which commands should be executed
bridgeBridge to be passed to the callback
swapChannel to swap with when joining the bridge

Definition at line 1304 of file control.c.

1305{
1306 int res;
1307 struct ast_bridge_features *features;
1309
1310 if (!control || !bridge) {
1311 return -1;
1312 }
1313
1314 ast_debug(3, "%s: Adding to bridge %s\n",
1316 bridge->uniqueid);
1317
1318 ast_assert(chan != NULL);
1319
1320 /* Depart whatever Stasis bridge we're currently in. */
1321 if (stasis_app_get_bridge(control)) {
1322 /* Note that it looks like there's a race condition here, since
1323 * we don't have control locked. But this happens from the
1324 * control callback thread, so there won't be any other
1325 * concurrent attempts to bridge.
1326 */
1327 ast_bridge_depart(chan);
1328 }
1329
1330
1332 bridge_after_cb_failed, control);
1333 if (res != 0) {
1334 ast_log(LOG_ERROR, "Error setting after-bridge callback\n");
1335 return -1;
1336 }
1337
1338 ao2_lock(control);
1339
1340 /* Ensure the controlling application is subscribed early enough
1341 * to receive the ChannelEnteredBridge message. This works in concert
1342 * with the subscription handled in the Stasis application execution
1343 * loop */
1344 app_subscribe_bridge(control->app, bridge);
1345
1346 /* Save off the channel's PBX */
1347 ast_assert(control->pbx == NULL);
1348 if (!control->pbx) {
1349 control->pbx = ast_channel_pbx(chan);
1351 }
1352
1353 /* Pull bridge features from the control */
1354 features = control->bridge_features;
1355 control->bridge_features = NULL;
1356 if (features && features->inhibit_colp) {
1358 }
1359
1361 /* We need to set control->bridge here since bridge_after_cb may be run
1362 * before ast_bridge_impart returns. bridge_after_cb gets a reason
1363 * code so it can tell if the bridge is actually valid or not.
1364 */
1365 control->bridge = bridge;
1366
1367 /* We can't be holding the control lock while impart is running
1368 * or we could create a deadlock with bridge_after_cb which also
1369 * tries to lock control.
1370 */
1371 ao2_unlock(control);
1372 res = ast_bridge_impart(bridge,
1373 chan,
1374 swap,
1375 features, /* features */
1376 flags);
1377 if (res != 0) {
1378 /* ast_bridge_impart failed before it could spawn the depart
1379 * thread. The callbacks aren't called in this case.
1380 * The impart could still fail even if ast_bridge_impart returned
1381 * ok but that's handled by bridge_after_cb.
1382 */
1383 ast_log(LOG_ERROR, "Error adding channel to bridge\n");
1384 ao2_lock(control);
1385 ast_channel_pbx_set(chan, control->pbx);
1386 control->pbx = NULL;
1387 control->bridge = NULL;
1388 ao2_unlock(control);
1389 } else {
1390 ast_channel_lock(chan);
1391 set_interval_hook(chan);
1392 ast_channel_unlock(chan);
1393 }
1394
1395 return res;
1396}
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1906
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Definition: bridge.h:588
@ AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP
Definition: bridge.h:592
int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data)
Setup an after bridge callback for when the channel leaves the bridging system.
Definition: bridge_after.c:251
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
void ast_channel_pbx_set(struct ast_channel *chan, struct ast_pbx *value)
static void set_interval_hook(struct ast_channel *chan)
Set a dial timeout interval hook on the channel.
Definition: control.c:1274
static void bridge_after_cb(struct ast_channel *chan, void *data)
Definition: control.c:1183
static void bridge_after_cb_failed(enum ast_bridge_after_cb_reason reason, void *data)
Definition: control.c:1190
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:951
int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Add a bridge subscription to an existing channel subscription.
Structure that contains features information.
unsigned int inhibit_colp
const ast_string_field uniqueid
Definition: bridge.h:401
struct ast_bridge_features * bridge_features
Definition: control.c:68
struct ast_bridge * bridge
Definition: control.c:64
struct ast_pbx * pbx
Definition: control.c:72

References ao2_lock, ao2_unlock, stasis_app_control::app, app_subscribe_bridge(), ast_assert, ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP, ast_bridge_set_after_callback(), ast_channel_lock, ast_channel_pbx(), ast_channel_pbx_set(), ast_channel_unlock, ast_debug, ast_log, stasis_app_control::bridge, bridge_after_cb(), bridge_after_cb_failed(), stasis_app_control::bridge_features, ast_bridge_features::inhibit_colp, LOG_ERROR, NULL, stasis_app_control::pbx, set_interval_hook(), stasis_app_control_get_channel_id(), stasis_app_get_bridge(), and ast_bridge::uniqueid.

Referenced by control_add_channel_to_bridge(), and defer_bridge_add().

◆ control_wait()

void control_wait ( struct stasis_app_control control)

Blocks until control's command queue has a command available.

Parameters
controlControl to block on.

Definition at line 1535 of file control.c.

1536{
1537 if (!control) {
1538 return;
1539 }
1540
1541 ast_assert(control->command_queue != NULL);
1542
1543 ao2_lock(control->command_queue);
1544 while (ao2_container_count(control->command_queue) == 0) {
1545 int res = ast_cond_wait(&control->wait_cond,
1547 if (res < 0) {
1548 ast_log(LOG_ERROR, "Error waiting on command queue\n");
1549 break;
1550 }
1551 }
1552 ao2_unlock(control->command_queue);
1553}
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205

References ao2_container_count(), ao2_lock, ao2_object_get_lockaddr(), ao2_unlock, ast_assert, ast_cond_wait, ast_log, stasis_app_control::command_queue, LOG_ERROR, NULL, and stasis_app_control::wait_cond.

Referenced by stasis_app_exec().