[asterisk-commits] oej: branch oej/pinepacketrequest r217226 - /team/oej/pinepacketrequest/chann...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 8 15:37:02 CDT 2009


Author: oej
Date: Tue Sep  8 15:37:00 2009
New Revision: 217226

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=217226
Log:
- Moving all sip_messages to AST_LIST
- No more "nextpacket" pointers
- created "sip_message_destroy" to safely destroy messages

Maybe we should do as we do with frames and act green, reuse sip_messages that we've allocated.

Well, this works. I can call echo.


Modified:
    team/oej/pinepacketrequest/channels/chan_sip.c

Modified: team/oej/pinepacketrequest/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/pinepacketrequest/channels/chan_sip.c?view=diff&rev=217226&r1=217225&r2=217226
==============================================================================
--- team/oej/pinepacketrequest/channels/chan_sip.c (original)
+++ team/oej/pinepacketrequest/channels/chan_sip.c Tue Sep  8 15:37:00 2009
@@ -1376,7 +1376,6 @@
 	struct sip_pvt *owner;			/*!< Owner AST call */
 	int timer_a;				/*!< SIP timer A, retransmission timer */
 	int timer_t1;				/*!< SIP Timer T1, estimated RTT or 500 ms */
-	struct sip_message *nextpacket;		/*!< STUPID STUPID STUPID and well STUPID */
 	/* ----------------------- Data */
 	struct ast_str *data;			/*!< The actual raw data */
 	struct ast_str *parsedata;		/*!< The parsed data */
@@ -1849,7 +1848,7 @@
 	struct ast_rtp_instance *rtp;		/*!< RTP Session */
 	struct ast_rtp_instance *vrtp;		/*!< Video RTP session */
 	struct ast_rtp_instance *trtp;		/*!< Text RTP session */
-	struct sip_message *packets;		/*!< Packets scheduled for re-transmission */
+	AST_LIST_HEAD_NOLOCK(packets, sip_message) packets; /*!< Packets scheduled for re-transmission */
 	struct sip_history_head *history;	/*!< History of this SIP dialog */
 	size_t history_entries;			/*!< Number of entires in the history */
 	struct ast_variable *chanvars;		/*!< Channel variables to set for inbound call */
@@ -2461,6 +2460,7 @@
 static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct sip_message *req, int seqno);
 static int sip_sipredirect(struct sip_pvt *p, const char *dest);
 static int is_method_allowed(unsigned int *allowed_methods, enum sipmethod method);
+static void sip_message_destroy(struct sip_message *msg);
 
 /*--- Codec handling / SDP */
 static void try_suggested_sip_codec(struct sip_pvt *p);
@@ -3093,21 +3093,19 @@
 		dialog->stateid = -1; /* shouldn't we 'zero' this out? */
 	}
 	/* Remove link from peer to subscription of MWI */
-	if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog)
+	if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog) {
 		dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
-	if (dialog->relatedpeer && dialog->relatedpeer->call == dialog)
+	}
+	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");
+	}
 
 	/* remove all current packets in this dialog */
