[MINOR] add an expiration flag to the stream_sock_interface

This expiration flag is used to indicate that the timer has
expired without having to check it everywhere.
diff --git a/include/proto/stream_sock.h b/include/proto/stream_sock.h
index d005be5..7a2dd3d 100644
--- a/include/proto/stream_sock.h
+++ b/include/proto/stream_sock.h
@@ -33,11 +33,11 @@
 /* main event functions used to move data between sockets and buffers */
 int stream_sock_read(int fd);
 int stream_sock_write(int fd);
-int stream_sock_data_check_timeouts(int fd);
 int stream_sock_data_update(int fd);
 int stream_sock_data_finish(int fd);
 int stream_sock_shutr(struct stream_interface *si);
 int stream_sock_shutw(struct stream_interface *si);
+int stream_sock_check_timeouts(struct stream_interface *si);
 
 
 /* This either returns the sockname or the original destination address. Code
diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h
index ba8d7a7..ba1a36d 100644
--- a/include/types/stream_interface.h
+++ b/include/types/stream_interface.h
@@ -56,11 +56,18 @@
 	SI_ET_DATA_ABRT  = 0x0200,  /* data phase aborted by external cause */
 };
 
+/* flags set after I/O */
+enum {
+	SI_FL_NONE       = 0x0000,  /* nothing */
+	SI_FL_EXP        = 0x0001,  /* timeout has expired */
+};
+
 struct stream_interface {
 	unsigned int state;     /* SI_ST* */
 	unsigned int prev_state;/* SI_ST*, copy of previous state */
 	void *owner;            /* generally a (struct task*) */
 	int fd;                 /* file descriptor for a stream driver when known */
+	unsigned int flags;     /* SI_FL_*, must be cleared before I/O */
 	unsigned int exp;       /* wake up time for connect, queue, turn-around, ... */
 	int (*shutr)(struct stream_interface *);  /* shutr function */
 	int (*shutw)(struct stream_interface *);  /* shutw function */
diff --git a/src/client.c b/src/client.c
index 547e215..d56a33e 100644
--- a/src/client.c
+++ b/src/client.c
@@ -177,6 +177,7 @@
 		s->si[0].shutr = stream_sock_shutr;
 		s->si[0].shutw = stream_sock_shutw;
 		s->si[0].fd = cfd;
+		s->si[0].flags = SI_FL_NONE;
 		s->si[0].exp = TICK_ETERNITY;
 		s->cli_fd = cfd;
 
@@ -188,6 +189,7 @@
 		s->si[1].shutw = stream_sock_shutw;
 		s->si[1].exp = TICK_ETERNITY;
 		s->si[1].fd = -1; /* just to help with debugging */
+		s->si[1].flags = SI_FL_NONE;
 
 		s->srv = s->prev_srv = s->srv_conn = NULL;
 		s->pend_pos = NULL;
diff --git a/src/proto_http.c b/src/proto_http.c
index d5760ae..9b3d0bc 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -659,10 +659,12 @@
 	unsigned int rqf_cli, rpf_cli;
 	unsigned int rqf_srv, rpf_srv;
 
-	/* Check timeouts only during data phase for now */
+	/* 1: Check timeouts only during data phase for now */
 	if (unlikely(t->state & TASK_WOKEN_TIMER)) {
 		buffer_check_timeouts(s->req);
 		buffer_check_timeouts(s->rep);
+		stream_sock_check_timeouts(&s->si[0]);
+		stream_sock_check_timeouts(&s->si[1]);
 
 		if (unlikely(s->req->flags & (BF_READ_TIMEOUT|BF_WRITE_TIMEOUT))) {
 			if (s->req->flags & BF_READ_TIMEOUT) {
@@ -690,7 +692,7 @@
 		 */
 	}
 
-	/* Check if we need to close the write side. This can only happen
+	/* 2: Check if we need to close the write side. This can only happen
 	 * when either SHUTR or EMPTY appears, because WRITE_ENA cannot appear
 	 * from low level, and neither HIJACK nor SHUTW can disappear from low
 	 * level.
@@ -705,7 +707,7 @@
 		s->rep->cons->shutw(s->rep->cons);
 	}
 
-	/* When a server-side connection is released, we have to
+	/* 3: When a server-side connection is released, we have to
 	 * count it and check for pending connections on this server.
 	 */
 	if (unlikely(s->req->cons->state == SI_ST_CLO &&
@@ -907,6 +909,7 @@
 		s->rep->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
 		s->si[0].prev_state = s->si[0].state;
 		s->si[1].prev_state = s->si[1].state;
+		s->si[0].flags = s->si[1].flags = 0;
 
 		/* Trick: if a request is being waiting for the server to respond,
 		 * and if we know the server can timeout, we don't want the timeout
diff --git a/src/stream_sock.c b/src/stream_sock.c
index efc33a6..3418e98 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -534,56 +534,17 @@
 }
 
 /*
- * This function only has to be called once after a wakeup event during a data
- * phase. It controls the file descriptor's status, as well as read and write
- * timeouts.
+ * This function only has to be called once after a wakeup event in case of
+ * suspected timeout. It controls the stream interface timeouts and sets
+ * si->flags accordingly. It does NOT close anything, as this timeout may
+ * be used for any purpose. It returns 1 if the timeout fired, otherwise
+ * zero.
  */
-int stream_sock_data_check_timeouts(int fd)
+int stream_sock_check_timeouts(struct stream_interface *si)
 {
-	struct buffer *ib = fdtab[fd].cb[DIR_RD].b;
-	struct buffer *ob = fdtab[fd].cb[DIR_WR].b;
-
-	DPRINTF(stderr,"[%u] %s: fd=%d owner=%p ib=%p, ob=%p, exp(r,w)=%u,%u ibf=%08x obf=%08x ibl=%d obl=%d\n",
-		now_ms, __FUNCTION__,
-		fd, fdtab[fd].owner,
-		ib, ob,
-		ib->rex, ob->wex,
-		ib->flags, ob->flags,
-		ib->l, ob->l);
-
-	/* Read timeout */
-	if (unlikely(!(ib->flags & (BF_SHUTR|BF_READ_TIMEOUT)) && tick_is_expired(ib->rex, now_ms))) {
-		//trace_term(t, TT_HTTP_SRV_12);
-		ib->flags |= BF_READ_TIMEOUT;
-		if (!ob->cons->err_type) {
-			//ob->cons->err_loc = t->srv;
-			ob->cons->err_type = SI_ET_DATA_TO;
-		}
-		buffer_shutr(ib);
-		if (ob->flags & BF_SHUTW) {
-		do_close_and_return:
-			fd_delete(fd);
-			ob->cons->state = SI_ST_CLO;
-			return 0;
-		}
-
-		EV_FD_CLR(fd, DIR_RD);
-	}
-
-	/* Write timeout */
-	if (unlikely(!(ob->flags & (BF_SHUTW|BF_WRITE_TIMEOUT)) && tick_is_expired(ob->wex, now_ms))) {
-		//trace_term(t, TT_HTTP_SRV_13);
-		ob->flags |= BF_WRITE_TIMEOUT;
-		if (!ob->cons->err_type) {
-			//ob->cons->err_loc = t->srv;
-			ob->cons->err_type = SI_ET_DATA_TO;
-		}
-		buffer_shutw(ob);
-		if (ib->flags & BF_SHUTR)
-			goto do_close_and_return;
-
-		EV_FD_CLR(fd, DIR_WR);
-		shutdown(fd, SHUT_WR);
+	if (tick_is_expired(si->exp, now_ms)) {
+		si->flags |= SI_FL_EXP;
+		return 1;
 	}
 	return 0;
 }