aboutsummaryrefslogtreecommitdiffstats
path: root/pbx.c
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2005-07-08 21:14:34 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2005-07-08 21:14:34 +0000
commit1945cc0f8179b17589095af3550c8969d7790eed (patch)
tree0991463e1dac7d5f44a2be634d9a79b713a86521 /pbx.c
parent4f868cef84f239a71b4f93b58aeb4852b3f0a0d3 (diff)
queue device state changes and handle them serially in a background thread
optimize device state related functions add ast_get_channel_by_name_prefix to allow searching for matching channels in O(1) operation git-svn-id: http://svn.digium.com/svn/asterisk/trunk@6062 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'pbx.c')
-rwxr-xr-xpbx.c146
1 files changed, 28 insertions, 118 deletions
diff --git a/pbx.c b/pbx.c
index 767023c85..f4deb884d 100755
--- a/pbx.c
+++ b/pbx.c
@@ -45,6 +45,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
#include "asterisk/app.h"
+#include "asterisk/devicestate.h"
/*
* I M P O R T A N T :
@@ -160,15 +161,6 @@ struct ast_state_cb {
struct ast_state_cb *next;
};
-/* ast_devstate_cb: An extension state notify */
-struct ast_devstate_cb {
- void *data;
- ast_devstate_cb_type callback;
- struct ast_devstate_cb *next;
-};
-
-static struct ast_devstate_cb *devcbs;
-
/* Hints are pointers from an extension in the dialplan to one or more devices (tech/name) */
struct ast_hint {
struct ast_exten *exten; /* Extension */
@@ -1805,130 +1797,48 @@ int ast_extension_state(struct ast_channel *c, char *context, char *exten)
return ast_extension_state2(e); /* Check all devices in the hint */
}
-/*--- ast_device_state_changed: If device state in cblist is changed - then notify callback function */
-int ast_device_state_changed(const char *fmt, ...)
+void ast_hint_state_changed(const char *device)
{
- struct ast_hint *list;
+ struct ast_hint *hint;
struct ast_state_cb *cblist;
- struct ast_devstate_cb *devcb;
- char hint[AST_MAX_EXTENSION] = "";
- char device[AST_MAX_EXTENSION];
-
- char *cur, *rest;
+ char buf[AST_MAX_EXTENSION];
+ char *parse;
+ char *cur;
int state;
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(device, sizeof(device), fmt, ap);
- va_end(ap);
-
- rest = strchr(device, '-');
- if (rest) {
- *rest = 0;
- }
-
-
- state = ast_device_state(device);
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "Changing state for %s - state %d\n", device, state);
-
ast_mutex_lock(&hintlock);
- /* First check device callbacks */
- devcb = devcbs;
- while(devcb) {
- if (devcb->callback)
- devcb->callback(device, state, devcb->data);
- devcb = devcb->next;
- }
-
- /* Then check callbacks in hints */
- list = hints;
-
- while (list) {
+ for (hint = hints; hint; hint = hint->next) {
+ ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf));
+ parse = buf;
+ for (cur = strsep(&parse, "&"); cur; cur = strsep(&parse, "&")) {
+ if (strcmp(cur, device))
+ continue;
- ast_copy_string(hint, ast_get_extension_app(list->exten), sizeof(hint));
- cur = hint;
- do {
- rest = strchr(cur, '&');
- if (rest) {
- *rest = 0;
- rest++;
- }
+ /* Get device state for this hint */
+ state = ast_extension_state2(hint->exten);
- if (!strcmp(cur, device)) { /* Is this device referred to in this hint? */
-
- /* Get device state for this hint */
- state = ast_extension_state2(list->exten);
-
- if ((state != -1) && (state != list->laststate)) {
- /* Device state changed since last check - notify the watcher */
-
- /* For general callbacks */
- cblist = statecbs;
- while (cblist) {
- cblist->callback(list->exten->parent->name, list->exten->exten, state, cblist->data);
- cblist = cblist->next;
- }
+ if ((state == -1) || (state == hint->laststate))
+ continue;
- /* For extension callbacks */
- cblist = list->callbacks;
- while (cblist) {
- cblist->callback(list->exten->parent->name, list->exten->exten, state, cblist->data);
- cblist = cblist->next;
- }
+ /* Device state changed since last check - notify the watchers */
- list->laststate = state;
- }
- break;
- }
- cur = rest;
- } while (cur);
- list = list->next;
- }
- ast_mutex_unlock(&hintlock);
- return 1;
-}
+ /* For general callbacks */
+ for (cblist = statecbs; cblist; cblist = cblist->next)
+ cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
-/*--- ast_devstate_add: Add device state watcher */
-int ast_devstate_add(ast_devstate_cb_type callback, void *data)
-{
- struct ast_devstate_cb *devcb;
- devcb = malloc(sizeof(struct ast_devstate_cb));
- if (devcb) {
- memset(devcb, 0, sizeof(struct ast_devstate_cb));
- ast_mutex_lock(&hintlock);
- devcb->data = data;
- devcb->callback = callback;
- devcb->next = devcbs;
- devcbs = devcb;
- ast_mutex_unlock(&hintlock);
+ /* For extension callbacks */
+ for (cblist = hint->callbacks; cblist; cblist = cblist->next)
+ cblist->callback(hint->exten->parent->name, hint->exten->exten, state, cblist->data);
+
+ hint->laststate = state;
+ break;
+ }
}
- return 0;
-}
-/*--- ast_devstate_del: Remove device state watcher */
-void ast_devstate_del(ast_devstate_cb_type callback, void *data)
-{
- struct ast_devstate_cb *devcb, *prev = NULL, *next;
- ast_mutex_lock(&hintlock);
- devcb = devcbs;
- while(devcb) {
- next = devcb->next;
- if ((devcb->data == data) && (devcb->callback == callback)) {
- if (prev)
- prev->next = next;
- else
- devcbs = next;
- free(devcb);
- } else
- prev = devcb;
- devcb = next;
- }
ast_mutex_unlock(&hintlock);
}
-
+
/*--- ast_extension_state_add: Add watcher for extension states */
int ast_extension_state_add(const char *context, const char *exten,
ast_state_cb_type callback, void *data)