[asterisk-commits] murf: branch murf/bug11210 r100738 - in /team/murf/bug11210: channels/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 28 19:30:42 CST 2008


Author: murf
Date: Mon Jan 28 19:30:41 2008
New Revision: 100738

URL: http://svn.digium.com/view/asterisk?view=rev&rev=100738
Log:
Checkpoint. Gotta resolve conflict. I'm in the middle to trying to figure out why we are double freeing an object. Have the refcounting debug turned on

Modified:
    team/murf/bug11210/channels/chan_iax2.c
    team/murf/bug11210/main/astobj2.c

Modified: team/murf/bug11210/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_iax2.c?view=diff&rev=100738&r1=100737&r2=100738
==============================================================================
--- team/murf/bug11210/channels/chan_iax2.c (original)
+++ team/murf/bug11210/channels/chan_iax2.c Mon Jan 28 19:30:41 2008
@@ -86,6 +86,7 @@
 #include "asterisk/stringfields.h"
 #include "asterisk/linkedlists.h"
 #include "asterisk/event.h"
+#define  REF_DEBUG 1
 #include "asterisk/astobj2.h"
 
 #include "iax2.h"
@@ -994,7 +995,8 @@
 #endif
 
 static void iax2_destroy_byptr(void *p2);
-static void iax2_destroy(int callno);
+/* static void iax2_destroy(int callno); replaced with destroy_byptr and iax2_unlink */
+static void iax2_unlink(int callno);
 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
 static int expire_registry(const void *data);
 static int iax2_answer(struct ast_channel *c);
@@ -1574,15 +1576,15 @@
 	struct chan_iax2_pvt *tmp;
 	jb_conf jbconf;
 
-	if (!(tmp = ao2_alloc(sizeof(struct chan_iax2_pvt),iax2_destroy_byptr)))
+	if (!(tmp = ao2_t_alloc(sizeof(struct chan_iax2_pvt),iax2_destroy_byptr,"allocate a new pvt struct")))
 		return NULL;
 
 	if (ast_string_field_init(tmp, 32)) {
-		ast_free(tmp);
+		ao2_t_ref(tmp,-1,"string field init fails-- toss the newly allocated pvt");
 		tmp = NULL;
 		return NULL;
 	}
-	ast_log(LOG_NOTICE,"New IAX pvt created.\n");
+	ast_log(LOG_NOTICE,"New IAX pvt created(%p).\n", tmp);
 	tmp->prefs = prefs;
 	tmp->pingid = -1;
 	tmp->lagid = -1;
@@ -1698,7 +1700,7 @@
 			ao2_t_unlink(findcall2, iaxs[callno], "moving a pvt to the trunked pvt range");
 			iaxs[x] = iaxs[callno];
 			iaxs[x]->callno = x;
-			iaxs[callno] = NULL;
+			iaxs[callno] = NULL; /* moving the reference to a different array position shouldn't modify the ref count */
 			/* put it back in in the new spot */
 #define CHECK_LINK_B  { void *zzq = 
 #define CHECK_LINK_E  if (!zzq) ast_log(LOG_WARNING,"ao2_link failure! Check this out!");}
@@ -1791,7 +1793,7 @@
 		tmp_pvt_ptr->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
 		tmp_pvt_ptr->addr.sin_port = sin->sin_port;
 		tmp_pvt_ptr->peercallno = callno;
-		respvt = ao2_t_find(findcall1, tmp_pvt_ptr, OBJ_POINTER, "Find the pvt in the findcall1 table\n");
+		respvt = ao2_t_find(findcall1, tmp_pvt_ptr, OBJ_POINTER, "Find the pvt in the findcall1 table");
 		/* show_iaxs();
 		   ast_log(LOG_NOTICE,"first lookup returns %p\n", respvt);
 		   show_findcall1();*/
