diff options
author | Kinsey Moore <kmoore@digium.com> | 2013-04-16 15:48:16 +0000 |
---|---|---|
committer | Kinsey Moore <kmoore@digium.com> | 2013-04-16 15:48:16 +0000 |
commit | 71a01725b850505a26d800288dc00e376e885dc1 (patch) | |
tree | 3a5d625f8fe0aeac4429834f74faaa7616e90d8e /main/pbx.c | |
parent | 191cf99ae1f821dec98199931fc775fc0716d27c (diff) |
Move presence state distribution to Stasis-core
Convert presence state events to Stasis-core messages and remove
redundant serializers where possible.
Review: https://reviewboard.asterisk.org/r/2410/
(closes issue ASTERISK-21102)
Patch-by: Kinsey Moore <kmoore@digium.com>
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@385862 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/pbx.c')
-rw-r--r-- | main/pbx.c | 266 |
1 files changed, 97 insertions, 169 deletions
diff --git a/main/pbx.c b/main/pbx.c index 017896979..43805ce7c 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -819,8 +819,6 @@ AST_APP_OPTIONS(waitexten_opts, { struct ast_context; struct ast_app; -static struct ast_taskprocessor *extension_state_tps; - AST_THREADSTORAGE(switch_data); AST_THREADSTORAGE(extensionstate_buf); @@ -1123,13 +1121,6 @@ static const struct cfextension_states { { AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD, "InUse&Hold" } }; -struct presencechange { - char *provider; - int state; - char *subtype; - char *message; -}; - struct pbx_exception { AST_DECLARE_STRING_FIELDS( AST_STRING_FIELD(context); /*!< Context associated with this exception */ @@ -1297,7 +1288,7 @@ static char *overrideswitch = NULL; /*! \brief Subscription for device state change events */ static struct stasis_subscription *device_state_sub; /*! \brief Subscription for presence state change events */ -static struct ast_event_sub *presence_state_sub; +static struct stasis_subscription *presence_state_sub; AST_MUTEX_DEFINE_STATIC(maxcalllock); static int countcalls; @@ -5042,125 +5033,6 @@ static int execute_state_callback(ast_state_cb_type cb, return res; } -static int handle_presencechange(void *datap) -{ - struct ast_hint *hint; - struct ast_str *hint_app = NULL; - struct presencechange *pc = datap; - struct ao2_iterator i; - struct ao2_iterator cb_iter; - char context_name[AST_MAX_CONTEXT]; - char exten_name[AST_MAX_EXTENSION]; - int res = -1; - - hint_app = ast_str_create(1024); - if (!hint_app) { - goto presencechange_cleanup; - } - - ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */ - i = ao2_iterator_init(hints, 0); - for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) { - struct ast_state_cb *state_cb; - const char *app; - char *parse; - - ao2_lock(hint); - - if (!hint->exten) { - /* The extension has already been destroyed */ - ao2_unlock(hint); - continue; - } - - /* Does this hint monitor the device that changed state? */ - app = ast_get_extension_app(hint->exten); - if (ast_strlen_zero(app)) { - /* The hint does not monitor presence at all. */ - ao2_unlock(hint); - continue; - } - - ast_str_set(&hint_app, 0, "%s", app); - parse = parse_hint_presence(hint_app); - if (ast_strlen_zero(parse)) { - ao2_unlock(hint); - continue; - } - if (strcasecmp(parse, pc->provider)) { - /* The hint does not monitor the presence provider. */ - ao2_unlock(hint); - continue; - } - - /* - * Save off strings in case the hint extension gets destroyed - * while we are notifying the watchers. - */ - ast_copy_string(context_name, - ast_get_context_name(ast_get_extension_context(hint->exten)), - sizeof(context_name)); - ast_copy_string(exten_name, ast_get_extension_name(hint->exten), - sizeof(exten_name)); - ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(hint->exten)); - - /* Check to see if update is necessary */ - if ((hint->last_presence_state == pc->state) && - ((hint->last_presence_subtype && pc->subtype && !strcmp(hint->last_presence_subtype, pc->subtype)) || (!hint->last_presence_subtype && !pc->subtype)) && - ((hint->last_presence_message && pc->message && !strcmp(hint->last_presence_message, pc->message)) || (!hint->last_presence_message && !pc->message))) { - - /* this update is the same as the last, do nothing */ - ao2_unlock(hint); - continue; - } - - /* update new values */ - ast_free(hint->last_presence_subtype); - ast_free(hint->last_presence_message); - hint->last_presence_state = pc->state; - hint->last_presence_subtype = pc->subtype ? ast_strdup(pc->subtype) : NULL; - hint->last_presence_message = pc->message ? ast_strdup(pc->message) : NULL; - - ao2_unlock(hint); - - /* For general callbacks */ - cb_iter = ao2_iterator_init(statecbs, 0); - for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) { - execute_state_callback(state_cb->change_cb, - context_name, - exten_name, - state_cb->data, - AST_HINT_UPDATE_PRESENCE, - hint, - NULL); - } - ao2_iterator_destroy(&cb_iter); - - /* For extension callbacks */ - cb_iter = ao2_iterator_init(hint->callbacks, 0); - for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) { - execute_state_callback(state_cb->change_cb, - context_name, - exten_name, - state_cb->data, - AST_HINT_UPDATE_PRESENCE, - hint, - NULL); - } - ao2_iterator_destroy(&cb_iter); - } - ao2_iterator_destroy(&i); - ast_mutex_unlock(&context_merge_lock); - - res = 0; - -presencechange_cleanup: - ast_free(hint_app); - ao2_ref(pc, -1); - - return res; -} - /*! * /internal * /brief Identify a channel for every device which is supposedly responsible for the device state. @@ -11663,49 +11535,112 @@ static int pbx_builtin_sayphonetic(struct ast_channel *chan, const char *data) return res; } -static void presencechange_destroy(void *data) -{ - struct presencechange *pc = data; - ast_free(pc->provider); - ast_free(pc->subtype); - ast_free(pc->message); -} - -static void presence_state_cb(const struct ast_event *event, void *unused) +static void presence_state_cb(void *unused, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *msg) { - struct presencechange *pc; - const char *tmp; + struct ast_presence_state_message *presence_state = stasis_message_data(msg); + struct ast_hint *hint; + struct ast_str *hint_app = NULL; + struct ao2_iterator hint_iter; + struct ao2_iterator cb_iter; + char context_name[AST_MAX_CONTEXT]; + char exten_name[AST_MAX_EXTENSION]; - if (!(pc = ao2_alloc(sizeof(*pc), presencechange_destroy))) { + if (stasis_message_type(msg) != ast_presence_state_message_type()) { return; } - tmp = ast_event_get_ie_str(event, AST_EVENT_IE_PRESENCE_PROVIDER); - if (ast_strlen_zero(tmp)) { - ast_log(LOG_ERROR, "Received invalid event that had no presence provider IE\n"); - ao2_ref(pc, -1); + hint_app = ast_str_create(1024); + if (!hint_app) { return; } - pc->provider = ast_strdup(tmp); - pc->state = ast_event_get_ie_uint(event, AST_EVENT_IE_PRESENCE_STATE); - if (pc->state < 0) { - ao2_ref(pc, -1); - return; - } + ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */ + hint_iter = ao2_iterator_init(hints, 0); + for (; (hint = ao2_iterator_next(&hint_iter)); ao2_cleanup(hint)) { + struct ast_state_cb *state_cb; + const char *app; + char *parse; + SCOPED_AO2LOCK(lock, hint); - if ((tmp = ast_event_get_ie_str(event, AST_EVENT_IE_PRESENCE_SUBTYPE))) { - pc->subtype = ast_strdup(tmp); - } + if (!hint->exten) { + /* The extension has already been destroyed */ + continue; + } - if ((tmp = ast_event_get_ie_str(event, AST_EVENT_IE_PRESENCE_MESSAGE))) { - pc->message = ast_strdup(tmp); - } + /* Does this hint monitor the device that changed state? */ + app = ast_get_extension_app(hint->exten); + if (ast_strlen_zero(app)) { + /* The hint does not monitor presence at all. */ + continue; + } + + ast_str_set(&hint_app, 0, "%s", app); + parse = parse_hint_presence(hint_app); + if (ast_strlen_zero(parse)) { + continue; + } + if (strcasecmp(parse, presence_state->provider)) { + /* The hint does not monitor the presence provider. */ + continue; + } + + /* + * Save off strings in case the hint extension gets destroyed + * while we are notifying the watchers. + */ + ast_copy_string(context_name, + ast_get_context_name(ast_get_extension_context(hint->exten)), + sizeof(context_name)); + ast_copy_string(exten_name, ast_get_extension_name(hint->exten), + sizeof(exten_name)); + ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(hint->exten)); - /* The task processor thread is taking our reference to the presencechange object. */ - if (ast_taskprocessor_push(extension_state_tps, handle_presencechange, pc) < 0) { - ao2_ref(pc, -1); + /* Check to see if update is necessary */ + if ((hint->last_presence_state == presence_state->state) && + ((hint->last_presence_subtype && presence_state->subtype && !strcmp(hint->last_presence_subtype, presence_state->subtype)) || (!hint->last_presence_subtype && !presence_state->subtype)) && + ((hint->last_presence_message && presence_state->message && !strcmp(hint->last_presence_message, presence_state->message)) || (!hint->last_presence_message && !presence_state->message))) { + + /* this update is the same as the last, do nothing */ + continue; + } + + /* update new values */ + ast_free(hint->last_presence_subtype); + ast_free(hint->last_presence_message); + hint->last_presence_state = presence_state->state; + hint->last_presence_subtype = presence_state->subtype ? ast_strdup(presence_state->subtype) : NULL; + hint->last_presence_message = presence_state->message ? ast_strdup(presence_state->message) : NULL; + + /* For general callbacks */ + cb_iter = ao2_iterator_init(statecbs, 0); + for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_ref(state_cb, -1)) { + execute_state_callback(state_cb->change_cb, + context_name, + exten_name, + state_cb->data, + AST_HINT_UPDATE_PRESENCE, + hint, + NULL); + } + ao2_iterator_destroy(&cb_iter); + + /* For extension callbacks */ + cb_iter = ao2_iterator_init(hint->callbacks, 0); + for (; (state_cb = ao2_iterator_next(&cb_iter)); ao2_cleanup(state_cb)) { + execute_state_callback(state_cb->change_cb, + context_name, + exten_name, + state_cb->data, + AST_HINT_UPDATE_PRESENCE, + hint, + NULL); + } + ao2_iterator_destroy(&cb_iter); } + ao2_iterator_destroy(&hint_iter); + ast_mutex_unlock(&context_merge_lock); + + ast_free(hint_app); } /*! @@ -11765,7 +11700,7 @@ static void unload_pbx(void) int x; if (presence_state_sub) { - presence_state_sub = ast_event_unsubscribe(presence_state_sub); + presence_state_sub = stasis_unsubscribe(presence_state_sub); } if (device_state_sub) { device_state_sub = stasis_unsubscribe(device_state_sub); @@ -11780,9 +11715,6 @@ static void unload_pbx(void) ast_custom_function_unregister(&exception_function); ast_custom_function_unregister(&testtime_function); ast_data_unregister(NULL); - if (extension_state_tps) { - extension_state_tps = ast_taskprocessor_unreference(extension_state_tps); - } } int load_pbx(void) @@ -11793,9 +11725,6 @@ int load_pbx(void) /* Initialize the PBX */ ast_verb(1, "Asterisk PBX Core Initializing\n"); - if (!(extension_state_tps = ast_taskprocessor_get("pbx-core", 0))) { - ast_log(LOG_WARNING, "failed to create pbx-core taskprocessor\n"); - } ast_verb(1, "Registering builtin applications:\n"); ast_cli_register_multiple(pbx_cli, ARRAY_LEN(pbx_cli)); @@ -11819,8 +11748,7 @@ int load_pbx(void) return -1; } - if (!(presence_state_sub = ast_event_subscribe(AST_EVENT_PRESENCE_STATE, presence_state_cb, "pbx Presence State Change", NULL, - AST_EVENT_IE_END))) { + if (!(presence_state_sub = stasis_subscribe(ast_presence_state_topic_all(), presence_state_cb, NULL))) { return -1; } |