[asterisk-dev] Pre-requesites of ast_cel_report_event breached in handle_request_refer (non-permitted lock)

Walter Doekes walter+asterisk-dev at osso.nl
Wed Aug 27 07:37:47 CDT 2014

On 27-08-14 12:45, Dave WOOLLEY wrote:
> Looking at the branch version of 1.8, the following code in
> handle_request_refer appears to blatantly breach the pre-conditions for
> ast_cel_report_event, namely that no locks be held.
>                 /* XXX - what to we put in CEL 'extra' for attended
> transfers to external systems? NULL for now */
>                 ast_channel_lock(current.chan1);
>                 ast_cel_report_event(current.chan1,
> p->refer->attendedtransfer? AST_CEL_ATTENDEDTRANSFER :
> AST_CEL_BLINDTRANSFER, NULL, p->refer->attendedtransfer ? NULL :
> p->refer->refer_to, current.chan2);
>                 ast_channel_unlock(current.chan1);

AFAICT, local_attended_transfer does that as well (locked by 
owner_chan_ref = sip_pvt_lock_full(p) in handle_request_do or by 
get_sip_pvt_byid_locked, or both):

> /* both p and p->owner _MUST_ be locked while calling local_attended_transfer */
> if ((res = local_attended_transfer(p, &current, req, seqno, nounlock))) {
> /* target.chan1 was locked in get_sip_pvt_byid_locked, do not unlock target.chan1 before this */
> ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2);

And that in turn causes a deadlock when the AST_CEL_BRIDGE_UPDATE event 
is simultaneously fired by a different thread (ast_do_masquerade).

We've had to disable BRIDGE_UPDATE cel events for now as a workaround.

Walter Doekes

More information about the asterisk-dev mailing list