diff options
author | Richard Mudgett <rmudgett@digium.com> | 2014-10-03 17:39:50 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2014-10-03 17:39:50 +0000 |
commit | 6a844be566478d6fed1ec93c0836fbf5d5d46ff3 (patch) | |
tree | ca7a344f77695f1ecdeaf68cb5c9a6b899562b96 /include/asterisk/res_pjsip_session.h | |
parent | b67094624d33b6586177435017cd4f6fdedd3f3f (diff) |
chan_pjsip: Fix deadlock when masquerading PJSIP channels.
Performing a directed call pickup resulted in a deadlock when PJSIP
channels were involved.
A masquerade needs to hold onto the channel locks while it swaps channel
information between the two channels involved in the masquerade. With
PJSIP channels, the fixup routine needed to push a fixup task onto the
PJSIP channel's serializer. Unfortunately, if the serializer was also
processing a task that needed to lock the channel, you get deadlock.
* Added a new control frame that is used to notify the channels that a
masquerade is about to start and when it has completed.
* Added the ability to query taskprocessors if the current thread is the
taskprocessor thread.
* Added the ability to suspend/unsuspend the PJSIP serializer thread so a
masquerade could fixup the PJSIP channel without using the serializer.
ASTERISK-24356 #close
Reported by: rmudgett
Review: https://reviewboard.asterisk.org/r/4034/
........
Merged revisions 424471 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@424472 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include/asterisk/res_pjsip_session.h')
-rw-r--r-- | include/asterisk/res_pjsip_session.h | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h index 010a74dc0..3344a6b38 100644 --- a/include/asterisk/res_pjsip_session.h +++ b/include/asterisk/res_pjsip_session.h @@ -87,6 +87,9 @@ struct ast_sip_session_media { */ struct ast_sip_session_delayed_request; +/*! \brief Opaque struct controlling the suspension of the session's serializer. */ +struct ast_sip_session_suspender; + /*! * \brief A structure describing a SIP session * @@ -96,43 +99,45 @@ struct ast_sip_session_delayed_request; * to use the term "SIP session" to refer to the INVITE dialog itself. */ struct ast_sip_session { - /* Dialplan extension where incoming call is destined */ + /*! Dialplan extension where incoming call is destined */ char exten[AST_MAX_EXTENSION]; - /* The endpoint with which Asterisk is communicating */ + /*! The endpoint with which Asterisk is communicating */ struct ast_sip_endpoint *endpoint; - /* The contact associated with this session */ + /*! The contact associated with this session */ struct ast_sip_contact *contact; - /* The PJSIP details of the session, which includes the dialog */ + /*! The PJSIP details of the session, which includes the dialog */ struct pjsip_inv_session *inv_session; - /* The Asterisk channel associated with the session */ + /*! The Asterisk channel associated with the session */ struct ast_channel *channel; - /* Registered session supplements */ + /*! Registered session supplements */ AST_LIST_HEAD(, ast_sip_session_supplement) supplements; - /* Datastores added to the session by supplements to the session */ + /*! Datastores added to the session by supplements to the session */ struct ao2_container *datastores; - /* Media streams */ + /*! Media streams */ struct ao2_container *media; - /* Serializer for tasks relating to this SIP session */ + /*! Serializer for tasks relating to this SIP session */ struct ast_taskprocessor *serializer; - /* Requests that could not be sent due to current inv_session state */ + /*! Non-null if the session serializer is suspended or being suspended. */ + struct ast_sip_session_suspender *suspended; + /*! Requests that could not be sent due to current inv_session state */ AST_LIST_HEAD_NOLOCK(, ast_sip_session_delayed_request) delayed_requests; - /* When we need to reschedule a reinvite, we use this structure to do it */ + /*! When we need to reschedule a reinvite, we use this structure to do it */ pj_timer_entry rescheduled_reinvite; - /* Format capabilities pertaining to direct media */ + /*! Format capabilities pertaining to direct media */ struct ast_format_cap *direct_media_cap; - /* When we need to forcefully end the session */ + /*! When we need to forcefully end the session */ pj_timer_entry scheduled_termination; - /* Identity of endpoint this session deals with */ + /*! Identity of endpoint this session deals with */ struct ast_party_id id; - /* Requested capabilities */ + /*! Requested capabilities */ struct ast_format_cap *req_caps; - /* Optional DSP, used only for inband DTMF detection if configured */ + /*! Optional DSP, used only for inband DTMF detection if configured */ struct ast_dsp *dsp; - /* Whether the termination of the session should be deferred */ + /*! Whether the termination of the session should be deferred */ unsigned int defer_terminate:1; - /* Deferred incoming re-invite */ + /*! Deferred incoming re-invite */ pjsip_rx_data *deferred_reinvite; - /* Current T.38 state */ + /*! Current T.38 state */ enum ast_sip_session_t38state t38state; }; @@ -388,6 +393,28 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, pjsip_inv_session *inv); /*! + * \brief Request and wait for the session serializer to be suspended. + * \since 12.7.0 + * + * \param session Which session to suspend the serializer. + * + * \note No channel locks can be held while calling without risk of deadlock. + * + * \return Nothing + */ +void ast_sip_session_suspend(struct ast_sip_session *session); + +/*! + * \brief Request the session serializer be unsuspended. + * \since 12.7.0 + * + * \param session Which session to unsuspend the serializer. + * + * \return Nothing + */ +void ast_sip_session_unsuspend(struct ast_sip_session *session); + +/*! * \brief Create a new outgoing SIP session * * The endpoint that is passed in will have its reference count increased by one since |