@@ -1802,7 +1804,7 @@
 		if (!res) {
 			tmp_pvt_ptr->callno = dcallno;
 			tmp_pvt_ptr->peercallno = 0;
-			respvt = ao2_t_find(findcall2, tmp_pvt_ptr, OBJ_POINTER, "Find the pvt in the findcall1 table\n");
+			respvt = ao2_t_find(findcall2, tmp_pvt_ptr, OBJ_POINTER, "Find the pvt in the findcall2 table");
 			/* ast_log(LOG_NOTICE,"second lookup returns %p\n", respvt);
 			   show_findcall2(); */
 			if (respvt)
@@ -1812,7 +1814,7 @@
 			tmp_pvt_ptr->callno = dcallno; /* just in case */
 			tmp_pvt_ptr->transfer.sin_addr.s_addr = sin->sin_addr.s_addr;
 			tmp_pvt_ptr->transfer.sin_port = sin->sin_port;
-			respvt = ao2_t_find(findcall3, tmp_pvt_ptr, OBJ_POINTER, "Find the pvt in the findcall1 table\n");
+			respvt = ao2_t_find(findcall3, tmp_pvt_ptr, OBJ_POINTER, "Find the pvt in the findcall3 table");
 			/* ast_log(LOG_NOTICE,"third lookup returns %p\n", respvt);
 			   show_findcall3(); */
 			if (respvt)
@@ -1821,13 +1823,15 @@
 		if (!res) {
 			tmp_pvt_ptr->transfercallno = dcallno;
 			/* transfer should still be in place from the previous test setup */
-			respvt = ao2_t_find(findcall4, tmp_pvt_ptr, OBJ_POINTER, "Find the pvt in the findcall1 table\n");
+			respvt = ao2_t_find(findcall4, tmp_pvt_ptr, OBJ_POINTER, "Find the pvt in the findcall4 table");
 			/* ast_log(LOG_NOTICE,"fourth lookup returns %p\n", respvt);
 			   show_findcall4(); */
 			if (respvt)
 				res = respvt->callno;
 		}
 	}
