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
OSSO B.V.



--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
  http://lists.digium.com/mailman/listinfo/asterisk-dev

Reply via email to