[SR-Dev] git:master: tcp: async write timeout fixes

Jan Janak jan at iptel.org
Fri Feb 27 23:32:59 CET 2009


Module: sip-router
Branch: master
Commit: dda6ba602c251def193f3b9f7a7534b78a7f6556
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=dda6ba602c251def193f3b9f7a7534b78a7f6556

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Thu Feb 26 23:13:44 2009 +0000

tcp: async write timeout fixes

- fixed a wrong write timeout test on connection-read-release
 (TICKS_LE instead of TICKS_GE)

- fixed initial write timeout after connection creation (the
  timeout was ended up set to tcp_con_lifetime instead of
  tcp_wq_timeout)

---

 tcp_main.c |   36 +++++++++++++++++++++++++++---------
 1 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/tcp_main.c b/tcp_main.c
index 82be36c..d9dd7f8 100644
--- a/tcp_main.c
+++ b/tcp_main.c
@@ -2661,7 +2661,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
 #ifdef TCP_BUF_WRITE
 			if (unlikely(tcp_options.tcp_buf_write && 
 							_wbufq_non_empty(tcpconn) )){
-				if (unlikely(TICKS_LE(t, tcpconn->wbuf_q.wr_timeout))){
+				if (unlikely(TICKS_GE(t, tcpconn->wbuf_q.wr_timeout))){
 					DBG("handle_tcp_child: wr. timeout on CONN_RELEASE for %p "
 							"refcnt= %d\n", tcpconn,
 							atomic_get(&tcpconn->refcnt));
@@ -2772,6 +2772,9 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
 	int fd;
 	int flags;
 	ticks_t t;
+#ifdef TCP_BUF_WRITE
+	ticks_t nxt_timeout;
+#endif /* TCP_BUF_WRITE */
 	
 	ret=-1;
 	if (unlikely(p->unix_sock<=0)){
@@ -2993,11 +2996,7 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
 			/* update the timeout*/
 			t=get_ticks_raw();
 			tcpconn->timeout=t+tcp_con_lifetime;
-			/* activate the timer (already properly init. in tcpconn_new())
-			 * no need for reinit */
-			local_timer_add(&tcp_main_ltimer, &tcpconn->timer, 
-								tcp_con_lifetime, t);
-			tcpconn->flags|=F_CONN_MAIN_TIMER|F_CONN_READ_W|F_CONN_WANTS_RD;
+			nxt_timeout=tcp_con_lifetime;
 			if (unlikely(cmd==CONN_NEW_COMPLETE)){
 				tcpconn->state=S_CONN_OK;
 				/* check if needs to be watched for write */
@@ -3005,8 +3004,18 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
 					/* if queue non empty watch it for write */
 					flags=(_wbufq_empty(tcpconn)-1)&POLLOUT;
 				lock_release(&tcpconn->write_lock);
-				tcpconn->flags|=(!(flags&POLLOUT)-1)&
-									(F_CONN_WRITE_W|F_CONN_WANTS_WR);
+				if (flags){
+					if (TICKS_LT(tcpconn->wbuf_q.wr_timeout, tcpconn->timeout)
+							&& TICKS_LT(t, tcpconn->wbuf_q.wr_timeout))
+						nxt_timeout=tcpconn->wbuf_q.wr_timeout-t;
+					tcpconn->flags|=F_CONN_WRITE_W|F_CONN_WANTS_WR;
+				}
+				/* activate the timer (already properly init. in 
+				   tcpconn_new())  no need for reinit */
+				local_timer_add(&tcp_main_ltimer, &tcpconn->timer, nxt_timeout,
+									t);
+				tcpconn->flags|=F_CONN_MAIN_TIMER|F_CONN_READ_W| 
+								F_CONN_WANTS_RD;
 			}else{
 				/* CONN_NEW_PENDING_WRITE */
 				/* we don't know if we successfully sent anything, but
@@ -3015,7 +3024,16 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
 				tcpconn->state=S_CONN_CONNECT;
 				/* no need to check, we have something queued for write */
 				flags=POLLOUT;
-				tcpconn->flags|=(F_CONN_WRITE_W|F_CONN_WANTS_WR);
+				if (TICKS_LT(tcpconn->wbuf_q.wr_timeout, tcpconn->timeout)
+						&& TICKS_LT(t, tcpconn->wbuf_q.wr_timeout))
+					nxt_timeout=tcpconn->wbuf_q.wr_timeout-t;
+				/* activate the timer (already properly init. in 
+				   tcpconn_new())  no need for reinit */
+				local_timer_add(&tcp_main_ltimer, &tcpconn->timer, nxt_timeout,
+									t);
+				tcpconn->flags|=F_CONN_MAIN_TIMER|F_CONN_READ_W| 
+								F_CONN_WANTS_RD |
+								F_CONN_WRITE_W|F_CONN_WANTS_WR;
 			}
 			flags|=POLLIN;
 			if (unlikely(




More information about the sr-dev mailing list