[asterisk-commits] murf: branch murf/bug11210 r103675 - /team/murf/bug11210/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Feb 14 12:22:32 CST 2008
Author: murf
Date: Thu Feb 14 12:22:31 2008
New Revision: 103675
URL: http://svn.digium.com/view/asterisk?view=rev&rev=103675
Log:
Finally, I've figured out why dialog destruction for those recorded in the peer->call field weren't always happening. It was a dependency cycle between the peer destruct func and the dialog destruct func. Copied the code from sip_destroy to unlink_all to unref the peer->call and dialog->relatedpeer if they are set.... I didn't spot this earlier because I was stopping the tests too early. THis happens in the peer_poke code several seconds after asterisk starts and the sip channel driver is activated.
Modified:
team/murf/bug11210/channels/chan_sip.c
Modified: team/murf/bug11210/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_sip.c?view=diff&rev=103675&r1=103674&r2=103675
==============================================================================
--- team/murf/bug11210/channels/chan_sip.c (original)
+++ team/murf/bug11210/channels/chan_sip.c Thu Feb 14 12:22:31 2008
@@ -2417,6 +2417,13 @@
dialog_unref(dialog, "removing extension_state, should unref the associated dialog ptr that was stored there.");
dialog->stateid = -1; /* shouldn't we 'zero' this out? */
}
+ /* Remove link from peer to subscription of MWI */
+ if (dialog->relatedpeer && dialog->relatedpeer->mwipvt)
+ dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
+ if (dialog->relatedpeer && dialog->relatedpeer->call == dialog)
+ dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
+ else if (dialog->relatedpeer && dialog->relatedpeer->call != dialog)
+ ast_log(LOG_NOTICE,"dialog relatedpeer field points to peer that doesn't point back (peer->call is %p)\n", dialog->relatedpeer->call);
/* remove all current packets in this dialog */
while((cp = dialog->packets)) {
@@ -4360,6 +4367,12 @@
/* Remove link from peer to subscription of MWI */
if (p->relatedpeer && p->relatedpeer->mwipvt)
p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
+ if (p->relatedpeer && p->relatedpeer->call == p)
+ p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
+ else if (p->relatedpeer && p->relatedpeer->call != p)
+ ast_log(LOG_NOTICE,"The dialog %p's relatedpeer (%p [%s]) does not point back to this dialog, but rather to dialog %p.\n",
+ p, p->relatedpeer, p->relatedpeer->name, p->relatedpeer->call);
+
if (p->relatedpeer)
p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy");
@@ -5970,23 +5983,6 @@
.callid = callid,
};
sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs");
-#ifdef DIALOG_DEBUG
- if (sip_pvt_ptr) {
- int rc;
- rc = ao2_t_ref(sip_pvt_ptr, 0, "");
- }
- if (!sip_pvt_ptr) {
- struct ao2_iterator i;
- struct sip_pvt *d2;
-
- i = ao2_iterator_init(dialogs, 0);
-
- while ((d2 = ao2_t_iterator_next(&i, "iterate thru dialogs "))) {
- ast_log(LOG_NOTICE, "Dialogs: %s\n", d2->callid);
- ao2_t_ref(d2, -1, "done with d2 pointer");
- }
- }
-#endif
if (sip_pvt_ptr) { /* well, if we don't find it-- what IS in there? */
/* Found the call */
sip_pvt_lock(sip_pvt_ptr);
@@ -7554,7 +7550,7 @@
struct sip_pvt *p = NULL;
if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
- ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
+ ast_log(LOG_ERROR, "Failed to get temporary pvt\n");
return -1;
}
@@ -9243,7 +9239,6 @@
ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
return 0;
}
- ast_log(LOG_NOTICE,"Allocated SIP pvt dialog %p in transmit_register!\n", p);
if (p->do_history)
append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
@@ -9630,7 +9625,7 @@
ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
if (peer->addr.sin_addr.s_addr) {
- ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers table");
+ ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
}
}
@@ -10434,7 +10429,7 @@
if (peer) {
ao2_t_link(peers, peer, "link peer into peer table");
if (peer->addr.sin_addr.s_addr) {
- ao2_t_link(peers_by_ip, peer, "link peer into peer table");
+ ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
}
if (sip_cancel_destroy(p))
@@ -17913,7 +17908,6 @@
}
if (authpeer->mwipvt && authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */
/* We only allow one subscription per peer */
- ast_log(LOG_NOTICE, "Calling Sip_Destroy() from subscribe request for %s....\n", authpeer->mwipvt->callid);
dialog_unlink_all(authpeer->mwipvt, TRUE, TRUE);
authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
/* sip_destroy(authpeer->mwipvt); */
@@ -18750,11 +18744,9 @@
}
if (monitor_thread != AST_PTHREADT_NULL) {
/* Wake up the thread */
- ast_log(LOG_NOTICE, "about to sigurg the SIP monitor thread.");
pthread_kill(monitor_thread, SIGURG);
} else {
/* Start a new monitor */
- ast_log(LOG_NOTICE, "about to fire up a thread for the SIP do_monitor().");
if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
ast_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
@@ -19128,7 +19120,8 @@
{
struct sip_pvt *p;
int xmitres = 0;
-
+ char mbuf3[200];
+
if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
/* IF we have no IP, or this isn't to be monitored, return
immediately after clearing things out */
@@ -19148,7 +19141,8 @@
}
if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS)))
return -1;
- peer->call = dialog_ref(p, "copy sip alloc from p to peer->call");
+ sprintf(mbuf3,"copy sip alloc from p to peer->call (peer is %p [%s])", peer, peer->name);
+ peer->call = dialog_ref(p, mbuf3);
p->sa = peer->addr;
p->recv = peer->addr;
@@ -20925,58 +20919,39 @@
if (reason != CHANNEL_MODULE_LOAD) {
ast_debug(4, "--------------- SIP reload started\n");
- ast_log(LOG_NOTICE, "Reload: #1a -- about to clear realm authentication\n");
clear_realm_authentication(authl);
- ast_log(LOG_NOTICE, "Reload: #1b -- about to clear sip domains\n");
clear_sip_domains();
- ast_log(LOG_NOTICE, "Reload: #1c -- about to traverse and destroy registry related dialogs\n");
authl = NULL;
/* First, destroy all outstanding registry calls */
/* This is needed, since otherwise active registry entries will not be destroyed */
ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { /* regl is locked */
- ast_log(LOG_NOTICE, "#1c.1. About to get iterator lock for registry entry ");
/* avoid a deadlock in the unlink_all call, if iterator->call's (a dialog) registry entry
is this registry entry. In other words, if the dialog we are pointing to points back to
us, then if we get a lock on this object, and try to UNREF it, we will deadlock, because
we already ... NO. This is not the problem. */
-#ifdef INANE_ATTEMPT_AT_HUMOR
- if (iterator->call && iterator->call->registry && iterator->call->registry->call == iterator->call)
- iterator->call->registry->call = dialog_unref(iterator->call, "null out the registry's call dialog field before unlink_all");
- if (iterator->call && iterator->call->registry)
- iterator->call->registry = registry_unref(iterator->call->registry, "delete dialog's registry entry before unlink_all");
- ast_log(LOG_NOTICE, "#1c.2. Right now....");
-#endif
ASTOBJ_RDLOCK(iterator); /* was RDLOCK and now regl is locked, and the object is also locked */
if (iterator->call) {
ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
- ast_log(LOG_NOTICE, "#1c.3. There's a dialog...unlinking it...");
/* This will also remove references to the registry */
dialog_unlink_all(iterator->call, TRUE, TRUE);
- ast_log(LOG_NOTICE, "#1c.4. Unreffing that dialog...");
iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal");
/* iterator->call = sip_destroy(iterator->call); */
}
- ast_log(LOG_NOTICE, "#1c.5. About to release iterator's registry lock...");
ASTOBJ_UNLOCK(iterator);
} while(0));
- ast_log(LOG_NOTICE, "Reload: #1d -- about to destroy all the users\n");
/* Then, actually destroy users and registry */
ao2_t_ref(users, -1, "destroy users table");
ast_debug(4, "--------------- Done destroying user list\n");
- ast_log(LOG_NOTICE, "Reload: #1e -- about to destroy all the registry entries\n");
ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy);
ast_debug(4, "--------------- Done destroying registry list\n");
- ast_log(LOG_NOTICE, "Reload: #1f -- about to mark all the peer entries for destruction\n");
ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, 0, "callback to mark all peers");
/* reinstate the user table */
- ast_log(LOG_NOTICE, "Reload: #1g -- about to reallocate the user table\n");
users = ao2_t_container_alloc(hash_user_size, user_hash_cb, user_cmp_cb, "allocate users");
}
- ast_log(LOG_NOTICE, "Reload: #2\n");
/* Reset certificate handling for TLS sessions */
default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */
@@ -21100,7 +21075,6 @@
ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT);
ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT);
- ast_log(LOG_NOTICE, "Reload: #3\n");
/* Read the [general] config section of sip.conf (or from realtime config) */
for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
@@ -21465,7 +21439,6 @@
ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
allow_external_domains = 1;
}
- ast_log(LOG_NOTICE, "Reload: #4\n");
/* Build list of authentication to various SIP realms, i.e. service providers */
for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
@@ -21529,7 +21502,6 @@
ast_config_destroy(ucfg);
}
- ast_log(LOG_NOTICE, "Reload: #5\n");
/* Load peers, users and friends */
cat = NULL;
@@ -21625,7 +21597,6 @@
ast_inet_ntoa(externip.sin_addr) , ntohs(externip.sin_port));
}
ast_mutex_unlock(&netlock);
- ast_log(LOG_NOTICE, "Reload: #7\n");
/* Add default domains - host name, IP address and IP:port */
/* Only do this if user added any sip domain with "localdomains" */
@@ -21653,7 +21624,6 @@
add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
}
- ast_log(LOG_NOTICE, "Reload: #8\n");
/* Release configuration from memory */
ast_config_destroy(cfg);
@@ -22376,7 +22346,6 @@
ast_manager_unregister("SIPpeers");
ast_manager_unregister("SIPshowpeer");
ast_manager_unregister("SIPshowregistry");
- ast_log(LOG_NOTICE, "About to hangup dialogs\n");
/* Kill TCP/TLS server threads */
if (sip_tcp_desc.master)
@@ -22404,7 +22373,6 @@
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
ao2_t_ref(p, -1, "toss dialog ptr from iterator_next");
}
- ast_log(LOG_NOTICE, "...Done! Now, grab a monitor lock and join threads...\n");
ast_mutex_lock(&monlock);
if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
@@ -22414,7 +22382,6 @@
}
monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
- ast_log(LOG_NOTICE, "...Done! Now, grab the dialoglist lock and get rid of the dialogs...\n");
/* Destroy all the dialogs and free their memory */
i = ao2_iterator_init(dialogs, 0);
@@ -22423,14 +22390,11 @@
ao2_t_ref(p, -1, "throw away iterator result");
}
- ast_log(LOG_NOTICE, "...Done! Now, free up the ha's...\n");
/* Free memory for local network address mask */
ast_free_ha(localaddr);
- ast_log(LOG_NOTICE, "...Done! Now, free up the realm_authentication...\n");
clear_realm_authentication(authl);
- ast_log(LOG_NOTICE, "...Done! Now, free up the registry entries...\n");
if (default_tls_cfg.certfile)
ast_free(default_tls_cfg.certfile);
@@ -22442,29 +22406,19 @@
ast_free(default_tls_cfg.capath);
ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy);
- ast_log(LOG_NOTICE, "...Done! Now, free up the registry List...\n");
ASTOBJ_CONTAINER_DESTROY(®l);
- ast_log(LOG_NOTICE, "...Done! Now, free up the peers...\n");
ao2_t_ref(peers, -1, "unref the peers table");
- ast_log(LOG_NOTICE, "...Done! Now, free up the peers-by-ip...\n");
ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table");
- ast_log(LOG_NOTICE, "...Done! Now, free up the users...\n");
ao2_t_ref(users, -1, "unref the users table");
- ast_log(LOG_NOTICE, "...Done! Now, free up the dialogs table itself...\n");
ao2_t_ref(dialogs, -1, "unref the dialogs table");
- ast_log(LOG_NOTICE, "...Done! Now, clear up the sip domains info...\n");
clear_sip_domains();
- ast_log(LOG_NOTICE, "...Done! Now, close the sip socket...\n");
close(sipsock);
- ast_log(LOG_NOTICE, "...Done! Now, destroy the scheduler's context...\n");
sched_context_destroy(sched);
- ast_log(LOG_NOTICE, "...Done! Now, destroy the scheduler's used context...\n");
con = ast_context_find(used_context);
if (con)
ast_context_destroy(con, "SIP");
- ast_log(LOG_NOTICE, "...Done!\n");
return 0;
}
More information about the asterisk-commits
mailing list