[svn-commits] mmichelson: branch mmichelson/timeout_fixes r373943 - /team/mmichelson/timeou...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Sep 27 15:38:19 CDT 2012


Author: mmichelson
Date: Thu Sep 27 15:38:15 2012
New Revision: 373943

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=373943
Log:
Fix timing errors in the main directory.


Modified:
    team/mmichelson/timeout_fixes/main/channel.c
    team/mmichelson/timeout_fixes/main/pbx.c
    team/mmichelson/timeout_fixes/main/rtp_engine.c

Modified: team/mmichelson/timeout_fixes/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/timeout_fixes/main/channel.c?view=diff&rev=373943&r1=373942&r2=373943
==============================================================================
--- team/mmichelson/timeout_fixes/main/channel.c (original)
+++ team/mmichelson/timeout_fixes/main/channel.c Thu Sep 27 15:38:15 2012
@@ -1836,11 +1836,12 @@
 }
 
 /*! \brief Wait, look for hangups and condition arg */
-int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int (*cond)(void*), void *data)
+int ast_safe_sleep_conditional(struct ast_channel *chan, int timeout_ms, int (*cond)(void*), void *data)
 {
 	struct ast_frame *f;
 	struct ast_silence_generator *silgen = NULL;
 	int res = 0;
+	struct timeval start;
 	AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
 
 	AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
@@ -1850,22 +1851,26 @@
 		silgen = ast_channel_start_silence_generator(chan);
 	}
 
