[MEDIUM] implement and use tv_cmp2_le instead of tv_cmp2_ms
tv_cmp2_ms handles multiple combinations of tv1 and tv2, but only
one form is used: (tv1 <= tv2). So it is overkill to use it everywhere.
A new function designed to do exactly this has been written for that
purpose: tv_cmp2_le. Also, removed old unused tv_* functions.
diff --git a/include/common/time.h b/include/common/time.h
index cb1e40b..3d81759 100644
--- a/include/common/time.h
+++ b/include/common/time.h
@@ -59,22 +59,18 @@
REGPRM2 int tv_cmp_ms(const struct timeval *tv1, const struct timeval *tv2);
/*
- * compares <tv1> and <tv2> : returns 0 if tv1 < tv2, 1 if tv1 >= tv2,
- * considering that 0 is the eternity.
- */
-REGPRM2 int tv_cmp_ge2(const struct timeval *tv1, const struct timeval *tv2);
-
-/*
- * compares <tv1> and <tv2> : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
- * considering that 0 is the eternity.
+ * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
+ * assuming that TV_ETERNITY is greater than everything.
*/
-REGPRM2 int tv_cmp2(const struct timeval *tv1, const struct timeval *tv2);
+REGPRM2 int tv_cmp2_ms(const struct timeval *tv1, const struct timeval *tv2);
/*
- * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
- * considering that 0 is the eternity.
+ * compares <tv1> and <tv2> modulo 1 ms: returns 1 if tv1 <= tv2, 0 if tv1 > tv2,
+ * assuming that TV_ETERNITY is greater than everything. Returns 0 if tv1 is
+ * TV_ETERNITY, and always assumes that tv2 != TV_ETERNITY. Designed to replace
+ * occurrences of (tv_cmp2_ms(tv,now) <= 0).
*/
-REGPRM2 int tv_cmp2_ms(const struct timeval *tv1, const struct timeval *tv2);
+REGPRM2 int tv_cmp2_le(const struct timeval *tv1, const struct timeval *tv2);
/*
* returns the remaining time between tv1=now and event=tv2
@@ -93,7 +89,6 @@
/*
* compares <tv1> and <tv2> : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2
- * Must not be used when either argument is eternity. Use tv_cmp2() for that.
*/
REGPRM2 static inline int tv_cmp(const struct timeval *tv1, const struct timeval *tv2)
{
diff --git a/src/proto_http.c b/src/proto_http.c
index 86dbc99..492d8b8 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1525,7 +1525,7 @@
}
/* 3: has the read timeout expired ? */
- else if (unlikely(tv_cmp2_ms(&req->rex, &now) <= 0)) {
+ else if (unlikely(tv_cmp2_le(&req->rex, &now))) {
/* read timeout : give up with an error message. */
txn->status = 408;
client_retnclose(t, error_message(t, HTTP_ERR_408));
@@ -1980,7 +1980,7 @@
return 1;
}
/* read timeout */
- else if (tv_cmp2_ms(&req->rex, &now) <= 0) {
+ else if (tv_cmp2_le(&req->rex, &now)) {
EV_FD_CLR(t->cli_fd, DIR_RD);
tv_eternity(&req->rex);
t->cli_state = CL_STSHUTR;
@@ -1997,7 +1997,7 @@
return 1;
}
/* write timeout */
- else if (tv_cmp2_ms(&rep->wex, &now) <= 0) {
+ else if (tv_cmp2_le(&rep->wex, &now)) {
EV_FD_CLR(t->cli_fd, DIR_WR);
tv_eternity(&rep->wex);
shutdown(t->cli_fd, SHUT_WR);
@@ -2089,7 +2089,7 @@
t->cli_state = CL_STCLOSE;
return 1;
}
- else if (tv_cmp2_ms(&rep->wex, &now) <= 0) {
+ else if (tv_cmp2_le(&rep->wex, &now)) {
tv_eternity(&rep->wex);
fd_delete(t->cli_fd);
t->cli_state = CL_STCLOSE;
@@ -2161,7 +2161,7 @@
t->cli_state = CL_STCLOSE;
return 1;
}
- else if (tv_cmp2_ms(&req->rex, &now) <= 0) {
+ else if (tv_cmp2_le(&req->rex, &now)) {
tv_eternity(&req->rex);
fd_delete(t->cli_fd);
t->cli_state = CL_STCLOSE;
@@ -2258,7 +2258,7 @@
* already set the connect expiration date to the right
* timeout. We just have to check that it has not expired.
*/
- if (tv_cmp2_ms(&req->cex, &now) > 0)
+ if (!tv_cmp2_le(&req->cex, &now))
return 0;
/* We will set the queue timer to the time spent, just for
@@ -2280,7 +2280,7 @@
* to any other session to release it and wake us up again.
*/
if (t->pend_pos) {
- if (tv_cmp2_ms(&req->cex, &now) > 0)
+ if (!tv_cmp2_le(&req->cex, &now))
return 0;
else {
/* we've been waiting too long here */
@@ -2325,7 +2325,7 @@
srv_close_with_err(t, SN_ERR_CLICL, SN_FINST_C, 0, NULL);
return 1;
}
- if (!(req->flags & BF_WRITE_STATUS) && tv_cmp2_ms(&req->cex, &now) > 0) {
+ if (!(req->flags & BF_WRITE_STATUS) && !tv_cmp2_le(&req->cex, &now)) {
//fprintf(stderr,"1: c=%d, s=%d, now=%d.%06d, exp=%d.%06d\n", c, s, now.tv_sec, now.tv_usec, req->cex.tv_sec, req->cex.tv_usec);
return 0; /* nothing changed */
}
@@ -2560,7 +2560,7 @@
/* read timeout : return a 504 to the client.
*/
else if (unlikely(EV_FD_ISSET(t->srv_fd, DIR_RD) &&
- tv_cmp2_ms(&rep->rex, &now) <= 0)) {
+ tv_cmp2_le(&rep->rex, &now))) {
tv_eternity(&rep->rex);
tv_eternity(&req->wex);
fd_delete(t->srv_fd);
@@ -2614,7 +2614,7 @@
* some work to do on the headers.
*/
else if (unlikely(EV_FD_ISSET(t->srv_fd, DIR_WR) &&
- tv_cmp2_ms(&req->wex, &now) <= 0)) {
+ tv_cmp2_le(&req->wex, &now))) {
EV_FD_CLR(t->srv_fd, DIR_WR);
tv_eternity(&req->wex);
shutdown(t->srv_fd, SHUT_WR);
@@ -3014,7 +3014,7 @@
return 1;
}
/* read timeout */
- else if (tv_cmp2_ms(&rep->rex, &now) <= 0) {
+ else if (tv_cmp2_le(&rep->rex, &now)) {
EV_FD_CLR(t->srv_fd, DIR_RD);
tv_eternity(&rep->rex);
t->srv_state = SV_STSHUTR;
@@ -3025,7 +3025,7 @@
return 1;
}
/* write timeout */
- else if (tv_cmp2_ms(&req->wex, &now) <= 0) {
+ else if (tv_cmp2_le(&req->wex, &now)) {
EV_FD_CLR(t->srv_fd, DIR_WR);
tv_eternity(&req->wex);
shutdown(t->srv_fd, SHUT_WR);
@@ -3120,7 +3120,7 @@
return 1;
}
- else if (tv_cmp2_ms(&req->wex, &now) <= 0) {
+ else if (tv_cmp2_le(&req->wex, &now)) {
//EV_FD_CLR(t->srv_fd, DIR_WR);
tv_eternity(&req->wex);
fd_delete(t->srv_fd);
@@ -3201,7 +3201,7 @@
return 1;
}
- else if (tv_cmp2_ms(&rep->rex, &now) <= 0) {
+ else if (tv_cmp2_le(&rep->rex, &now)) {
//EV_FD_CLR(t->srv_fd, DIR_RD);
tv_eternity(&rep->rex);
fd_delete(t->srv_fd);
diff --git a/src/time.c b/src/time.c
index d94e364..c146504 100644
--- a/src/time.c
+++ b/src/time.c
@@ -62,39 +62,6 @@
}
/*
- * compares <tv1> and <tv2> : returns 0 if tv1 < tv2, 1 if tv1 >= tv2,
- * assuming that TV_ETERNITY is greater than everything.
- */
-REGPRM2 int tv_cmp_ge2(const struct timeval *tv1, const struct timeval *tv2)
-{
- if ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec)
- return 1;
- if ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec)
- return 0;
- if ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec)
- return 1;
- return 0;
-}
-
-/*
- * compares <tv1> and <tv2> : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
- * assuming that TV_ETERNITY is greater than everything.
- */
-REGPRM2 int tv_cmp2(const struct timeval *tv1, const struct timeval *tv2)
-{
- if ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec)
- return 1;
- else if ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec)
- return -1;
- else if ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec)
- return 1;
- else if ((unsigned)tv1->tv_usec < (unsigned)tv2->tv_usec)
- return -1;
- else
- return 0;
-}
-
-/*
* compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
* assuming that TV_ETERNITY is greater than everything.
*/
@@ -126,6 +93,34 @@
return -1;
else
return 0;
+}
+
+/*
+ * compares <tv1> and <tv2> modulo 1 ms: returns 1 if tv1 <= tv2, 0 if tv1 > tv2,
+ * assuming that TV_ETERNITY is greater than everything. Returns 0 if tv1 is
+ * TV_ETERNITY, and always assumes that tv2 != TV_ETERNITY. Designed to replace
+ * occurrences of (tv_cmp2_ms(tv,now) <= 0).
+ */
+REGPRM2 int tv_cmp2_le(const struct timeval *tv1, const struct timeval *tv2)
+{
+ if (likely((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1))
+ return 0;
+
+ if (likely((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec))
+ return 1;
+
+ if (likely((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec)) {
+ if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000)
+ return 1;
+ else
+ return 0;
+ }
+
+ if (unlikely(((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) &&
+ ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000)))
+ return 0;
+ else
+ return 1;
}
/*