Module: sip-router Branch: master Commit: dda6ba602c251def193f3b9f7a7534b78a7f6556 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=dda6ba60...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@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(