Merged revisions 335323 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/10

................
  r335323 | oej | 2011-09-12 15:47:13 +0200 (Mån, 12 Sep 2011) | 19 lines
  
  Merged revisions 335319 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.8
  
  ........
    r335319 | oej | 2011-09-12 15:25:30 +0200 (Mån, 12 Sep 2011) | 12 lines
    
    Lock the peer->mvipvt to avoid crashes with SIP history enabled
    
    After the launch of 1.6 event-based MWI we have two threads handling the peer->mwipvt,
    which cause issues with SIP history additions in combination with the max limit for
    number of history entries.
    
    Review: https://reviewboard.asterisk.org/r/1373/
    
    (closes issue ASTERISK-18288)
    
    Thanks to irrot for peer review. Work with this bug funded by IPvision AS
  ........
................


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@335324 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Olle Johansson
2011-09-12 13:50:24 +00:00
parent c5c1fed9b6
commit e4a11bcb6e

View File

@@ -14358,9 +14358,7 @@ static void mwi_event_cb(const struct ast_event *event, void *userdata)
{ {
struct sip_peer *peer = userdata; struct sip_peer *peer = userdata;
ao2_lock(peer);
sip_send_mwi_to_peer(peer, 0); sip_send_mwi_to_peer(peer, 0);
ao2_unlock(peer);
} }
static void network_change_event_subscribe(void) static void network_change_event_subscribe(void)
@@ -24926,9 +24924,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
transmit_response(p, "200 OK", req); transmit_response(p, "200 OK", req);
if (p->relatedpeer) { /* Send first notification */ if (p->relatedpeer) { /* Send first notification */
ao2_lock(p->relatedpeer); /* was WRLOCK */
sip_send_mwi_to_peer(p->relatedpeer, 0); sip_send_mwi_to_peer(p->relatedpeer, 0);
ao2_unlock(p->relatedpeer);
} }
} else if (p->subscribed != CALL_COMPLETION) { } else if (p->subscribed != CALL_COMPLETION) {
@@ -25666,14 +25662,18 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only)
} }
ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs); ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs);
} }
ao2_lock(peer);
if (peer->mwipvt) { if (peer->mwipvt) {
/* Base message on subscription */ /* Base message on subscription */
p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt-- should this be done?"); p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt-- should this be done?");
} else { } else {
/* Build temporary dialog for this message */ /* Build temporary dialog for this message */
if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
ao2_unlock(peer);
return -1; return -1;
}
/* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer
* uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy
* the peer's socket information to the sip_pvt we just allocated * the peer's socket information to the sip_pvt we just allocated
@@ -25701,11 +25701,17 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only)
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
} }
/* We have multiple threads (mwi events and monitor retransmits) working with this PVT and as we modify the sip history if that's turned on,
we really need to have a lock on it */
sip_pvt_lock(p);
/* Send MWI */ /* Send MWI */
ast_set_flag(&p->flags[0], SIP_OUTGOING); ast_set_flag(&p->flags[0], SIP_OUTGOING);
/* the following will decrement the refcount on p as it finishes */ /* the following will decrement the refcount on p as it finishes */
transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
sip_pvt_unlock(p);
dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer."); dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer.");
ao2_unlock(peer);
return 0; return 0;
} }