diff options
author | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-12-07 16:25:25 +0000 |
---|---|---|
committer | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-12-07 16:25:25 +0000 |
commit | aad96df6c1bc59e8f14f2ef7bcae9ed0571b18d6 (patch) | |
tree | e15d0a0639c562b3e82cb452915f79eb7bef289e /apps/app_queue.c | |
parent | 32e7c2d616699b3fbad25b7cfeec707636aec109 (diff) |
* 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: http://svn.digium.com/svn/asterisk/branches/1.4@91780 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r-- | apps/app_queue.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index 8606ede2f..34d039562 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2502,7 +2502,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)); time(&now); @@ -2559,7 +2563,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); @@ -2569,48 +2572,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); ast_mutex_unlock(&qe->parent->lock); - if(use_weight) + if (use_weight) AST_LIST_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); + ast_mutex_unlock(&qe->parent->lock); + if (use_weight) + AST_LIST_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); ast_mutex_unlock(&qe->parent->lock); - if(use_weight) + if (use_weight) AST_LIST_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; |