Update of /usr/cvsroot/asterisk
In directory localhost.localdomain:/tmp/cvs-serv23507

Modified Files:
        Makefile asterisk.c channel.c pbx.c 
Log Message:
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


Index: Makefile
===================================================================
RCS file: /usr/cvsroot/asterisk/Makefile,v
retrieving revision 1.172
retrieving revision 1.173
diff -u -d -r1.172 -r1.173
--- Makefile    5 Jul 2005 19:04:49 -0000       1.172
+++ Makefile    8 Jul 2005 21:14:34 -0000       1.173
@@ -254,7 +254,7 @@
        cdr.o tdd.o acl.o rtp.o manager.o asterisk.o \
        dsp.o chanvars.o indications.o autoservice.o db.o privacy.o \
        astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \
-       utils.o config_old.o plc.o jitterbuf.o dnsmgr.o
+       utils.o config_old.o plc.o jitterbuf.o dnsmgr.o devicestate.o
 ifeq (${OSARCH},Darwin)
 OBJS+=poll.o dlfcn.o
 ASTLINK=-Wl,-dynamic

Index: asterisk.c
===================================================================
RCS file: /usr/cvsroot/asterisk/asterisk.c,v
retrieving revision 1.166
retrieving revision 1.167
diff -u -d -r1.166 -r1.167
--- asterisk.c  5 Jul 2005 22:11:42 -0000       1.166
+++ asterisk.c  8 Jul 2005 21:14:34 -0000       1.167
@@ -65,6 +65,7 @@
 #include "asterisk/version.h"
 #include "asterisk/build.h"
 #include "asterisk/linkedlists.h"
+#include "asterisk/devicestate.h"
 
 #include "defaults.h"
 
@@ -2095,6 +2096,10 @@
                printf(term_quit());
                exit(1);
        }
+       if (ast_device_state_engine_init()) {
+               printf(term_quit());
+               exit(1);
+       }
        ast_rtp_init();
        if (ast_image_init()) {
                printf(term_quit());

Index: channel.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channel.c,v
retrieving revision 1.211
retrieving revision 1.212
diff -u -d -r1.211 -r1.212
--- channel.c   5 Jul 2005 22:21:54 -0000       1.211
+++ channel.c   8 Jul 2005 21:14:34 -0000       1.212
@@ -57,6 +57,7 @@
 #include "asterisk/lock.h"
 #include "asterisk/app.h"
 #include "asterisk/transcap.h"
+#include "asterisk/devicestate.h"
 
 /* uncomment if you have problems with 'monitoring' synchronized files */
 #if 0
@@ -295,6 +296,58 @@
        return 0;
 }
 
