[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, ¤t, 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
OSSO B.V.
More information about the asterisk-dev
mailing list