-	while (ms > 0) {
+	start = ast_tvnow();
+	while (ast_tvdiff_ms(ast_tvnow(), start) < timeout_ms) {
 		struct ast_frame *dup_f = NULL;
+		int ms = ast_remaining_ms(start, timeout_ms);
+
 		if (cond && ((*cond)(data) == 0)) {
 			break;
 		}
-		ms = ast_waitfor(chan, ms);
-		if (ms < 0) {
-			res = -1;
+		res = ast_waitfor(chan, ms);
+		if (res < 0) {
 			break;
 		}
-		if (ms > 0) {
+		if (res > 0) {
 			f = ast_read(chan);
 			if (!f) {
 				res = -1;
 				break;
 			}
+
+			res = 0;
 
 			if (!ast_is_deferrable_frame(f)) {
 				ast_frfree(f);
@@ -2987,19 +2992,21 @@
 		do {
 			AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
 			struct ast_frame *cur, *new;
-			int ms = MAX(delay, 500);
+			int timeout_ms = MAX(delay, 500);
 			unsigned int done = 0;
+			struct timeval start;
 
 			AST_LIST_HEAD_INIT_NOLOCK(&frames);
 
+			start = ast_tvnow();
 			for (;;) {
-				ms = ast_waitfor(chan, ms);
-				if (ms < 0) {
+				int ms = ast_remaining_ms(start, timeout_ms);
+				res = ast_waitfor(chan, ms);
+				if (res < 0) {
 					ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno));
-					res = -1;
 					break;
 				}
-				if (ms == 0) {
+				if (res == 0) {
 					ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500));
 					break;
 				}
@@ -4581,15 +4588,16 @@
 {
 	int res, done = 0;
 	char *buf = NULL;
+	struct timeval start = ast_tvnow();
 	
 	while (!done) {
 		struct ast_frame *f;
+		int ms = ast_remaining_ms(start, timeout);
 		if (ast_check_hangup(chan))
 			break;
-		res = ast_waitfor(chan, timeout);
+		res = ast_waitfor(chan, ms);
 		if (res <= 0) /* timeout or error */
 			break;
-		timeout = res;	/* update timeout */
 		f = ast_read(chan);
 		if (f == NULL)
 			break; /* no frame */
@@ -5437,18 +5445,19 @@
 	if (ast_call(chan, data, 0)) {	/* ast_call failed... */
 		ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
 	} else {
+		struct timeval start = ast_tvnow();
 		res = 1;	/* mark success in case chan->_state is already AST_STATE_UP */
 		while (timeout && chan->_state != AST_STATE_UP) {
 			struct ast_frame *f;
-			res = ast_waitfor(chan, timeout);
+			int ms = ast_remaining_ms(start, timeout);
+
+			res = ast_waitfor(chan, ms);
 			if (res == 0) { /* timeout, treat it like ringing */
 				*outstate = AST_CONTROL_RINGING;
 				break;
 			}
 			if (res < 0) /* error or done */
 				break;
-			if (timeout > -1)
-				timeout = res;
 			if (!ast_strlen_zero(chan->call_forward)) {
 				if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) {
 					return NULL;

Modified: team/mmichelson/timeout_fixes/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/timeout_fixes/main/pbx.c?view=diff&rev=373943&r1=373942&r2=373943
==============================================================================
--- team/mmichelson/timeout_fixes/main/pbx.c (original)
+++ team/mmichelson/timeout_fixes/main/pbx.c Thu Sep 27 15:38:15 2012
@@ -8718,13 +8718,16 @@
 	int res;
 	struct ast_frame *f;
 	struct ast_app *app;
-
-	while (timeout && (chan->_state != AST_STATE_UP)) {
-		res = ast_waitfor(chan, timeout);
+	struct timeval start = ast_tvnow();
+
+	while ((ast_tvdiff_ms(ast_tvnow(), start) < timeout || timeout < 0) &&
+			chan->_state != AST_STATE_UP) {
+		int ms = ast_remaining_ms(start, timeout);
+
+		res = ast_waitfor(chan, ms);
 		if (res < 1)
 			break;
-		if (timeout > -1)
-			timeout = res;
+
 		f = ast_read(chan);
 		if (!f)
 			break;

Modified: team/mmichelson/timeout_fixes/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/timeout_fixes/main/rtp_engine.c?view=diff&rev=373943&r1=373942&r2=373943
==============================================================================
--- team/mmichelson/timeout_fixes/main/rtp_engine.c (original)
+++ team/mmichelson/timeout_fixes/main/rtp_engine.c Thu Sep 27 15:38:15 2012
@@ -810,6 +810,7 @@
 	enum ast_bridge_result res = AST_BRIDGE_FAILED;
 	struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, };
 	struct ast_frame *fr = NULL;
+	struct timeval start;
 
 	/* Start locally bridging both instances */
 	if (instance0->engine->local_bridge && instance0->engine->local_bridge(instance0, instance1)) {
@@ -840,7 +841,9 @@
 	cs[0] = c0;
 	cs[1] = c1;
 	cs[2] = NULL;
+	start = ast_tvnow();
 	for (;;) {
+		int ms;
 		/* If the underlying formats have changed force this bridge to break */
 		if ((c0->rawreadformat != c1->rawwriteformat) || (c1->rawreadformat != c0->rawwriteformat)) {
 			ast_debug(1, "rtp-engine-local-bridge: Oooh, formats changed, backing out\n");
@@ -865,8 +868,9 @@
 			break;
 		}
 		/* Wait on a channel to feed us a frame */
-		if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
-			if (!timeoutms) {
+		ms = ast_remaining_ms(start, timeoutms);
+		if (!(who = ast_waitfor_n(cs, 2, &ms))) {
+			if (!ms) {
 				res = AST_BRIDGE_RETRY;
 				break;
 			}
@@ -985,6 +989,7 @@
 	struct ast_sockaddr ac1 = {{0,}}, vac1 = {{0,}}, tac1 = {{0,}}, ac0 = {{0,}}, vac0 = {{0,}}, tac0 = {{0,}};
 	struct ast_sockaddr t1 = {{0,}}, vt1 = {{0,}}, tt1 = {{0,}}, t0 = {{0,}}, vt0 = {{0,}}, tt0 = {{0,}};
 	struct ast_frame *fr = NULL;
+	struct timeval start;
 
 	/* Test the first channel */
 	if (!(glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0))) {
@@ -1024,7 +1029,9 @@
 	cs[0] = c0;
 	cs[1] = c1;
 	cs[2] = NULL;
+	start = ast_tvnow();
 	for (;;) {
+		int ms;
 		/* Check if anything changed */
 		if ((c0->tech_pvt != pvt0) ||
 		    (c1->tech_pvt != pvt1) ||
@@ -1115,9 +1122,10 @@
 			oldcodec0 = codec0;
 		}
 
+		ms = ast_remaining_ms(start, timeoutms);
 		/* Wait for frame to come in on the channels */
-		if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
-			if (!timeoutms) {
+		if (!(who = ast_waitfor_n(cs, 2, &ms))) {
+			if (!ms) {
 				res = AST_BRIDGE_RETRY;
 				break;
 			}




More information about the svn-commits mailing list