+	if (respvt)
+		ao2_t_ref(respvt,-1,"dec the refcount for the returned pvt ptr; it goes from here to frames...");
 	
 	if ((res < 1) && (new >= NEW_ALLOW)) {
 		/* It may seem odd that we look through the peer list for a name for
@@ -1850,7 +1854,7 @@
 			ast_log(LOG_WARNING, "No more space\n");
 			return 0;
 		}
-		iaxs[x] = new_iax(sin, host);
+		iaxs[x] = new_iax(sin, host); /* allocating the object should have bumped the count */
 		update_max_nontrunk();
 		if (iaxs[x]) {
 			/* ast_log(LOG_NOTICE,"Creating new pvt structure: callid = %d. reason: not found.\n", x); */
@@ -2351,6 +2355,7 @@
 
 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
 {
+	ast_log(LOG_NOTICE,"destroy helper called for callno %d (%p)\n", pvt->callno, pvt);
 	/* Decrement AUTHREQ count if needed */
 	if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
 		struct iax2_user *user;
@@ -2396,6 +2401,8 @@
 	struct ast_channel *c = NULL;
 	struct chan_iax2_pvt *pvt = iaxs[callno];
 
+	ast_log(LOG_NOTICE,"predestroy called for callno %d (%p)\n", callno, pvt);
+
 	if (!pvt)
 		return -1;
 
@@ -2405,7 +2412,16 @@
 	}
 
 	if ((c = pvt->owner)) {
+		int zz = PTR_TO_CALLNO(c->tech_pvt);
+		struct chan_iax2_pvt *pvt = iaxs[zz];
+		
+		ast_log(LOG_NOTICE,"predestroy: channel has pvt index of %d (%p)\n", zz, pvt);
 		c->tech_pvt = NULL;
+		if (pvt)
+			ao2_t_ref(pvt,-1,"Nulled out the index stored in the channel");
+		
+		ast_log(LOG_NOTICE,"predestroy: about to force hangup for callno %d, then null out pvt->owner field\n", callno);
+		
 		iax2_queue_hangup(callno);
 		pvt->owner = NULL;
 		ast_module_unref(ast_module_info->self);
@@ -2418,26 +2434,132 @@
 static void iax2_destroy_byptr(void *p2)
 {
 	struct chan_iax2_pvt *pvt = p2;
-	iax2_destroy(pvt->callno);
-}
-
-static void iax2_destroy(int callno)
+	/* gotta free up the stringfields */
+	ast_log(LOG_NOTICE,"Destry_byptr called\n");
+	ast_string_field_free_memory(pvt);
+	ast_log(LOG_NOTICE,"Freeing %p pvt struct(%d)\n", pvt, pvt->callno);
+	ast_free(pvt);
+}
+
+static void iax2_unlink(int callno) /* there are some REAL philosophical challenges in this code.
+									   first, You Cannot Destroy and Free The PVT Directly 
+									   at any point in the code. When you remove the last reference,
+									   the destroy code will be called automatically.
+									   But, the INTENTION of previously calling iax2_destroy() was
+									   to IMMEDIATELY remove the pvt and free it! So, we could
+									   let the unlink routine do almost ALL the work, and then 
+									   decrement the ref counter, and the destroy routine will do the final 
+									   free, OR, we could do nothing more than just decrement the 
+									   ref, and let the destroy routine do all the work....
+									   which should we do? which should we do?
+
+									The minimum demands on the unlink are that ALL refs to this object
+									should be removed, so that the last ao2_ref(pvt,-1) will call the
+									destroy... The destroy routine can't remove references, because 
+									it won't get called until all the refs are removed... so...
+									usually, removing all the refs should involve also unscheduling any
+									routines that might require the pvt ptr... so... */
+
 {
 	struct chan_iax2_pvt *pvt = NULL;
 	struct iax_frame *cur = NULL;
 	struct ast_channel *owner = NULL;
-
+	ast_log(LOG_NOTICE,"Iax2_unlink called for %d\n", callno);
+	pvt = iaxs[callno];
+	if (pvt)
+	{
+		ao2_t_unlink(findcall1,pvt,"remove from findcall1 table");
+		if (!pvt->peercallno)
+			ao2_t_unlink(findcall2,pvt,"remove from findcall2 table");
+		if (pvt->transferring)
+			ao2_t_unlink(findcall3,pvt,"remove from the findcall3 table");
+		if (pvt->transferring == TRANSFER_MEDIAPASS)
+			ao2_t_unlink(findcall4,pvt,"remove from the findcall4 table");
+	}
+	lastused[callno] = ast_tvnow();
+	
+retry:
+	if (pvt)
+		ao2_t_ref(pvt,1,"adding to refcount for unlink... don't want pvt to dissappear until all the fields are inactivated");
+	owner = pvt ? pvt->owner : NULL;
+
+	if (owner) {
+		if (ast_channel_trylock(owner)) {
+			ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
+			ast_mutex_unlock(&iaxsl[callno]);
+			usleep(1);
+			ast_mutex_lock(&iaxsl[callno]);
+			if (pvt)
+				ao2_t_ref(pvt,-1,"we are going to re-get the pvt ptr... decrement here");
+			goto retry;
+		}
+	}
+	if (pvt) {
+		iax2_destroy_helper(pvt);
+
+		/* Already gone */
+		ast_set_flag(pvt, IAX_ALREADYGONE);	
+
+		if (owner) {
+			/* If there's an owner, prod it to give up */
+			/* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
+			 * because we already hold the owner channel lock. */
+			ast_queue_hangup(owner); /* this will remove the ref to the pvt from the channel? */
+			/* this had better zero iaxs[callno] or... we's in trubbel! */
+		}
+
+		AST_LIST_LOCK(&frame_queue);
+		AST_LIST_TRAVERSE(&frame_queue, cur, list) {
+			/* Cancel any pending transmissions */
+			if (cur->callno == pvt->callno) 
+				cur->retries = -1;
+		}
+		AST_LIST_UNLOCK(&frame_queue);
+
+		if (!owner) {
+			jb_frame frame;
+			if (pvt->vars) {
+			    ast_variables_destroy(pvt->vars);
+			    pvt->vars = NULL;
+			}
+
+			while (jb_getall(pvt->jb, &frame) == JB_OK)
+				iax2_frame_free(frame.data);
+			jb_destroy(pvt->jb);
+	
+		}
+	}
+	if (owner) {
+		ast_channel_unlock(owner);
+	}
+	/* the only logical explanation for the next four lines of code is
+	   that if iaxs[callno] is set, and there's no owning channel, then
+	   it's safe to remove the pointer. If there IS an owning channel,
+	   then IT will remove the ref to the pvt as part of the hangup process... */
+	if (!owner) {
+		ao2_t_ref(iaxs[callno], -1, "Remove pvt ptr from iaxs array");
+		iaxs[callno] = NULL;
+	}
+	if (pvt)
+		ao2_t_ref(pvt,-1, "done with the pvt ptr in the unlink routine");
+	if (callno & 0x4000)
+		update_max_trunk();
+	
+}
+
+#ifdef OLDWAY
+static void iax2_destroy(int callno)
+{
+	struct chan_iax2_pvt *pvt = NULL;
+	struct iax_frame *cur = NULL;
+	struct ast_channel *owner = NULL;
+
+	ast_log(LOG_NOTICE,"Iax2_destroy called for %d\n", callno);
+	
 retry:
 	pvt = iaxs[callno];
-	ao2_t_unlink(findcall1,pvt,"destroy this pvt");
-	ao2_t_unlink(findcall2,pvt,"destroy this pvt");
-	if (pvt->transferring)
-		ao2_t_unlink(findcall3,pvt,"destroy this pvt");
-	if (pvt->transferring == TRANSFER_MEDIAPASS)
-		ao2_t_unlink(findcall4,pvt,"destroy this pvt");
-
 	lastused[callno] = ast_tvnow();
-	
+
 	owner = pvt ? pvt->owner : NULL;
 
 	if (owner) {
@@ -2449,8 +2571,7 @@
 			goto retry;
 		}
 	}
-	if (!owner)
-		iaxs[callno] = NULL;
+	
 	if (pvt) {
 		if (!owner)
 			pvt->owner = NULL;
@@ -2497,6 +2618,7 @@
 	if (callno & 0x4000)
 		update_max_trunk();
 }
+#endif
 
 static int update_packet(struct iax_frame *f)
 {
@@ -2530,8 +2652,10 @@
 						/* Transfer timeout */
 						send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
 					} else if (f->final) {
-						if (f->final) 
-							iax2_destroy(callno);
+						if (f->final) {
+							ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+							iax2_unlink(callno);
+						}
 					} else {
 						if (iaxs[callno]->owner)
 							ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
@@ -2551,7 +2675,8 @@
 								iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
 								iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
 							}
-							iax2_destroy(callno);
+							ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+							iax2_unlink(callno);
 						}
 					}
 
