mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-01 18:09:41 +00:00
chan_sip: Fix realtime locking inversion when poking a just built peer.
When a realtime peer is built it can cause a locking inversion when the just built peer is poked. If the CLI command "sip show channels" is periodically executed then a deadlock can happen because of the locking inversion. * Push the peer poke off onto the scheduler thread to avoid the locking inversion of the just built realtime peer. AST-1540 ASTERISK-24838 #close Reported by: Richard Mudgett Review: https://reviewboard.asterisk.org/r/4454/ ........ Merged revisions 432526 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@432528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -16011,6 +16011,17 @@ static int sip_poke_peer_s(const void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sip_poke_peer_now(const void *data)
|
||||
{
|
||||
struct sip_peer *peer = (struct sip_peer *) data;
|
||||
|
||||
peer->pokeexpire = -1;
|
||||
sip_poke_peer(peer, 0);
|
||||
sip_unref_peer(peer, "removing poke peer ref");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \brief Get registration details from Asterisk DB */
|
||||
static void reg_source_db(struct sip_peer *peer)
|
||||
{
|
||||
@@ -20688,24 +20699,33 @@ static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args
|
||||
static char *sip_show_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
{
|
||||
struct ast_str *cbuf;
|
||||
struct ast_cb_names cbnames = {9, { "retrans_pkt",
|
||||
"__sip_autodestruct",
|
||||
"expire_register",
|
||||
"auto_congest",
|
||||
"sip_reg_timeout",
|
||||
"sip_poke_peer_s",
|
||||
"sip_poke_noanswer",
|
||||
"sip_reregister",
|
||||
"sip_reinvite_retry"},
|
||||
{ retrans_pkt,
|
||||
__sip_autodestruct,
|
||||
expire_register,
|
||||
auto_congest,
|
||||
sip_reg_timeout,
|
||||
sip_poke_peer_s,
|
||||
sip_poke_noanswer,
|
||||
sip_reregister,
|
||||
sip_reinvite_retry}};
|
||||
struct ast_cb_names cbnames = {
|
||||
10,
|
||||
{
|
||||
"retrans_pkt",
|
||||
"__sip_autodestruct",
|
||||
"expire_register",
|
||||
"auto_congest",
|
||||
"sip_reg_timeout",
|
||||
"sip_poke_peer_s",
|
||||
"sip_poke_peer_now",
|
||||
"sip_poke_noanswer",
|
||||
"sip_reregister",
|
||||
"sip_reinvite_retry"
|
||||
},
|
||||
{
|
||||
retrans_pkt,
|
||||
__sip_autodestruct,
|
||||
expire_register,
|
||||
auto_congest,
|
||||
sip_reg_timeout,
|
||||
sip_poke_peer_s,
|
||||
sip_poke_peer_now,
|
||||
sip_poke_noanswer,
|
||||
sip_reregister,
|
||||
sip_reinvite_retry
|
||||
}
|
||||
};
|
||||
|
||||
switch (cmd) {
|
||||
case CLI_INIT:
|
||||
@@ -31084,7 +31104,17 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
|
||||
|
||||
/* Startup regular pokes */
|
||||
if (!devstate_only && enablepoke) {
|
||||
sip_poke_peer(peer, 0);
|
||||
/*
|
||||
* We cannot poke the peer now in this thread without
|
||||
* a lock inversion so pass it off to the scheduler
|
||||
* thread.
|
||||
*/
|
||||
AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
|
||||
0, /* Poke the peer ASAP */
|
||||
sip_poke_peer_now, peer,
|
||||
sip_unref_peer(_data, "removing poke peer ref"),
|
||||
sip_unref_peer(peer, "removing poke peer ref"),
|
||||
sip_ref_peer(peer, "adding poke peer ref"));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user