summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/res_stasis_device_state.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/res/res_stasis_device_state.c b/res/res_stasis_device_state.c
index 8b5375910..e16bd8edd 100644
--- a/res/res_stasis_device_state.c
+++ b/res/res_stasis_device_state.c
@@ -146,13 +146,13 @@ static struct device_state_subscription *find_device_state_subscription(
.device_name = name
};
- return ao2_find(device_state_subscriptions, &dummy_sub, OBJ_SEARCH_OBJECT);
+ return ao2_find(device_state_subscriptions, &dummy_sub, OBJ_SEARCH_OBJECT | OBJ_NOLOCK);
}
static void remove_device_state_subscription(
struct device_state_subscription *sub)
{
- ao2_unlink(device_state_subscriptions, sub);
+ ao2_unlink_flags(device_state_subscriptions, sub, OBJ_NOLOCK);
}
struct ast_json *stasis_app_device_state_to_json(
@@ -344,6 +344,17 @@ static int is_subscribed_device_state(struct stasis_app *app, const char *name)
return 0;
}
+static int is_subscribed_device_state_lock(struct stasis_app *app, const char *name)
+{
+ int is_subscribed;
+
+ ao2_lock(device_state_subscriptions);
+ is_subscribed = is_subscribed_device_state(app, name);
+ ao2_unlock(device_state_subscriptions);
+
+ return is_subscribed;
+}
+
static int subscribe_device_state(struct stasis_app *app, void *obj)
{
struct device_state_subscription *sub = obj;
@@ -362,7 +373,10 @@ static int subscribe_device_state(struct stasis_app *app, void *obj)
topic = ast_device_state_topic_all();
}
+ ao2_lock(device_state_subscriptions);
+
if (is_subscribed_device_state(app, sub->device_name)) {
+ ao2_unlock(device_state_subscriptions);
ast_debug(3, "App %s is already subscribed to %s\n", stasis_app_name(app), sub->device_name);
return 0;
}
@@ -371,6 +385,7 @@ static int subscribe_device_state(struct stasis_app *app, void *obj)
sub->sub = stasis_subscribe_pool(topic, device_state_cb, ao2_bump(sub));
if (!sub->sub) {
+ ao2_unlock(device_state_subscriptions);
ast_log(LOG_ERROR, "Unable to subscribe to device %s\n",
sub->device_name);
/* Reference we added when attempting to stasis_subscribe_pool */
@@ -378,15 +393,25 @@ static int subscribe_device_state(struct stasis_app *app, void *obj)
return -1;
}
- ao2_link(device_state_subscriptions, sub);
+ ao2_link_flags(device_state_subscriptions, sub, OBJ_NOLOCK);
+ ao2_unlock(device_state_subscriptions);
+
return 0;
}
static int unsubscribe_device_state(struct stasis_app *app, const char *name)
{
- RAII_VAR(struct device_state_subscription *, sub,
- find_device_state_subscription(app, name), ao2_cleanup);
- remove_device_state_subscription(sub);
+ struct device_state_subscription *sub;
+
+ ao2_lock(device_state_subscriptions);
+ sub = find_device_state_subscription(app, name);
+ if (sub) {
+ remove_device_state_subscription(sub);
+ }
+ ao2_unlock(device_state_subscriptions);
+
+ ao2_cleanup(sub);
+
return 0;
}
@@ -419,7 +444,7 @@ struct stasis_app_event_source device_state_event_source = {
.find = find_device_state,
.subscribe = subscribe_device_state,
.unsubscribe = unsubscribe_device_state,
- .is_subscribed = is_subscribed_device_state,
+ .is_subscribed = is_subscribed_device_state_lock,
.to_json = devices_to_json
};