@@ -3886,6 +4011,7 @@
 	int alreadygone;
  	struct iax_ie_data ied;
  	memset(&ied, 0, sizeof(ied));
+	ast_log(LOG_NOTICE,"Hangup called for callno %d\n", callno);
 	ast_mutex_lock(&iaxsl[callno]);
 	if (callno && iaxs[callno]) {
 		ast_debug(1, "We're hanging up %s now...\n", c->name);
@@ -3900,11 +4026,13 @@
 			}
 		}
 		/* Explicitly predestroy it */
+		ast_log(LOG_NOTICE,"Hangup calling predestroy  for callno %d\n", callno);
 		iax2_predestroy(callno);
 		/* If we were already gone to begin with, destroy us now */
 		if (alreadygone && iaxs[callno]) {
 			ast_debug(1, "Really destroying %s now...\n", c->name);
-			iax2_destroy(callno);
+			ast_log(LOG_NOTICE,"Hangup Calling Iax2_destroy\n");
+			iax2_unlink(callno);
 		}
 	}
 	ast_mutex_unlock(&iaxsl[callno]);
@@ -4021,7 +4149,7 @@
 	}
 	/* Put them in native bridge mode */
 	if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
-		iaxs[callno0]->bridgecallno = callno1;
+		iaxs[callno0]->bridgecallno = callno1; /* HUH? Should I treat the callno index refs equiv to a ptr ref and bump the ref counts for this sort of thing? */
 		iaxs[callno1]->bridgecallno = callno0;
 	}
 	unlock_both(callno0, callno1);
@@ -4036,12 +4164,12 @@
 			/* Remove from native mode */
 			if (c0->tech == &iax2_tech) {
 				ast_mutex_lock(&iaxsl[callno0]);
-				iaxs[callno0]->bridgecallno = 0;
+				iaxs[callno0]->bridgecallno = 0; /* HUH? Should I treat the callno index refs equiv to a ptr ref and dec the ref counts for this sort of thing? */
 				ast_mutex_unlock(&iaxsl[callno0]);
 			}
 			if (c1->tech == &iax2_tech) {
 				ast_mutex_lock(&iaxsl[callno1]);
-				iaxs[callno1]->bridgecallno = 0;
+				iaxs[callno1]->bridgecallno = 0; /* HUH? Should I treat the callno index refs equiv to a ptr ref and dec the ref counts for this sort of thing? */
 				ast_mutex_unlock(&iaxsl[callno1]);
 			}
 			return AST_BRIDGE_FAILED_NOWARN;
@@ -4055,9 +4183,9 @@
 			/* Remove from native mode */
 			lock_both(callno0, callno1);
 			if (iaxs[callno0])
