diff --git a/src/Makefile.in b/src/Makefile.in index bccaac04..a10d04c8 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -308,7 +308,8 @@ context.lo context.o: $(srcdir)/context.c config.h \ $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/platform.h $(srcdir)/dnssec.h \ $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h -convert.lo convert.o: $(srcdir)/convert.c config.h \ +convert.lo convert.o: $(srcdir)/convert.c \ + config.h \ getdns/getdns.h \ getdns/getdns_extra.h \ $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ @@ -354,7 +355,7 @@ general.lo general.o: $(srcdir)/general.c config.h \ $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \ - $(srcdir)/dict.h $(srcdir)/mdns.h $(srcdir)/platform.h $(srcdir)/debug.h + $(srcdir)/dict.h $(srcdir)/mdns.h $(srcdir)/platform.h list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \ getdns/getdns.h \ getdns/getdns_extra.h \ @@ -422,8 +423,9 @@ server.lo server.o: $(srcdir)/server.c config.h \ $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/platform.h -stub.lo stub.o: $(srcdir)/stub.c config.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/util-internal.h $(srcdir)/platform.h +stub.lo stub.o: $(srcdir)/stub.c \ + config.h \ $(srcdir)/debug.h $(srcdir)/stub.h \ getdns/getdns.h \ $(srcdir)/types-internal.h \ @@ -435,8 +437,10 @@ stub.lo stub.o: $(srcdir)/stub.c config.h \ $(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/anchor.h \ $(srcdir)/util-internal.h $(srcdir)/platform.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h -sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h \ - config.h $(srcdir)/context.h \ +sync.lo sync.o: $(srcdir)/sync.c \ + getdns/getdns.h \ + config.h \ + $(srcdir)/context.h \ getdns/getdns_extra.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ @@ -550,12 +554,13 @@ libuv.lo libuv.o: $(srcdir)/extension/libuv.c \ getdns/getdns_extra.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \ - config.h $(srcdir)/util-internal.h \ - $(srcdir)/context.h getdns/getdns.h \ + config.h \ + $(srcdir)/util-internal.h $(srcdir)/context.h \ + getdns/getdns.h \ getdns/getdns_extra.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \ $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ - $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ + $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \ $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \ $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/platform.h diff --git a/src/stub.c b/src/stub.c index ebcb2527..46f0056a 100644 --- a/src/stub.c +++ b/src/stub.c @@ -462,13 +462,42 @@ stub_next_upstream(getdns_network_req *netreq) dnsreq->upstreams->current_udp = 0; } +static void +remove_from_write_queue(getdns_upstream *upstream, getdns_network_req * netreq) +{ + getdns_network_req *r, *prev_r; + + for ( r = upstream->write_queue, prev_r = NULL + ; r + ; prev_r = r, r = r->write_queue_tail) { + + if (r != netreq) + continue; + + if (prev_r) + prev_r->write_queue_tail = r->write_queue_tail; + else + upstream->write_queue = r->write_queue_tail; + + if (r == upstream->write_queue_last) { + /* If r was the last netreq, + * its write_queue tail MUST be NULL + */ + assert(r->write_queue_tail == NULL); + upstream->write_queue_last = prev_r ? prev_r : NULL; + } + + netreq->write_queue_tail = NULL; + break; /* netreq found and removed */ + } +} + static void stub_cleanup(getdns_network_req *netreq) { DEBUG_STUB("%s %-35s: MSG: %p\n", STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq); getdns_dns_req *dnsreq = netreq->owner; - getdns_network_req *r, *prev_r; getdns_upstream *upstream; GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); @@ -481,22 +510,7 @@ stub_cleanup(getdns_network_req *netreq) (void) _getdns_rbtree_delete(&upstream->netreq_by_query_id, (void *)(intptr_t)GLDNS_ID_WIRE(netreq->query)); - /* Delete from upstream->write_queue (if present) */ - for (prev_r = NULL, r = upstream->write_queue; r; - prev_r = r, r = r->write_queue_tail) - - if (r == netreq) { - if (prev_r) - prev_r->write_queue_tail = r->write_queue_tail; - else - upstream->write_queue = r->write_queue_tail; - - if (r == upstream->write_queue_last) - upstream->write_queue_last = - prev_r ? prev_r : NULL; - netreq->write_queue_tail = NULL; - break; - } + remove_from_write_queue(upstream, netreq); upstream_reschedule_events(upstream, upstream->keepalive_timeout); } @@ -1706,8 +1720,11 @@ upstream_write_cb(void *userarg) upstream->queries_sent++; /* Unqueue the netreq from the write_queue */ - if (!(upstream->write_queue = netreq->write_queue_tail)) { - upstream->write_queue_last = NULL; + remove_from_write_queue(upstream, netreq); + + /* Empty write_queue?, then deschedule upstream write_cb */ + if (upstream->write_queue == NULL) { + assert(upstream->write_queue_last == NULL); GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event); upstream->event.write_cb = NULL; /* Reschedule (if already reading) to clear writable */ diff --git a/src/test/tpkg/clean.sh b/src/test/tpkg/clean.sh index 60e4ef42..a405d5b0 100755 --- a/src/test/tpkg/clean.sh +++ b/src/test/tpkg/clean.sh @@ -3,5 +3,5 @@ export SRCDIR=`dirname $0` ( cd $SRCDIR ./tpkg clean - rm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info + rm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info Makefile )