chiark / gitweb /
+ * bug_if_query_done feature for debugging (SHOULD BE TAKEN OUT FOR RELEASE)
[adns.git] / src / event.c
index a1641c630a1d0307d62fffc6f6e6c61e39a3844d..b82b5de397d9a9e7eeb9f007cc01c41a0d7fe33d 100644 (file)
@@ -143,6 +143,17 @@ void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
   return;
 }
 
+static void inter_immed(struct timeval **tv_io, struct timeval *tvbuf) {
+  struct timeval *rbuf;
+
+  if (!tv_io) return;
+
+  rbuf= *tv_io;
+  if (!rbuf) { *tv_io= rbuf= tvbuf; }
+
+  timerclear(rbuf);
+}
+    
 static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf,
                        struct timeval maxto) {
   struct timeval *rbuf;
@@ -185,12 +196,7 @@ static void timeouts_queue(adns_state ads, int act,
     if (!timercmp(&now,&qu->timeout,>)) {
       inter_maxtoabs(tv_io,tvbuf,now,qu->timeout);
     } else {
-      if (!act) {
-       tvbuf->tv_sec= 0;
-       tvbuf->tv_usec= 0;
-       *tv_io= tvbuf;
-       return;
-      }
+      if (!act) { inter_immed(tv_io,tvbuf); return; }
       LIST_UNLINK(*queue,qu);
       if (qu->state != query_tosend) {
        adns__query_fail(qu,adns_s_timeout);
@@ -210,6 +216,7 @@ static void tcp_events(adns_state ads, int act,
   for (;;) {
     switch (ads->tcpstate) {
     case server_broken:
+      if (!act) { inter_immed(tv_io,tvbuf); return; }
       for (qu= ads->tcpw.head; qu; qu= nqu) {
        nqu= qu->next;
        assert(qu->state == query_tcpw);
@@ -221,6 +228,7 @@ static void tcp_events(adns_state ads, int act,
       ads->tcpstate= server_disconnected;
     case server_disconnected: /* fall through */
       if (!ads->tcpw.head) return;
+      if (!act) { inter_immed(tv_io,tvbuf); return; }
       adns__tcp_tryconnect(ads,now);
       break;
     case server_ok:
@@ -231,7 +239,7 @@ static void tcp_events(adns_state ads, int act,
        timevaladd(&ads->tcptimeout,TCPIDLEMS);
       }
     case server_connecting: /* fall through */
-      if (!timercmp(&now,&ads->tcptimeout,>)) {
+      if (!act || !timercmp(&now,&ads->tcptimeout,>)) {
        inter_maxtoabs(tv_io,tvbuf,now,ads->tcptimeout);
        return;
       } {
@@ -253,6 +261,7 @@ static void tcp_events(adns_state ads, int act,
       abort();
     }
   }
+  return;
 }
 
 void adns__timeouts(adns_state ads, int act,
@@ -531,7 +540,7 @@ void adns_beforeselect(adns_state ads, int *maxfd_io, fd_set *readfds_io,
   if (tv_mod && (!*tv_mod || (*tv_mod)->tv_sec || (*tv_mod)->tv_usec)) {
     /* The caller is planning to sleep. */
     adns__must_gettimeofday(ads,&now,&tv_nowbuf);
-    if (!now) goto xit;
+    if (!now) { inter_immed(tv_mod,tv_tobuf); goto xit; }
     adns__timeouts(ads, 1, tv_mod,tv_tobuf, *now);
   }
 
@@ -664,7 +673,10 @@ int adns_wait(adns_state ads,
     if (r != EAGAIN) break;
     maxfd= 0; tvp= 0;
     FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
+    ads->bug_if_query_done_now= 1;
     adns_beforeselect(ads,&maxfd,&readfds,&writefds,&exceptfds,&tvp,&tvbuf,0);
+    ads->bug_if_query_done_now= 0;
+    assert(tvp);
     rsel= select(maxfd,&readfds,&writefds,&exceptfds,tvp);
     if (rsel==-1) {
       if (errno == EINTR) {