-				iaxs[callno0]->bridgecallno = 0;
+				iaxs[callno0]->bridgecallno = 0; /* HUH? Should I treat the callno index refs equiv to a ptr ref and dec the ref counts for this sort of thing? */
 			if (iaxs[callno1])
-				iaxs[callno1]->bridgecallno = 0;
+				iaxs[callno1]->bridgecallno = 0; /* HUH? Should I treat the callno index refs equiv to a ptr ref and dec the ref counts for this sort of thing? */
 			unlock_both(callno0, callno1);
 			return AST_BRIDGE_FAILED_NOWARN;
 		}
@@ -4142,9 +4270,9 @@
 	}
 	lock_both(callno0, callno1);
 	if(iaxs[callno0])
-		iaxs[callno0]->bridgecallno = 0;
+		iaxs[callno0]->bridgecallno = 0; /* HUH? Should I treat the callno index refs equiv to a ptr ref and dec the ref counts for this sort of thing? */
 	if(iaxs[callno1])
-		iaxs[callno1]->bridgecallno = 0;
+		iaxs[callno1]->bridgecallno = 0; /* HUH? Should I treat the callno index refs equiv to a ptr ref and dec the ref counts for this sort of thing? */
 	unlock_both(callno0, callno1);
 	return res;
 }
@@ -4256,8 +4384,9 @@
 	tmp->nativeformats = capability;
 	tmp->readformat = ast_best_codec(capability);
 	tmp->writeformat = ast_best_codec(capability);
-	tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
-
+	tmp->tech_pvt = CALLNO_TO_PTR(i->callno); /* HUH? Again, it's like a double ref, the callno is an index into the iaxs array... do I count this as a ref ? */
+	ao2_t_ref(i,1,"Bump the ref because the channel now has an index into the iaxs array");
+	
 	/* Don't use ast_set_callerid() here because it will
 	 * generate a NewCallerID event before the NewChannel event */
 	if (!ast_strlen_zero(i->ani))
@@ -5809,6 +5938,7 @@
 {
 	int call_num = i->callno;
 	/* It is assumed that the callno has already been locked */
+	ast_log(LOG_NOTICE,"send_command_final calling predestroy  for callno %d\n", i->callno);
 	iax2_predestroy(i->callno);
 	if (!iaxs[call_num])
 		return -1;
@@ -8245,7 +8375,8 @@
 					if (call_to_destroy) {
 						if (iaxdebug)
 							ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
-						iax2_destroy(call_to_destroy);
+						ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+						iax2_unlink(call_to_destroy);
 					}
 				}
 				/* Note how much we've received acknowledgement for */
@@ -8698,7 +8829,8 @@
 					iaxs[fr->callno]->owner->hangupcause = ies.causecode;
 				/* Send ack immediately, before we destroy */
 				send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
-				iax2_destroy(fr->callno);
+				ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+				iax2_unlink(fr->callno);
 				break;
 			case IAX_COMMAND_REJECT:
 				/* Set hangup cause according to remote */
@@ -8718,7 +8850,8 @@
 						       fr->ts, NULL, 0, fr->iseqno);
 				if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
 					iaxs[fr->callno]->error = EPERM;
-				iax2_destroy(fr->callno);
+				ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+				iax2_unlink(fr->callno);
 				break;
 			case IAX_COMMAND_TRANSFER:
 				if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
@@ -8751,7 +8884,8 @@
 				if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
 					/* Send ack immediately, before we destroy */
 					send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
-					iax2_destroy(fr->callno);
+					ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+					iax2_unlink(fr->callno);
 					break;
 				}
 				if (ies.format) {
@@ -8868,7 +9002,8 @@
 					/* and finally send the ack */
 					send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
 					/* And wrap up the qualify call */
-					iax2_destroy(fr->callno);
+					ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+					iax2_unlink(fr->callno);
 					peer->callno = 0;
 					ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
 				}
@@ -9065,9 +9200,10 @@
 											using_prefs);
 
 							ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
