Index: main/dial.c =================================================================== --- main/dial.c (revision 104083) +++ main/dial.c (working copy) @@ -50,7 +50,7 @@ enum ast_dial_result state; /*! Status of dial */ void *options[AST_DIAL_OPTION_MAX]; /*! Global options */ ast_dial_state_callback state_callback; /*! Status callback */ - AST_LIST_HEAD_NOLOCK(, ast_dial_channel) channels; /*! Channels being dialed */ + AST_LIST_HEAD(, ast_dial_channel) channels; /*! Channels being dialed */ pthread_t thread; /*! Thread (if running in async) */ ast_mutex_t lock; /*! Lock to protect the thread information above */ }; @@ -189,7 +189,7 @@ return NULL; /* Initialize list of channels */ - AST_LIST_HEAD_INIT_NOLOCK(&dial->channels); + AST_LIST_HEAD_INIT(&dial->channels); /* Initialize thread to NULL */ dial->thread = AST_PTHREADT_NULL; @@ -236,6 +236,7 @@ int success = 0, res = 0; /* Iterate through channel list, requesting and calling each one */ + AST_LIST_LOCK(&dial->channels); AST_LIST_TRAVERSE(&dial->channels, channel, list) { char numsubst[AST_MAX_EXTENSION]; @@ -285,6 +286,7 @@ ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst); } } + AST_LIST_UNLOCK(&dial->channels); /* If number of failures matches the number of channels, then this truly failed */ return success; @@ -295,10 +297,12 @@ { struct ast_dial_channel *channel = NULL; + AST_LIST_LOCK(&dial->channels); AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (channel->owner == owner) break; } + AST_LIST_UNLOCK(&dial->channels); return channel; } @@ -319,8 +323,10 @@ case AST_CONTROL_ANSWER: if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", channel->owner->name, chan->name); + AST_LIST_LOCK(&dial->channels); AST_LIST_REMOVE(&dial->channels, channel, list); AST_LIST_INSERT_HEAD(&dial->channels, channel, list); + AST_LIST_UNLOCK(&dial->channels); set_state(dial, AST_DIAL_RESULT_ANSWERED); break; case AST_CONTROL_BUSY: @@ -394,8 +400,10 @@ case AST_CONTROL_ANSWER: if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "%s answered\n", channel->owner->name); + AST_LIST_LOCK(&dial->channels); AST_LIST_REMOVE(&dial->channels, channel, list); AST_LIST_INSERT_HEAD(&dial->channels, channel, list); + AST_LIST_UNLOCK(&dial->channels); set_state(dial, AST_DIAL_RESULT_ANSWERED); break; case AST_CONTROL_BUSY: @@ -460,12 +468,14 @@ cs[pos++] = chan; /* Add channels we are attempting to dial */ + AST_LIST_LOCK(&dial->channels); AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (channel->owner) { cs[pos++] = channel->owner; count++; } } + AST_LIST_UNLOCK(&dial->channels); /* If we have no outbound channels in progress, switch state to unanswered and stop */ if (!count) { @@ -517,12 +527,14 @@ /* Do post-processing from loop */ if (dial->state == AST_DIAL_RESULT_ANSWERED) { /* Hangup everything except that which answered */ + AST_LIST_LOCK(&dial->channels); AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (!channel->owner || channel->owner == who) continue; ast_hangup(channel->owner); channel->owner = NULL; } + AST_LIST_UNLOCK(&dial->channels); /* If ANSWER_EXEC is enabled as an option, execute application on answered channel */ if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC))) { channel->is_running_app = 1; @@ -531,12 +543,14 @@ } } else if (dial->state == AST_DIAL_RESULT_HANGUP) { /* Hangup everything */ + AST_LIST_LOCK(&dial->channels); AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (!channel->owner) continue; ast_hangup(channel->owner); channel->owner = NULL; } + AST_LIST_UNLOCK(&dial->channels); } return dial->state; @@ -636,6 +650,7 @@ dial->thread = AST_PTHREADT_STOP; /* If the answered channel is running an application we have to soft hangup it, can't just poke the thread */ + AST_LIST_LOCK(&dial->channels); if (AST_LIST_FIRST(&dial->channels)->is_running_app) { struct ast_channel *chan = AST_LIST_FIRST(&dial->channels)->owner; ast_channel_lock(chan); @@ -645,6 +660,7 @@ /* Now we signal it with SIGURG so it will break out of it's waitfor */ pthread_kill(thread, SIGURG); } + AST_LIST_UNLOCK(&dial->channels); /* Yay done with it */ ast_mutex_unlock(&dial->lock); @@ -669,12 +685,14 @@ if (!dial) return; + AST_LIST_LOCK(&dial->channels); AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (channel->owner) { ast_hangup(channel->owner); channel->owner = NULL; } } + AST_LIST_UNLOCK(&dial->channels); return; } @@ -693,6 +711,7 @@ return -1; /* Hangup and deallocate all the dialed channels */ + AST_LIST_LOCK(&dial->channels); AST_LIST_TRAVERSE_SAFE_BEGIN(&dial->channels, channel, list) { /* Disable any enabled options */ for (i = 0; i < AST_DIAL_OPTION_MAX; i++) { @@ -712,6 +731,7 @@ free(channel); } AST_LIST_TRAVERSE_SAFE_END; + AST_LIST_UNLOCK(&dial->channels); /* Disable any enabled options globally */ for (i = 0; i < AST_DIAL_OPTION_MAX; i++) { @@ -768,6 +788,7 @@ return -1; /* Look for channel, we can sort of cheat and predict things - the last channel in the list will probably be what they want */ + AST_LIST_LOCK(&dial->channels); if (AST_LIST_LAST(&dial->channels)->num != num) { AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (channel->num == num) @@ -776,6 +797,7 @@ } else { channel = AST_LIST_LAST(&dial->channels); } + AST_LIST_UNLOCK(&dial->channels); /* If none found, return failure */ if (!channel) @@ -830,6 +852,7 @@ return -1; /* Look for channel, we can sort of cheat and predict things - the last channel in the list will probably be what they want */ + AST_LIST_LOCK(&dial->channels); if (AST_LIST_LAST(&dial->channels)->num != num) { AST_LIST_TRAVERSE(&dial->channels, channel, list) { if (channel->num == num) @@ -838,6 +861,7 @@ } else { channel = AST_LIST_LAST(&dial->channels); } + AST_LIST_UNLOCK(&dial->channels); /* If none found, return failure */ if (!channel)