Index: channel.c =================================================================== --- channel.c (revision 62036) +++ channel.c (working copy) @@ -1311,6 +1311,7 @@ int ast_hangup(struct ast_channel *chan) { int res = 0; + struct ast_cdr *cdr; /* Don't actually hang up a channel that will masquerade as someone else, or if someone is going to masquerade as us */ @@ -1355,9 +1356,11 @@ chan->generator->release(chan, chan->generatordata); chan->generatordata = NULL; chan->generator = NULL; + cdr = NULL; if (chan->cdr) { /* End the CDR if it hasn't already */ ast_cdr_end(chan->cdr); - ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ + /* Post the CDR later as we have a lock, and this can be SLOW */ + cdr = chan->cdr; chan->cdr = NULL; } if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { @@ -1388,6 +1391,8 @@ ast_cause2str(chan->hangupcause) ); ast_channel_free(chan); + if (cdr) + ast_cdr_detach(cdr); /* Post and free the CDR */ return res; }