+void ast_channel_unregister(const struct ast_channel_tech *tech)
+{
+       struct chanlist *chan, *last=NULL;
+
+       if (option_debug)
+               ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", 
tech->type);
+
+       ast_mutex_lock(&chlock);
+
+       chan = backends;
+       while (chan) {
+               if (chan->tech == tech) {
+                       if (last)
+                               last->next = chan->next;
+                       else
+                               backends = backends->next;
+                       free(chan);
+                       ast_mutex_unlock(&chlock);
+
+                       if (option_verbose > 1)
+                               ast_verbose( VERBOSE_PREFIX_2 "Unregistered 
channel type '%s'\n", tech->type);
+
+                       return;
+               }
+               last = chan;
+               chan = chan->next;
+       }
+
+       ast_mutex_unlock(&chlock);
+}
+
+const struct ast_channel_tech *ast_get_channel_tech(const char *name)
+{
+       struct chanlist *chanls;
+
+       if (ast_mutex_lock(&chlock)) {
+               ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
+               return NULL;
+       }
+
+       for (chanls = backends; chanls; chanls = chanls->next) {
+               if (strcasecmp(name, chanls->tech->type))
+                       continue;
+
+               ast_mutex_unlock(&chlock);
+               return chanls->tech;
+       }
+
+       ast_mutex_unlock(&chlock);
+       return NULL;
+}
+
 /*--- ast_cause2str: Gives the string form of a given hangup cause */
 const char *ast_cause2str(int cause)
 {
@@ -605,7 +658,7 @@
  * We should definitely go for a better scheme that is deadlock-free.
  */
 static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
-                                              const char *name)
+                                              const char *name, const int 
namelen)
 {
        const char *msg = prev ? "deadlock" : "initial deadlock";
        int retries, done;
@@ -615,8 +668,14 @@
                ast_mutex_lock(&chlock);
                for (c = channels; c; c = c->next) {
                        if (prev == NULL) {
-                               /* want either head of list or match by name */
-                               if (name == NULL || !strcasecmp(name, c->name))
+                               /* want head of list */
+                               if (!name)
+                                       break;
+                               /* want match by full name */
+                               if (!namelen && !strcasecmp(c->name, name))
+                                       break;
+                               /* want match by name prefix */
+                               if (!strncasecmp(c->name, name, namelen))
                                        break;
                        } else if (c == prev) { /* found, return c->next */
                                c = c->next;
@@ -646,13 +705,19 @@
 /*--- ast_channel_walk_locked: Browse channels in use */
 struct ast_channel *ast_channel_walk_locked(const struct ast_channel *prev)
 {
-       return channel_find_locked(prev, NULL);
+       return channel_find_locked(prev, NULL, 0);
 }
 
 /*--- ast_get_channel_by_name_locked: Get channel by name and lock it */
 struct ast_channel *ast_get_channel_by_name_locked(const char *name)
 {
-       return channel_find_locked(NULL, name);
+       return channel_find_locked(NULL, name, 0);
+}
+
+/*--- ast_get_channel_by_name_prefix_locked: Get channel by name prefix and 
lock it */
+struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, 
const int namelen)
+{
+       return channel_find_locked(NULL, name, namelen);
 }
 
 /*--- ast_safe_sleep_conditional: Wait, look for hangups and condition arg */
@@ -964,37 +1029,6 @@
        return res;
 }
 
-void ast_channel_unregister(const struct ast_channel_tech *tech)
-{
-       struct chanlist *chan, *last=NULL;
-
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", 
tech->type);
-
-       ast_mutex_lock(&chlock);
-
-       chan = backends;
-       while (chan) {
-               if (chan->tech == tech) {
-                       if (last)
-                               last->next = chan->next;
-                       else
-                               backends = backends->next;
-                       free(chan);
-                       ast_mutex_unlock(&chlock);
-
-                       if (option_verbose > 1)
-                               ast_verbose( VERBOSE_PREFIX_2 "Unregistered 
channel type '%s'\n", tech->type);
-
-                       return;
-               }
-               last = chan;
-               chan = chan->next;
-       }
-
-       ast_mutex_unlock(&chlock);
-}
-
 int ast_answer(struct ast_channel *chan)
 {
        int res = 0;
@@ -2167,70 +2201,6 @@
        return c;
 }
 
-int ast_parse_device_state(char *device)
-{
-       char name[AST_CHANNEL_NAME] = "";
-       char *cut;
-       struct ast_channel *chan;
-
-       chan = ast_channel_walk_locked(NULL);
-       while (chan) {
-               ast_copy_string(name, chan->name, sizeof(name));
-               ast_mutex_unlock(&chan->lock);
-               cut = strchr(name,'-');
-               if (cut)
-                       *cut = 0;
-               if (!strcmp(name, device)) {
-                       if (chan->_state == AST_STATE_RINGING) {
-                               return AST_DEVICE_RINGING;
-                       } else {
-                               return AST_DEVICE_INUSE;
-                       }
-               }
-               chan = ast_channel_walk_locked(chan);
-       }
-       return AST_DEVICE_UNKNOWN;
-}
-
-int ast_device_state(char *device)
-{
-       char tech[AST_MAX_EXTENSION] = "";
-       char *number;
-       struct chanlist *chanls;
-       int res = 0;
-       
-       ast_copy_string(tech, device, sizeof(tech));
-       number = strchr(tech, '/');
-       if (!number) {
-           return AST_DEVICE_INVALID;
-       }
-       *number = 0;
-       number++;
-               
-       if (ast_mutex_lock(&chlock)) {
-               ast_log(LOG_WARNING, "Unable to lock channel list\n");
-               return -1;
-       }
-       chanls = backends;
-       while(chanls) {
-               if (!strcasecmp(tech, chanls->tech->type)) {
-                       ast_mutex_unlock(&chlock);
-                       if (!chanls->tech->devicestate) 
-                               return ast_parse_device_state(device);
-                       else {
-                               res = chanls->tech->devicestate(number);
-                               if (res == AST_DEVICE_UNKNOWN)
-                                       return ast_parse_device_state(device);
-                               else
-                                       return res;
-                       }
-               }
-               chanls = chanls->next;
-       }
-       ast_mutex_unlock(&chlock);
-       return AST_DEVICE_INVALID;
-}
-
 int ast_call(struct ast_channel *chan, char *addr, int timeout) 
 {
        /* Place an outgoing call, but don't wait any longer than timeout ms 
before returning. 

Index: pbx.c
===================================================================
RCS file: /usr/cvsroot/asterisk/pbx.c,v
retrieving revision 1.256
retrieving revision 1.257
diff -u -d -r1.256 -r1.257
--- pbx.c       20 Jun 2005 23:37:01 -0000      1.256
+++ pbx.c       8 Jul 2005 21:14:34 -0000       1.257
@@ -45,6 +45,7 @@
 #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 *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 @@
        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)

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to