Index: channels/chan_iax2.c =================================================================== --- channels/chan_iax2.c (revision 48552) +++ channels/chan_iax2.c (working copy) @@ -6182,15 +6182,27 @@ if (errno != ECONNREFUSED && errno != EAGAIN) ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); handle_error(); - AST_LIST_LOCK(&idle_list); - AST_LIST_INSERT_TAIL(&idle_list, thread, list); - AST_LIST_UNLOCK(&idle_list); + if (thread->type == IAX_TYPE_DYNAMIC) { + AST_LIST_LOCK(&dynamic_list); + AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); + AST_LIST_UNLOCK(&dynamic_list); + } else { + AST_LIST_LOCK(&idle_list); + AST_LIST_INSERT_TAIL(&idle_list, thread, list); + AST_LIST_UNLOCK(&idle_list); + } return 1; } if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ - AST_LIST_LOCK(&idle_list); - AST_LIST_INSERT_TAIL(&idle_list, thread, list); - AST_LIST_UNLOCK(&idle_list); + if (thread->type == IAX_TYPE_DYNAMIC) { + AST_LIST_LOCK(&dynamic_list); + AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); + AST_LIST_UNLOCK(&dynamic_list); + } else { + AST_LIST_LOCK(&idle_list); + AST_LIST_INSERT_TAIL(&idle_list, thread, list); + AST_LIST_UNLOCK(&idle_list); + } return 1; } /* Mark as ready and send on its way */ @@ -7569,10 +7581,29 @@ struct iax2_thread *thread = data; struct timeval tv; struct timespec ts; + int putinto_idle=0; for(;;) { /* Wait for something to signal us to be awake */ ast_mutex_lock(&thread->lock); + /* + Return threads back to the pool under the thread lock. + Course we don't want to allow the signal to be sent to the thread + at the moment when it's not in a waiting state. + Signal send function wait for the thread lock before sending signal. + */ + if (putinto_idle) { + /* Go back into our respective list */ + if (thread->type == IAX_TYPE_DYNAMIC) { + AST_LIST_LOCK(&dynamic_list); + AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); + AST_LIST_UNLOCK(&dynamic_list); + } else { + AST_LIST_LOCK(&idle_list); + AST_LIST_INSERT_TAIL(&idle_list, thread, list); + AST_LIST_UNLOCK(&idle_list); + } + } if (thread->type == IAX_TYPE_DYNAMIC) { /* Wait to be signalled or time out */ tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); @@ -7626,17 +7657,7 @@ AST_LIST_LOCK(&active_list); AST_LIST_REMOVE(&active_list, thread, list); AST_LIST_UNLOCK(&active_list); - - /* Go back into our respective list */ - if (thread->type == IAX_TYPE_DYNAMIC) { - AST_LIST_LOCK(&dynamic_list); - AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); - AST_LIST_UNLOCK(&dynamic_list); - } else { - AST_LIST_LOCK(&idle_list); - AST_LIST_INSERT_TAIL(&idle_list, thread, list); - AST_LIST_UNLOCK(&idle_list); - } + putinto_idle = 1; } /* Free our own memory */