mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 11:25:35 +00:00
Merge "res_stasis: Reduce RAII_VAR usage."
This commit is contained in:
191
res/stasis/app.c
191
res/stasis/app.c
@@ -112,20 +112,19 @@ static void forwards_unsubscribe(struct app_forwards *forwards)
|
||||
static struct app_forwards *forwards_create(struct stasis_app *app,
|
||||
const char *id)
|
||||
{
|
||||
RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
|
||||
struct app_forwards *forwards;
|
||||
|
||||
if (!app || ast_strlen_zero(id)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
forwards = ao2_alloc(sizeof(*forwards) + strlen(id) + 1, forwards_dtor);
|
||||
forwards = ao2_t_alloc(sizeof(*forwards) + strlen(id) + 1, forwards_dtor, id);
|
||||
if (!forwards) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(forwards->id, id);
|
||||
strcpy(forwards->id, id); /* SAFE */
|
||||
|
||||
ao2_ref(forwards, +1);
|
||||
return forwards;
|
||||
}
|
||||
|
||||
@@ -335,7 +334,7 @@ static void sub_default_handler(void *data, struct stasis_subscription *sub,
|
||||
struct stasis_message *message)
|
||||
{
|
||||
struct stasis_app *app = data;
|
||||
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
|
||||
struct ast_json *json;
|
||||
|
||||
if (stasis_subscription_final_message(sub, message)) {
|
||||
ao2_cleanup(app);
|
||||
@@ -352,6 +351,7 @@ static void sub_default_handler(void *data, struct stasis_subscription *sub,
|
||||
}
|
||||
|
||||
app_send(app, json);
|
||||
ast_json_unref(json);
|
||||
}
|
||||
|
||||
/*! \brief Typedef for callbacks that get called on channel snapshot updates */
|
||||
@@ -554,11 +554,12 @@ static void sub_channel_update_handler(void *data,
|
||||
stasis_message_timestamp(message);
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
|
||||
RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);
|
||||
struct ast_json *msg;
|
||||
|
||||
msg = channel_monitors[i](old_snapshot, new_snapshot, tv);
|
||||
if (msg) {
|
||||
app_send(app, msg);
|
||||
ast_json_unref(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +587,7 @@ static struct ast_json *simple_endpoint_event(
|
||||
|
||||
static int message_received_handler(const char *endpoint_id, struct ast_json *json_msg, void *pvt)
|
||||
{
|
||||
RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup);
|
||||
struct ast_endpoint_snapshot *snapshot;
|
||||
struct ast_json *json_endpoint;
|
||||
struct ast_json *message;
|
||||
struct stasis_app *app = pvt;
|
||||
@@ -610,6 +611,7 @@ static int message_received_handler(const char *endpoint_id, struct ast_json *js
|
||||
}
|
||||
|
||||
json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
|
||||
ao2_ref(snapshot, -1);
|
||||
if (!json_endpoint) {
|
||||
return -1;
|
||||
}
|
||||
@@ -631,7 +633,6 @@ static void sub_endpoint_update_handler(void *data,
|
||||
struct stasis_subscription *sub,
|
||||
struct stasis_message *message)
|
||||
{
|
||||
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
|
||||
struct stasis_app *app = data;
|
||||
struct stasis_cache_update *update;
|
||||
struct ast_endpoint_snapshot *new_snapshot;
|
||||
@@ -648,6 +649,8 @@ static void sub_endpoint_update_handler(void *data,
|
||||
old_snapshot = stasis_message_data(update->old_snapshot);
|
||||
|
||||
if (new_snapshot) {
|
||||
struct ast_json *json;
|
||||
|
||||
tv = stasis_message_timestamp(update->new_snapshot);
|
||||
|
||||
json = simple_endpoint_event("EndpointStateChange", new_snapshot, tv);
|
||||
@@ -656,6 +659,7 @@ static void sub_endpoint_update_handler(void *data,
|
||||
}
|
||||
|
||||
app_send(app, json);
|
||||
ast_json_unref(json);
|
||||
}
|
||||
|
||||
if (!new_snapshot && old_snapshot) {
|
||||
@@ -683,7 +687,7 @@ static void sub_bridge_update_handler(void *data,
|
||||
struct stasis_subscription *sub,
|
||||
struct stasis_message *message)
|
||||
{
|
||||
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
|
||||
struct ast_json *json = NULL;
|
||||
struct stasis_app *app = data;
|
||||
struct stasis_cache_update *update;
|
||||
struct ast_bridge_snapshot *new_snapshot;
|
||||
@@ -717,6 +721,7 @@ static void sub_bridge_update_handler(void *data,
|
||||
|
||||
if (json) {
|
||||
app_send(app, json);
|
||||
ast_json_unref(json);
|
||||
}
|
||||
|
||||
if (!new_snapshot && old_snapshot) {
|
||||
@@ -1019,7 +1024,7 @@ void app_send(struct stasis_app *app, struct ast_json *message)
|
||||
{
|
||||
stasis_app_cb handler;
|
||||
char eid[20];
|
||||
RAII_VAR(void *, data, NULL, ao2_cleanup);
|
||||
void *data;
|
||||
|
||||
if (ast_json_object_set(message, "asterisk_id", ast_json_string_create(
|
||||
ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) {
|
||||
@@ -1028,37 +1033,36 @@ void app_send(struct stasis_app *app, struct ast_json *message)
|
||||
}
|
||||
|
||||
/* Copy off mutable state with lock held */
|
||||
{
|
||||
SCOPED_AO2LOCK(lock, app);
|
||||
handler = app->handler;
|
||||
if (app->data) {
|
||||
ao2_ref(app->data, +1);
|
||||
data = app->data;
|
||||
}
|
||||
/* Name is immutable; no need to copy */
|
||||
}
|
||||
ao2_lock(app);
|
||||
handler = app->handler;
|
||||
data = ao2_bump(app->data);
|
||||
ao2_unlock(app);
|
||||
/* Name is immutable; no need to copy */
|
||||
|
||||
if (!handler) {
|
||||
if (handler) {
|
||||
handler(data, app->name, message);
|
||||
} else {
|
||||
ast_verb(3,
|
||||
"Inactive Stasis app '%s' missed message\n", app->name);
|
||||
return;
|
||||
}
|
||||
|
||||
handler(data, app->name, message);
|
||||
ao2_cleanup(data);
|
||||
}
|
||||
|
||||
void app_deactivate(struct stasis_app *app)
|
||||
{
|
||||
SCOPED_AO2LOCK(lock, app);
|
||||
ao2_lock(app);
|
||||
|
||||
ast_verb(1, "Deactivating Stasis app '%s'\n", app->name);
|
||||
app->handler = NULL;
|
||||
ao2_cleanup(app->data);
|
||||
app->data = NULL;
|
||||
|
||||
ao2_unlock(app);
|
||||
}
|
||||
|
||||
void app_shutdown(struct stasis_app *app)
|
||||
{
|
||||
SCOPED_AO2LOCK(lock, app);
|
||||
ao2_lock(app);
|
||||
|
||||
ast_assert(app_is_finished(app));
|
||||
|
||||
@@ -1068,27 +1072,37 @@ void app_shutdown(struct stasis_app *app)
|
||||
app->bridge_router = NULL;
|
||||
stasis_message_router_unsubscribe(app->endpoint_router);
|
||||
app->endpoint_router = NULL;
|
||||
|
||||
ao2_unlock(app);
|
||||
}
|
||||
|
||||
int app_is_active(struct stasis_app *app)
|
||||
{
|
||||
SCOPED_AO2LOCK(lock, app);
|
||||
return app->handler != NULL;
|
||||
int ret;
|
||||
|
||||
ao2_lock(app);
|
||||
ret = app->handler != NULL;
|
||||
ao2_unlock(app);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int app_is_finished(struct stasis_app *app)
|
||||
{
|
||||
SCOPED_AO2LOCK(lock, app);
|
||||
int ret;
|
||||
|
||||
return app->handler == NULL && ao2_container_count(app->forwards) == 0;
|
||||
ao2_lock(app);
|
||||
ret = app->handler == NULL && ao2_container_count(app->forwards) == 0;
|
||||
ao2_unlock(app);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void app_update(struct stasis_app *app, stasis_app_cb handler, void *data)
|
||||
{
|
||||
SCOPED_AO2LOCK(lock, app);
|
||||
|
||||
ao2_lock(app);
|
||||
if (app->handler && app->data) {
|
||||
RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);
|
||||
struct ast_json *msg;
|
||||
|
||||
ast_verb(1, "Replacing Stasis app '%s'\n", app->name);
|
||||
|
||||
@@ -1097,17 +1111,15 @@ void app_update(struct stasis_app *app, stasis_app_cb handler, void *data)
|
||||
"application", app->name);
|
||||
if (msg) {
|
||||
app_send(app, msg);
|
||||
ast_json_unref(msg);
|
||||
}
|
||||
} else {
|
||||
ast_verb(1, "Activating Stasis app '%s'\n", app->name);
|
||||
}
|
||||
|
||||
app->handler = handler;
|
||||
ao2_cleanup(app->data);
|
||||
if (data) {
|
||||
ao2_ref(data, +1);
|
||||
}
|
||||
app->data = data;
|
||||
ao2_replace(app->data, data);
|
||||
ao2_unlock(app);
|
||||
}
|
||||
|
||||
const char *stasis_app_name(const struct stasis_app *app)
|
||||
@@ -1184,68 +1196,72 @@ void stasis_app_to_cli(const struct stasis_app *app, struct ast_cli_args *a)
|
||||
|
||||
struct ast_json *app_to_json(const struct stasis_app *app)
|
||||
{
|
||||
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
|
||||
struct ast_json *json;
|
||||
struct ast_json *channels;
|
||||
struct ast_json *bridges;
|
||||
struct ast_json *endpoints;
|
||||
struct ao2_iterator i;
|
||||
void *obj;
|
||||
struct app_forwards *forwards;
|
||||
|
||||
json = ast_json_pack("{s: s, s: [], s: [], s: []}",
|
||||
"name", app->name,
|
||||
"channel_ids", "bridge_ids", "endpoint_ids");
|
||||
if (!json) {
|
||||
return NULL;
|
||||
}
|
||||
channels = ast_json_object_get(json, "channel_ids");
|
||||
bridges = ast_json_object_get(json, "bridge_ids");
|
||||
endpoints = ast_json_object_get(json, "endpoint_ids");
|
||||
|
||||
i = ao2_iterator_init(app->forwards, 0);
|
||||
while ((obj = ao2_iterator_next(&i))) {
|
||||
RAII_VAR(struct app_forwards *, forwards, obj, ao2_cleanup);
|
||||
RAII_VAR(struct ast_json *, id, NULL, ast_json_unref);
|
||||
int append_res = -1;
|
||||
|
||||
id = ast_json_string_create(forwards->id);
|
||||
while ((forwards = ao2_iterator_next(&i))) {
|
||||
struct ast_json *array = NULL;
|
||||
int append_res;
|
||||
|
||||
switch (forwards->forward_type) {
|
||||
case FORWARD_CHANNEL:
|
||||
append_res = ast_json_array_append(channels,
|
||||
ast_json_ref(id));
|
||||
array = channels;
|
||||
break;
|
||||
case FORWARD_BRIDGE:
|
||||
append_res = ast_json_array_append(bridges,
|
||||
ast_json_ref(id));
|
||||
array = bridges;
|
||||
break;
|
||||
case FORWARD_ENDPOINT:
|
||||
append_res = ast_json_array_append(endpoints,
|
||||
ast_json_ref(id));
|
||||
array = endpoints;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If forward_type value is unexpected this will safely return an error. */
|
||||
append_res = ast_json_array_append(array, ast_json_string_create(forwards->id));
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
if (append_res != 0) {
|
||||
ast_log(LOG_ERROR, "Error building response\n");
|
||||
ao2_iterator_destroy(&i);
|
||||
ast_json_unref(json);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ao2_iterator_destroy(&i);
|
||||
|
||||
return ast_json_ref(json);
|
||||
return json;
|
||||
}
|
||||
|
||||
int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
|
||||
{
|
||||
struct app_forwards *forwards;
|
||||
SCOPED_AO2LOCK(lock, app->forwards);
|
||||
int res;
|
||||
|
||||
if (!app) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ao2_lock(app->forwards);
|
||||
/* If subscribed to all, don't subscribe again */
|
||||
forwards = ao2_find(app->forwards, CHANNEL_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
||||
if (forwards) {
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1253,16 +1269,21 @@ int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
|
||||
chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL,
|
||||
OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
||||
if (!forwards) {
|
||||
int res;
|
||||
|
||||
/* Forwards not found, create one */
|
||||
forwards = forwards_create_channel(app, chan);
|
||||
if (!forwards) {
|
||||
ao2_unlock(app->forwards);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = ao2_link_flags(app->forwards, forwards,
|
||||
OBJ_NOLOCK);
|
||||
res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
|
||||
if (!res) {
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1273,7 +1294,9 @@ int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
|
||||
forwards->interested,
|
||||
app->name);
|
||||
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1284,8 +1307,7 @@ static int subscribe_channel(struct stasis_app *app, void *obj)
|
||||
|
||||
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)
|
||||
{
|
||||
RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
|
||||
SCOPED_AO2LOCK(lock, app->forwards);
|
||||
struct app_forwards *forwards;
|
||||
|
||||
if (!id) {
|
||||
if (!strcmp(kind, "bridge")) {
|
||||
@@ -1300,8 +1322,10 @@ static int unsubscribe(struct stasis_app *app, const char *kind, const char *id,
|
||||
}
|
||||
}
|
||||
|
||||
ao2_lock(app->forwards);
|
||||
forwards = ao2_find(app->forwards, id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
||||
if (!forwards) {
|
||||
ao2_unlock(app->forwards);
|
||||
ast_debug(3, "App '%s' not subscribed to %s '%s'\n", app->name, kind, id);
|
||||
return -1;
|
||||
}
|
||||
@@ -1320,6 +1344,8 @@ static int unsubscribe(struct stasis_app *app, const char *kind, const char *id,
|
||||
messaging_app_unsubscribe_endpoint(app->name, id);
|
||||
}
|
||||
}
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1344,12 +1370,14 @@ int app_unsubscribe_channel_id(struct stasis_app *app, const char *channel_id)
|
||||
|
||||
int app_is_subscribed_channel_id(struct stasis_app *app, const char *channel_id)
|
||||
{
|
||||
RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
|
||||
struct app_forwards *forwards;
|
||||
|
||||
if (ast_strlen_zero(channel_id)) {
|
||||
channel_id = CHANNEL_ALL;
|
||||
}
|
||||
forwards = ao2_find(app->forwards, channel_id, OBJ_SEARCH_KEY);
|
||||
ao2_cleanup(forwards);
|
||||
|
||||
return forwards != NULL;
|
||||
}
|
||||
|
||||
@@ -1369,28 +1397,42 @@ struct stasis_app_event_source channel_event_source = {
|
||||
int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
|
||||
{
|
||||
struct app_forwards *forwards;
|
||||
SCOPED_AO2LOCK(lock, app->forwards);
|
||||
|
||||
if (!app) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ao2_lock(app->forwards);
|
||||
/* If subscribed to all, don't subscribe again */
|
||||
forwards = ao2_find(app->forwards, BRIDGE_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
||||
if (forwards) {
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
forwards = ao2_find(app->forwards, bridge ? bridge->uniqueid : BRIDGE_ALL,
|
||||
forwards = ao2_find(app->forwards,
|
||||
bridge ? bridge->uniqueid : BRIDGE_ALL,
|
||||
OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
||||
if (!forwards) {
|
||||
int res;
|
||||
|
||||
/* Forwards not found, create one */
|
||||
forwards = forwards_create_bridge(app, bridge);
|
||||
if (!forwards) {
|
||||
ao2_unlock(app->forwards);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
|
||||
if (!res) {
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
|
||||
}
|
||||
|
||||
++forwards->interested;
|
||||
@@ -1399,7 +1441,9 @@ int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
|
||||
forwards->interested,
|
||||
app->name);
|
||||
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1456,16 +1500,18 @@ struct stasis_app_event_source bridge_event_source = {
|
||||
int app_subscribe_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)
|
||||
{
|
||||
struct app_forwards *forwards;
|
||||
SCOPED_AO2LOCK(lock, app->forwards);
|
||||
|
||||
if (!app) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ao2_lock(app->forwards);
|
||||
/* If subscribed to all, don't subscribe again */
|
||||
forwards = ao2_find(app->forwards, ENDPOINT_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
||||
if (forwards) {
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1473,12 +1519,23 @@ int app_subscribe_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint
|
||||
endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL,
|
||||
OBJ_SEARCH_KEY | OBJ_NOLOCK);
|
||||
if (!forwards) {
|
||||
int res;
|
||||
|
||||
/* Forwards not found, create one */
|
||||
forwards = forwards_create_endpoint(app, endpoint);
|
||||
if (!forwards) {
|
||||
ao2_unlock(app->forwards);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
|
||||
if (!res) {
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
|
||||
|
||||
/* Subscribe for messages */
|
||||
messaging_app_subscribe_endpoint(app->name, endpoint, &message_received_handler, app);
|
||||
@@ -1490,7 +1547,9 @@ int app_subscribe_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint
|
||||
forwards->interested,
|
||||
app->name);
|
||||
|
||||
ao2_unlock(app->forwards);
|
||||
ao2_ref(forwards, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1510,12 +1569,14 @@ int app_unsubscribe_endpoint_id(struct stasis_app *app, const char *endpoint_id)
|
||||
|
||||
int app_is_subscribed_endpoint_id(struct stasis_app *app, const char *endpoint_id)
|
||||
{
|
||||
RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
|
||||
struct app_forwards *forwards;
|
||||
|
||||
if (ast_strlen_zero(endpoint_id)) {
|
||||
endpoint_id = ENDPOINT_ALL;
|
||||
}
|
||||
forwards = ao2_find(app->forwards, endpoint_id, OBJ_SEARCH_KEY);
|
||||
ao2_cleanup(forwards);
|
||||
|
||||
return forwards != NULL;
|
||||
}
|
||||
|
||||
|
@@ -76,21 +76,26 @@ struct stasis_app_command *command_create(
|
||||
|
||||
void command_complete(struct stasis_app_command *command, int retval)
|
||||
{
|
||||
SCOPED_MUTEX(lock, &command->lock);
|
||||
|
||||
ast_mutex_lock(&command->lock);
|
||||
command->is_done = 1;
|
||||
command->retval = retval;
|
||||
ast_cond_signal(&command->condition);
|
||||
ast_mutex_unlock(&command->lock);
|
||||
}
|
||||
|
||||
int command_join(struct stasis_app_command *command)
|
||||
{
|
||||
SCOPED_MUTEX(lock, &command->lock);
|
||||
int ret;
|
||||
|
||||
ast_mutex_lock(&command->lock);
|
||||
while (!command->is_done) {
|
||||
ast_cond_wait(&command->condition, &command->lock);
|
||||
}
|
||||
|
||||
return command->retval;
|
||||
ret = command->retval;
|
||||
ast_mutex_unlock(&command->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void command_invoke(struct stasis_app_command *command,
|
||||
|
@@ -148,8 +148,9 @@ static void app_control_register_rule(
|
||||
struct stasis_app_control *control,
|
||||
struct app_control_rules *list, struct stasis_app_control_rule *obj)
|
||||
{
|
||||
SCOPED_AO2LOCK(lock, control->command_queue);
|
||||
ao2_lock(control->command_queue);
|
||||
AST_LIST_INSERT_TAIL(list, obj, next);
|
||||
ao2_unlock(control->command_queue);
|
||||
}
|
||||
|
||||
static void app_control_unregister_rule(
|
||||
@@ -157,7 +158,8 @@ static void app_control_unregister_rule(
|
||||
struct app_control_rules *list, struct stasis_app_control_rule *obj)
|
||||
{
|
||||
struct stasis_app_control_rule *rule;
|
||||
SCOPED_AO2LOCK(lock, control->command_queue);
|
||||
|
||||
ao2_lock(control->command_queue);
|
||||
AST_RWLIST_TRAVERSE_SAFE_BEGIN(list, rule, next) {
|
||||
if (rule == obj) {
|
||||
AST_RWLIST_REMOVE_CURRENT(next);
|
||||
@@ -165,6 +167,7 @@ static void app_control_unregister_rule(
|
||||
}
|
||||
}
|
||||
AST_RWLIST_TRAVERSE_SAFE_END;
|
||||
ao2_unlock(control->command_queue);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -508,9 +511,10 @@ static int app_control_mute(struct stasis_app_control *control,
|
||||
struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct stasis_app_control_mute_data *mute_data = data;
|
||||
SCOPED_CHANNELLOCK(lockvar, chan);
|
||||
|
||||
ast_channel_lock(chan);
|
||||
ast_channel_suppress(control->channel, mute_data->direction, mute_data->frametype);
|
||||
ast_channel_unlock(chan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -535,9 +539,10 @@ static int app_control_unmute(struct stasis_app_control *control,
|
||||
struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct stasis_app_control_mute_data *mute_data = data;
|
||||
SCOPED_CHANNELLOCK(lockvar, chan);
|
||||
|
||||
ast_channel_lock(chan);
|
||||
ast_channel_unsuppress(control->channel, mute_data->direction, mute_data->frametype);
|
||||
ast_channel_unlock(chan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -746,7 +751,7 @@ void stasis_app_control_silence_stop(struct stasis_app_control *control)
|
||||
struct ast_channel_snapshot *stasis_app_control_get_snapshot(
|
||||
const struct stasis_app_control *control)
|
||||
{
|
||||
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
||||
struct stasis_message *msg;
|
||||
struct ast_channel_snapshot *snapshot;
|
||||
|
||||
msg = stasis_cache_get(ast_channel_cache(), ast_channel_snapshot_type(),
|
||||
@@ -759,6 +764,8 @@ struct ast_channel_snapshot *stasis_app_control_get_snapshot(
|
||||
ast_assert(snapshot != NULL);
|
||||
|
||||
ao2_ref(snapshot, +1);
|
||||
ao2_ref(msg, -1);
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
@@ -767,7 +774,8 @@ static int app_send_command_on_condition(struct stasis_app_control *control,
|
||||
command_data_destructor_fn data_destructor,
|
||||
app_command_can_exec_cb can_exec_fn)
|
||||
{
|
||||
RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
|
||||
int ret;
|
||||
struct stasis_app_command *command;
|
||||
|
||||
if (control == NULL || control->is_done) {
|
||||
/* If exec_command_on_condition fails, it calls the data_destructor.
|
||||
@@ -787,7 +795,10 @@ static int app_send_command_on_condition(struct stasis_app_control *control,
|
||||
return -1;
|
||||
}
|
||||
|
||||
return command_join(command);
|
||||
ret = command_join(command);
|
||||
ao2_ref(command, -1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int stasis_app_send_command(struct stasis_app_control *control,
|
||||
@@ -800,7 +811,7 @@ int stasis_app_send_command_async(struct stasis_app_control *control,
|
||||
stasis_app_command_cb command_fn, void *data,
|
||||
command_data_destructor_fn data_destructor)
|
||||
{
|
||||
RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
|
||||
struct stasis_app_command *command;
|
||||
|
||||
if (control == NULL || control->is_done) {
|
||||
/* If exec_command fails, it calls the data_destructor. In order to
|
||||
@@ -818,18 +829,24 @@ int stasis_app_send_command_async(struct stasis_app_control *control,
|
||||
if (!command) {
|
||||
return -1;
|
||||
}
|
||||
ao2_ref(command, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control)
|
||||
{
|
||||
struct ast_bridge *ret;
|
||||
|
||||
if (!control) {
|
||||
return NULL;
|
||||
} else {
|
||||
SCOPED_AO2LOCK(lock, control);
|
||||
return control->bridge;
|
||||
}
|
||||
|
||||
ao2_lock(control);
|
||||
ret = control->bridge;
|
||||
ao2_unlock(control);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -970,16 +987,16 @@ static int depart_channel(struct stasis_app_control *control, struct ast_channel
|
||||
static int bridge_channel_depart(struct stasis_app_control *control,
|
||||
struct ast_channel *chan, void *data)
|
||||
{
|
||||
struct ast_bridge_channel *bridge_channel = data;
|
||||
struct ast_bridge_channel *bridge_channel;
|
||||
|
||||
{
|
||||
SCOPED_CHANNELLOCK(lock, chan);
|
||||
ast_channel_lock(chan);
|
||||
bridge_channel = ast_channel_internal_bridge_channel(chan);
|
||||
ast_channel_unlock(chan);
|
||||
|
||||
if (bridge_channel != ast_channel_internal_bridge_channel(chan)) {
|
||||
ast_debug(3, "%s: Channel is no longer in departable state\n",
|
||||
ast_channel_uniqueid(chan));
|
||||
return -1;
|
||||
}
|
||||
if (bridge_channel != data) {
|
||||
ast_debug(3, "%s: Channel is no longer in departable state\n",
|
||||
ast_channel_uniqueid(chan));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ast_debug(3, "%s: Channel departing bridge\n",
|
||||
@@ -994,9 +1011,9 @@ static void internal_bridge_after_cb(struct ast_channel *chan, void *data,
|
||||
enum ast_bridge_after_cb_reason reason)
|
||||
{
|
||||
struct stasis_app_control *control = data;
|
||||
SCOPED_AO2LOCK(lock, control);
|
||||
struct ast_bridge_channel *bridge_channel;
|
||||
|
||||
ao2_lock(control);
|
||||
ast_debug(3, "%s, %s: %s\n",
|
||||
ast_channel_uniqueid(chan), control->bridge ? control->bridge->uniqueid : "unknown",
|
||||
ast_bridge_after_cb_reason_string(reason));
|
||||
@@ -1042,6 +1059,7 @@ static void internal_bridge_after_cb(struct ast_channel *chan, void *data,
|
||||
ast_softhangup_nolock(chan, hangup_flag);
|
||||
ast_channel_unlock(chan);
|
||||
}
|
||||
ao2_unlock(control);
|
||||
}
|
||||
|
||||
static void bridge_after_cb(struct ast_channel *chan, void *data)
|
||||
|
@@ -250,7 +250,7 @@ static int bridge_stasis_moving(struct ast_bridge_channel *bridge_channel, void
|
||||
{
|
||||
if (src->v_table == &bridge_stasis_v_table &&
|
||||
dst->v_table != &bridge_stasis_v_table) {
|
||||
RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
|
||||
struct stasis_app_control *control;
|
||||
struct ast_channel *chan;
|
||||
|
||||
chan = bridge_channel->chan;
|
||||
@@ -263,6 +263,7 @@ static int bridge_stasis_moving(struct ast_bridge_channel *bridge_channel, void
|
||||
|
||||
stasis_app_channel_set_stasis_end_published(chan);
|
||||
app_send_end_msg(control_app(control), chan);
|
||||
ao2_ref(control, -1);
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
Reference in New Issue
Block a user