From bfd58d8c2a27b12e8ddd405815eada9468ffad22 Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Fri, 7 Dec 2007 16:28:36 +0000 Subject: Merged revisions 91780 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r91780 | russell | 2007-12-07 10:25:25 -0600 (Fri, 07 Dec 2007) | 7 lines * Add channel locking around datastore operations that expect the channel to be locked. * Document why we don't record Local channels in the dialed interfaces list. * Handle memory allocation failure. * Remove the dialed variable, as it wasn't actually needed. * Tweak some formatting to conform to coding guidelines. ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@91781 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_queue.c | 56 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'apps/app_queue.c') diff --git a/apps/app_queue.c b/apps/app_queue.c index 9b667d69f..bd8fb5057 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2735,7 +2735,11 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce int forwardsallowed = 1; int callcompletedinsl; struct ao2_iterator memi; - struct ast_datastore *datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL); + struct ast_datastore *datastore; + + ast_channel_lock(qe->chan); + datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL); + ast_channel_unlock(qe->chan); memset(&bridge_config, 0, sizeof(bridge_config)); tmpid[0] = 0; @@ -2806,7 +2810,6 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce while ((cur = ao2_iterator_next(&memi))) { struct callattempt *tmp = ast_calloc(1, sizeof(*tmp)); struct ast_dialed_interface *di; - int dialed = 0; AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces; if (!tmp) { ao2_ref(cur, -1); @@ -2816,48 +2819,67 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce goto out; } if (!datastore) { - if(!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) { + if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) { ao2_ref(cur, -1); ao2_unlock(qe->parent); - if(use_weight) + if (use_weight) ao2_unlock(queues); free(tmp); goto out; } datastore->inheritance = DATASTORE_INHERIT_FOREVER; - dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)); + if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) { + ao2_ref(cur, -1); + ao2_unlock(&qe->parent); + if (use_weight) + ao2_unlock(queues); + free(tmp); + goto out; + } datastore->data = dialed_interfaces; AST_LIST_HEAD_INIT(dialed_interfaces); + + ast_channel_lock(qe->chan); ast_channel_datastore_add(qe->chan, datastore); + ast_channel_unlock(qe->chan); } else dialed_interfaces = datastore->data; + AST_LIST_LOCK(dialed_interfaces); AST_LIST_TRAVERSE(dialed_interfaces, di, list) { - /* XXX case sensitive ?? */ - if(!strcasecmp(cur->interface, di->interface)) { - dialed = 1; + if (!strcasecmp(cur->interface, di->interface)) { + ast_log(LOG_DEBUG, "Skipping dialing interface '%s' since it has already been dialed\n", + di->interface); break; } } - if (!dialed && strncasecmp(cur->interface, "Local/", 6)) { - if(!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) { + AST_LIST_UNLOCK(dialed_interfaces); + + if (di) { + free(tmp); + continue; + } + + /* It is always ok to dial a Local interface. We only keep track of + * which "real" interfaces have been dialed. The Local channel will + * inherit this list so that if it ends up dialing a real interface, + * it won't call one that has already been called. */ + if (strncasecmp(cur->interface, "Local/", 6)) { + if (!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) { ao2_ref(cur, -1); - AST_LIST_UNLOCK(dialed_interfaces); ao2_unlock(qe->parent); - if(use_weight) + if (use_weight) ao2_unlock(queues); free(tmp); goto out; } strcpy(di->interface, cur->interface); + + AST_LIST_LOCK(dialed_interfaces); AST_LIST_INSERT_TAIL(dialed_interfaces, di, list); - } else if (dialed) { - ast_log(LOG_DEBUG, "Skipping dialing interface '%s' since it has already been dialed\n", di->interface); AST_LIST_UNLOCK(dialed_interfaces); - free(tmp); - continue; } - AST_LIST_UNLOCK(dialed_interfaces); + tmp->stillgoing = -1; tmp->member = cur; tmp->oldstatus = cur->status; -- cgit v1.2.3