diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index ef2f19e..05af050 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -2680,6 +2680,7 @@ static void my_handle_dchan_exception(struct sig_pri_span *pri, int index) pri_event_noalarm(pri, index, 0); break; case DAHDI_EVENT_REMOVED: + ast_mutex_unlock(&pri->lock); pri_destroy_span(pri); break; default: @@ -14144,6 +14145,7 @@ static void pri_destroy_span(struct sig_pri_span *pri) int cancel_code; struct dahdi_pri* dahdi_pri; pthread_t master = pri->master; + pthread_t me = pthread_self(); if (!master || (master == AST_PTHREADT_NULL)) { return; @@ -14161,15 +14163,18 @@ static void pri_destroy_span(struct sig_pri_span *pri) dahdi_destroy_channel_range(channel, channel); } - cancel_code = pthread_cancel(master); - pthread_kill(master, SIGURG); - ast_debug(4, - "Waiting to join thread of span %d " - "with pid=%p cancel_code=%d\n", - pri->span, (void *)master, cancel_code); - res = pthread_join(master, NULL); - if (res != 0) { - ast_log(LOG_NOTICE, "pthread_join failed: %d\n", res); + ast_mutex_lock(&pri->lock); + if (me != master) { + cancel_code = pthread_cancel(master); + pthread_kill(master, SIGURG); + ast_debug(4, + "Waiting to join thread of span %d " + "with pid=%p cancel_code=%d\n", + pri->span, (void *)master, cancel_code); + res = pthread_join(master, NULL); + if (res != 0) { + ast_log(LOG_NOTICE, "pthread_join failed: %d\n", res); + } } pri->master = AST_PTHREADT_NULL; @@ -14179,8 +14184,12 @@ static void pri_destroy_span(struct sig_pri_span *pri) ast_debug(4, "closing pri_fd %d\n", i); dahdi_close_pri_fd(dahdi_pri, i); } + ast_mutex_unlock(&pri->lock); sig_pri_init_pri(pri); ast_debug(1, "PRI span %d destroyed\n", pri->span); + if (me == master) { + pthread_exit(NULL); + } } static char *handle_pri_destroy_span(struct ast_cli_entry *e, int cmd,