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;
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);
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);
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:
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;
} {
abort();
}
}
+ return;
}
void adns__timeouts(adns_state ads, int act,
switch (ads->tcpstate) {
case server_disconnected:
+ case server_broken:
return 1;
case server_connecting:
pollfds_buf[1].events= POLLOUT;
case server_ok:
if (fd != ads->tcpsocket) break;
assert(!ads->tcprecv_skip);
- for (;;) {
+ do {
if (ads->tcprecv.used >= ads->tcprecv_skip+2) {
dgramlen= ((ads->tcprecv.buf[ads->tcprecv_skip]<<8) |
ads->tcprecv.buf[ads->tcprecv_skip+1]);
if (errno_resources(errno)) { r= errno; goto xit; }
}
adns__tcp_broken(ads,"read",r?strerror(errno):"closed");
- r= 0; goto xit;
}
- } /* never reached */
+ } while (ads->tcpstate == server_ok);
+ r= 0; goto xit;
default:
abort();
}
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;
- adns__timeouts(ads, 1, tv_mod,tv_tobuf, *now);
+ if (!now) { inter_immed(tv_mod,tv_tobuf); goto xit; }
+ adns__timeouts(ads, 0, tv_mod,tv_tobuf, *now);
}
npollfds= adns__pollfds(ads,pollfds);
maxfd= 0; tvp= 0;
FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
adns_beforeselect(ads,&maxfd,&readfds,&writefds,&exceptfds,&tvp,&tvbuf,0);
+ assert(tvp);
rsel= select(maxfd,&readfds,&writefds,&exceptfds,tvp);
if (rsel==-1) {
if (errno == EINTR) {