-							if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
-								iax2_destroy(fr->callno);
-							else if (ies.vars) {
+							if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) {
+								ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+								iax2_unlink(fr->callno);
+							} else if (ies.vars) {
 								struct ast_datastore *variablestore;
 								struct ast_variable *var, *prev = NULL;
 								AST_LIST_HEAD(, ast_var_t) *varlist;
@@ -9129,9 +9265,10 @@
 						ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
 						ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 						send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
-						if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
-							iax2_destroy(fr->callno);
-						else if (ies.vars) {
+						if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) {
+							ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+							iax2_unlink(fr->callno);
+						} else if (ies.vars) {
 							struct ast_datastore *variablestore;
 							struct ast_variable *var, *prev = NULL;
 							AST_LIST_HEAD(, ast_var_t) *varlist;
@@ -9171,7 +9308,8 @@
 			case IAX_COMMAND_INVAL:
 				iaxs[fr->callno]->error = ENOTCONN;
 				ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
-				iax2_destroy(fr->callno);
+				ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+				iax2_unlink(fr->callno);
 				ast_debug(1, "Destroying call %d\n", fr->callno);
 				break;
 			case IAX_COMMAND_VNAK:
@@ -9229,7 +9367,8 @@
 					ast_log(LOG_WARNING, "Registration failure\n");
 				/* Send ack immediately, before we destroy */
 				send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
-				iax2_destroy(fr->callno);
+				ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+				iax2_unlink(fr->callno);
 				break;
 			case IAX_COMMAND_REGREJ:
 				if (iaxs[fr->callno]->reg) {
@@ -9241,7 +9380,8 @@
 				}
 				/* Send ack immediately, before we destroy */
 				send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
-				iax2_destroy(fr->callno);
+				ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+				iax2_unlink(fr->callno);
 				break;
 			case IAX_COMMAND_REGAUTH:
 				/* Authentication request */
@@ -9666,7 +9806,8 @@
 	 */
 	if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
 		ast_mutex_lock(&iaxsl[reg->callno]);
-		iax2_destroy(reg->callno);
+		ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+		iax2_unlink(reg->callno);
 		ast_mutex_unlock(&iaxsl[reg->callno]);
 		reg->callno = 0;
 	}
@@ -9839,7 +9980,8 @@
 	}
 	if (peer->callno > 0) {
 		ast_mutex_lock(&iaxsl[peer->callno]);
-		iax2_destroy(peer->callno);
+		ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+		iax2_unlink(peer->callno);
 		ast_mutex_unlock(&iaxsl[peer->callno]);
 	}
 	peer->callno = 0;
@@ -9885,7 +10027,8 @@
 	if (peer->callno > 0) {
 		ast_log(LOG_NOTICE, "Still have a callno...\n");
 		ast_mutex_lock(&iaxsl[peer->callno]);
-		iax2_destroy(peer->callno);
+		ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+		iax2_unlink(peer->callno);
 		ast_mutex_unlock(&iaxsl[peer->callno]);
 	}
 	if (heldcall)
@@ -10272,7 +10415,8 @@
 
 	if (peer->callno > 0) {
 		ast_mutex_lock(&iaxsl[peer->callno]);
-		iax2_destroy(peer->callno);
+		ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+		iax2_unlink(peer->callno);
 		ast_mutex_unlock(&iaxsl[peer->callno]);
 	}
 
@@ -10782,7 +10926,8 @@
 			ast_mutex_lock(&iaxsl[reg->callno]);
 			if (iaxs[reg->callno]) {
 				iaxs[reg->callno]->reg = NULL;
-				iax2_destroy(reg->callno);
+				ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+				iax2_unlink(reg->callno);
 			}
 			ast_mutex_unlock(&iaxsl[reg->callno]);
 		}
@@ -12028,8 +12173,11 @@
 	ast_netsock_release(netsock);
 	ast_netsock_release(outsock);
 	for (x = 0; x < IAX_MAX_CALLS; x++) {
-		if (iaxs[x])
-			iax2_destroy(x);
+		if (iaxs[x]) {
+			ast_log(LOG_NOTICE,"Calling Iax2_destroy\n");
+			iax2_unlink(x);
+		}
+		
 	}
 	ast_manager_unregister( "IAXpeers" );
 	ast_manager_unregister( "IAXpeerlist" );

Modified: team/murf/bug11210/main/astobj2.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/main/astobj2.c?view=diff&rev=100738&r1=100737&r2=100738
==============================================================================
--- team/murf/bug11210/main/astobj2.c (original)
+++ team/murf/bug11210/main/astobj2.c Mon Jan 28 19:30:41 2008
@@ -22,7 +22,7 @@
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include "asterisk/_private.h"
-/* #define  REF_DEBUG 1 */
+#define  REF_DEBUG 1
 #include "asterisk/astobj2.h"
 #include "asterisk/utils.h"
 #include "asterisk/cli.h"




More information about the asterisk-commits mailing list