[asterisk-commits] russell: branch russell/iax2_ff r70806 - /team/russell/iax2_ff/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 21 14:35:25 CDT 2007


Author: russell
Date: Thu Jun 21 14:35:25 2007
New Revision: 70806

URL: http://svn.digium.com/view/asterisk?view=rev&rev=70806
Log:
Instead of dropping full frames if there is another full frame for this call
being processed, queue it up for processing by the thread that is already
handling a full frame for this same call

Modified:
    team/russell/iax2_ff/channels/chan_iax2.c

Modified: team/russell/iax2_ff/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/iax2_ff/channels/chan_iax2.c?view=diff&rev=70806&r1=70805&r2=70806
==============================================================================
--- team/russell/iax2_ff/channels/chan_iax2.c (original)
+++ team/russell/iax2_ff/channels/chan_iax2.c Thu Jun 21 14:35:25 2007
@@ -682,6 +682,12 @@
 #define IAX_TYPE_POOL    1
 #define IAX_TYPE_DYNAMIC 2
 
+struct iax2_pkt_buf {
+	AST_LIST_ENTRY(iax2_pkt_buf) entry;
+	size_t len;
+	unsigned char buf[0];
+};
+
 struct iax2_thread {
 	AST_LIST_ENTRY(iax2_thread) list;
 	int type;
@@ -713,6 +719,10 @@
 		unsigned char type;
 		unsigned char csub;
 	} ffinfo;
+	/*! Queued up full frames for processing.  If more full frames arrive for
+	 *  a call which this thread is already processing a full frame for, they
+	 *  are queued up here. */
+	AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
 };
 
 /* Thread lists */
@@ -6272,6 +6282,60 @@
 	iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
 }
 
+/*!
+ * \brief Check to see if they are deferred full frames for this thread
+ *
+ * \retval 0 No deferred frames were present
+ * \retval non-zero A deferred full frame has been copied into the 
+ *         thread's main buffer for processing
+ */
+static int check_deferred_full_frames(struct iax2_thread *thread)
+{
+	struct iax2_pkt_buf *pkt_buf;
+
+	if (AST_LIST_EMPTY(&thread->full_frames))
+		return 0;
+	
+	pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry);
+	memcpy(thread->buf, pkt_buf->buf, pkt_buf->len);
+	thread->iores = pkt_buf->len;
+
+	ast_free(pkt_buf);
+
+	return 1;
+}
+
+/*!
+ * \brief Queue the last read full frame for processing by a certain thread
+ *
+ * If there are already any full frames queued, they are sorted
+ * by sequence number.
+ */
+static void defer_full_frame(struct iax2_thread *thread)
+{
+	struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
+	struct ast_iax2_full_hdr *fh, *cur_fh;
+
+	if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + thread->iores)))
+		return;
+
+	pkt_buf->len = thread->iores;
+	memcpy(pkt_buf->buf, thread->buf, pkt_buf->len);
+
+	fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&thread->full_frames, cur_pkt_buf, entry) {
+		cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
+		if (fh->oseqno < cur_fh->oseqno) {
+			AST_LIST_INSERT_BEFORE_CURRENT(&thread->full_frames, pkt_buf, entry);
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+
+	if (!cur_pkt_buf)
+		AST_LIST_INSERT_TAIL(&thread->full_frames, pkt_buf, entry);
+}
+
 static int socket_read(int *id, int fd, short events, void *cbdata)
 {
 	struct iax2_thread *thread;
@@ -6320,13 +6384,8 @@
 		AST_LIST_UNLOCK(&active_list);
 		if (cur) {
 			/* we found another thread processing a full frame for this call,
-			   so we can't accept this frame */
-			if (option_debug)
-				ast_log(LOG_DEBUG, "Dropping frame from %s (callno %d) of type %d (subclass %d) due to frame of type %d (subclass %d) already in process\n",
-				ast_inet_ntoa(thread->iosin.sin_addr), cur->ffinfo.callno,
-				fh->type, uncompress_subclass(fh->csub),
-				cur->ffinfo.type, uncompress_subclass(cur->ffinfo.csub));
-			insert_idle_thread(thread);
+			   so queue it up for processing later. */
+			defer_full_frame(thread);
 			return 1;
 		} else {
 			/* this thread is going to process this frame, so mark it */
@@ -7806,7 +7865,9 @@
 		case IAX_IOSTATE_READY:
 			thread->actions++;
 			thread->iostate = IAX_IOSTATE_PROCESSING;
-			socket_process(thread);
+			do {
+				socket_process(thread);
+			} while (check_deferred_full_frames(thread));
 			break;
 		case IAX_IOSTATE_SCHEDREADY:
 			thread->actions++;




More information about the asterisk-commits mailing list