-	while((cp = dialog->packets)) {
-		dialog->packets = dialog->packets->nextpacket;
-		AST_SCHED_DEL(sched, cp->retransid);
-		dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy");
-		if (cp->data) {
-			ast_free(cp->data);
-		}
-		ast_free(cp);
-	}
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&dialog->packets, cp, next) {
+		AST_LIST_REMOVE_CURRENT(next);
+		sip_message_destroy(cp);
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
 
 	AST_SCHED_DEL_UNREF(sched, dialog->waitid, dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
 
@@ -3258,6 +3256,23 @@
 	if (sipdebug)
 		ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n");
 	return NULL;
+}
+
+/*! \brief Deallocate and unref a sip_message */
+static void sip_message_destroy(struct sip_message *msg)
+{
+	if (msg->retransid) {
+		AST_SCHED_DEL(sched, msg->retransid);
+	}
+	if (msg->owner) {
+		dialog_unref(msg->owner, "remove all packet in this dialog, and the pointer to the dialog too");
+	}
+	if (msg->data) {
+		ast_free(msg->data);
+	}
+	if (msg->parsedata) {
+		ast_free(msg->data);
+	}
 }
 
 /*! \brief returns true if 'name' (with optional trailing whitespace)
@@ -3644,7 +3659,7 @@
 /*! \brief Retransmit SIP message if no answer (Called from scheduler) */
 static int retrans_pkt(const void *data)
 {
-	struct sip_message *pkt = (struct sip_message *)data, *prev, *cur = NULL;
+	struct sip_message *pkt = (struct sip_message *)data, *cur = NULL;
 	int reschedule = DEFAULT_RETRANS;
 	int xmitres = 0;
 	
@@ -3746,19 +3761,15 @@
 	}
 
 	/* Remove the packet */
-	for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->nextpacket) {
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&pkt->owner->packets, cur, next) {
 		if (cur == pkt) {
-			UNLINKPACKET(cur, pkt->owner->packets, prev);
+			AST_LIST_REMOVE_CURRENT(next);
 			sip_pvt_unlock(pkt->owner);
-			if (pkt->owner)
-				pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
-			if (pkt->data)
-				ast_free(pkt->data);
-			pkt->data = NULL;
-			ast_free(pkt);
+			sip_message_destroy(pkt);
 			return 0;
 		}
 	}
+	AST_LIST_TRAVERSE_SAFE_END;
 	/* error case */
 	ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
 	sip_pvt_unlock(pkt->owner);
@@ -3808,8 +3819,8 @@
 	pkt->is_resp = resp;
 	pkt->is_fatal = fatal;
 	pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner");
