X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=blobdiff_plain;f=src%2Fevent.c;h=88e5d03077bd17fe2e73234fb9ca8586fcecae99;hp=48970c8b89fae9aa44bb62b6c0128c2a5c47fd54;hb=0544e0de19b492a0cda3b65584f9822ba36e50fc;hpb=f7f83b4a88b5168130a7bb9cb3d3811eb8c1c260 diff --git a/src/event.c b/src/event.c index 48970c8..88e5d03 100644 --- a/src/event.c +++ b/src/event.c @@ -6,10 +6,10 @@ */ /* * This file is - * Copyright (C) 1997-1999 Ian Jackson + * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is - * Copyright (C) 1997-1999 Ian Jackson + * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999 Tony Finch * * This program is free software; you can redistribute it and/or modify @@ -39,6 +39,7 @@ #include #include "internal.h" +#include "tvarith.h" /* TCP connection management. */ @@ -142,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; @@ -184,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); @@ -209,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); @@ -220,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: @@ -230,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; } { @@ -252,6 +261,7 @@ static void tcp_events(adns_state ads, int act, abort(); } } + return; } void adns__timeouts(adns_state ads, int act, @@ -294,6 +304,7 @@ int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]) { switch (ads->tcpstate) { case server_disconnected: + case server_broken: return 1; case server_connecting: pollfds_buf[1].events= POLLOUT; @@ -322,7 +333,7 @@ int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { 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]); @@ -356,9 +367,9 @@ int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { 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(); } @@ -530,8 +541,8 @@ 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; - 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); @@ -608,7 +619,7 @@ int adns_processany(adns_state ads) { * likely just to want to do a read on one or two fds anyway. */ npollfds= adns__pollfds(ads,pollfds); - for (i=0; i