-	pkt->nextpacket = p->packets;
-	p->packets = pkt;	/* Add it to the queue */
+
+	AST_LIST_INSERT_HEAD(&p->packets, pkt, next);
 	if (resp) {
 		/* Parse out the response code */
 		if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30d", &respid) == 1) {
@@ -3831,11 +3842,8 @@
 	if (xmitres == XMIT_ERROR) {	/* Serious network trouble, no need to try again */
 		append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
 		ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n");
-		AST_SCHED_DEL(sched, pkt->retransid);
-		p->packets = pkt->nextpacket;
-		pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
-		ast_free(pkt->data);
-		ast_free(pkt);
+		AST_LIST_REMOVE_HEAD(&p->packets, next);
+		sip_message_destroy(pkt);
 		return AST_FAILURE;
 	} else {
 		return AST_SUCCESS;
@@ -3861,7 +3869,7 @@
 	}
 
 	/* If there are packets still waiting for delivery, delay the destruction */
-	if (p->packets) {
+	if(AST_LIST_EMPTY(&p->packets)) {
 		if (!p->needdestroy) {
 			char method_str[31];
 			ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
@@ -3953,7 +3961,7 @@
  * called with p locked*/
 static int __sip_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
 {
-	struct sip_message *cur, *prev = NULL;
+	struct sip_message *cur;
 	const char *msg = "Not Found";	/* used only for debugging */
 	int res = FALSE;
 
@@ -3965,8 +3973,7 @@
 	if (p->outboundproxy && !p->outboundproxy->force){
 		ref_proxy(p, NULL);
 	}
-
-	for (cur = p->packets; cur; prev = cur, cur = cur->nextpacket) {
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&p->packets, cur, next) {
 		if (cur->seqno != seqno || cur->is_resp != resp)
 			continue;
 		if (cur->is_resp || cur->method == sipmethod) {
@@ -4001,14 +4008,13 @@
 				usleep(1);
 				sip_pvt_lock(p);
 			}
-			UNLINKPACKET(cur, p->packets, prev);
-			dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt");
-			if (cur->data)
-				ast_free(cur->data);
-			ast_free(cur);
+	
+			AST_LIST_REMOVE_CURRENT(next);
+			sip_message_destroy(cur);
 			break;
 		}
 	}
+	AST_LIST_TRAVERSE_SAFE_END;
 	ast_debug(1, "Stopping retransmission on '%s' of %s %d: Match %s\n",
 		p->callid, resp ? "Response" : "Request", seqno, msg);
 	return res;
@@ -4019,14 +4025,16 @@
 static void __sip_pretend_ack(struct sip_pvt *p)
 {
 	struct sip_message *cur = NULL;
-
-	while (p->packets) {
+	struct sip_message *prev = NULL;
+
+	AST_LIST_TRAVERSE(&p->packets, cur, next) {
 		int method;
-		if (cur == p->packets) {
+
+		if (prev == cur) {
 			ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
 			return;
 		}
-		cur = p->packets;
+		prev = cur;
 		method = (cur->method) ? cur->method : find_sip_method(cur->data->str);
 		__sip_ack(p, cur->seqno, cur->is_resp, method);
 	}
@@ -4038,7 +4046,7 @@
 	struct sip_message *cur;
 	int res = FALSE;
 
-	for (cur = p->packets; cur; cur = cur->nextpacket) {
+	AST_LIST_TRAVERSE(&p->packets, cur, next) {
 		if (cur->seqno == seqno && cur->is_resp == resp &&
 			(cur->is_resp || method_match(sipmethod, cur->data->str))) {
 			/* this is our baby */
@@ -6078,7 +6086,7 @@
 			if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
 				/* stop retransmitting an INVITE that has not received a response */
 				struct sip_message *cur;
-				for (cur = p->packets; cur; cur = cur->nextpacket) {
+				AST_LIST_TRAVERSE(&p->packets, cur, next) {
 					__sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(cur->data->str));
 				}
 
@@ -7252,6 +7260,7 @@
 	ast_string_field_set(p, engine, default_engine);
 
 	AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue);
+	AST_LIST_HEAD_INIT_NOLOCK(&p->packets);
 
 	/* Add to active dialog list */
 
@@ -15242,7 +15251,7 @@
 	/* If we have sessions that needs to be destroyed, do it now */
 	/* Check if we have outstanding requests not responsed to or an active call
 	   - if that's the case, wait with destruction */
-	if (dialog->needdestroy && !dialog->packets && !dialog->owner) {
+	if (dialog->needdestroy && AST_LIST_EMPTY(&dialog->packets) && !dialog->owner) {
 		/* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
 		if (dialog->rtp && ast_rtp_instance_get_bridged(dialog->rtp)) {
 			ast_debug(2, "Bridge still active.  Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
@@ -21437,7 +21446,7 @@
 	else
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 	if (p->initreq.len > 0) {
-		struct sip_message *pkt, *prev_pkt;
+		struct sip_message *pkt;
 		/* If the CANCEL we are receiving is a retransmission, and we already have scheduled
 		 * a reliable 487, then we don't want to schedule another one on top of the previous
 		 * one.
@@ -21449,14 +21458,17 @@
 		 * The only way to do this correctly is to cancel our previously-scheduled reliably-
 		 * transmitted response and send a new one in its place.
 		 */
-		for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->nextpacket) {
+		//for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->nextpacket) {
+
+		AST_LIST_TRAVERSE_SAFE_BEGIN(&p->packets, pkt, next) {
 			if (pkt->seqno == p->lastinvite && pkt->response_code == 487) {
 				AST_SCHED_DEL(sched, pkt->retransid);
-				UNLINKPACKET(pkt, p->packets, prev_pkt);
-				ast_free(pkt);
+				AST_LIST_REMOVE_CURRENT(next);
+				sip_message_destroy(pkt);
 				break;
 			}
 		}
+		AST_LIST_TRAVERSE_SAFE_END;
 		transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
 		transmit_response(p, "200 OK", req);
 		return 1;




More information about the asterisk-commits mailing list