mirror of https://github.com/getdnsapi/getdns.git
Merge pull request #260 from wtoorop/devel/fixed_eventloop
Devel/fixed eventloop
This commit is contained in:
commit
c7ae2f5011
|
@ -217,7 +217,6 @@ esac
|
|||
|
||||
DEFAULT_EVENTLOOP=select_eventloop
|
||||
AC_CHECK_HEADERS([sys/poll.h poll.h sys/resource.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([getrlimit])
|
||||
AC_ARG_ENABLE(poll-eventloop, AC_HELP_STRING([--disable-poll-eventloop], [Disable default eventloop based on poll (default=enabled if available)]))
|
||||
case "$enable_poll_eventloop" in
|
||||
no)
|
||||
|
|
|
@ -225,29 +225,28 @@ context.lo context.o: $(srcdir)/context.c \
|
|||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h \
|
||||
$(srcdir)/pubkey-pinning.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.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 \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h \
|
||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h \
|
||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h \
|
||||
$(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h \
|
||||
$(srcdir)/convert.h
|
||||
dict.lo dict.o: $(srcdir)/dict.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
|
||||
$(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h \
|
||||
$(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h
|
||||
dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h \
|
||||
|
@ -255,11 +254,11 @@ dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
|
|||
$(srcdir)/context.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h \
|
||||
$(srcdir)/list.h $(srcdir)/util/val_secalgo.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
|
||||
$(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h \
|
||||
$(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h \
|
||||
$(srcdir)/util/val_secalgo.h
|
||||
general.lo general.o: $(srcdir)/general.c \
|
||||
config.h \
|
||||
$(srcdir)/general.h \
|
||||
|
@ -268,26 +267,26 @@ general.lo general.o: $(srcdir)/general.c \
|
|||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h \
|
||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
|
||||
$(srcdir)/dict.h $(srcdir)/mdns.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \
|
||||
$(srcdir)/mdns.h
|
||||
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \
|
||||
config.h \
|
||||
$(srcdir)/context.h $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h \
|
||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h
|
||||
mdns.lo mdns.o: $(srcdir)/mdns.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h $(srcdir)/context.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/server.h $(srcdir)/general.h $(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/general.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/mdns.h
|
||||
pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h \
|
||||
|
@ -295,26 +294,25 @@ pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
|
|||
$(srcdir)/context.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
|
||||
request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/convert.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/convert.h
|
||||
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/util-internal.h $(srcdir)/context.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h
|
||||
rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
|
@ -324,8 +322,7 @@ server.lo server.o: $(srcdir)/server.c \
|
|||
getdns/getdns_extra.h \
|
||||
getdns/getdns.h \
|
||||
$(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/debug.h $(srcdir)/server.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h
|
||||
stub.lo stub.o: $(srcdir)/stub.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h $(srcdir)/stub.h \
|
||||
|
@ -335,18 +332,17 @@ stub.lo stub.o: $(srcdir)/stub.c \
|
|||
$(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/context.h $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h \
|
||||
$(srcdir)/general.h $(srcdir)/pubkey-pinning.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/general.h \
|
||||
$(srcdir)/pubkey-pinning.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)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
|
||||
$(srcdir)/gldns/wire2str.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/gldns/wire2str.h
|
||||
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
|
@ -358,9 +354,9 @@ util-internal.lo util-internal.o: $(srcdir)/util-internal.c \
|
|||
$(srcdir)/dict.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/util/uthash.h $(srcdir)/ub_loop.h \
|
||||
$(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
|
||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h
|
||||
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \
|
||||
config.h \
|
||||
$(srcdir)/gldns/gbuffer.h
|
||||
|
@ -441,7 +437,7 @@ poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \
|
|||
$(srcdir)/extension/poll_eventloop.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/uthash.h $(srcdir)/debug.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/debug.h
|
||||
select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \
|
||||
config.h \
|
||||
$(srcdir)/extension/select_eventloop.h \
|
||||
|
|
233
src/context.c
233
src/context.c
|
@ -135,8 +135,7 @@ static getdns_return_t create_default_namespaces(struct getdns_context *context)
|
|||
static getdns_return_t create_default_dns_transports(struct getdns_context *context);
|
||||
static int transaction_id_cmp(const void *, const void *);
|
||||
static void dispatch_updated(struct getdns_context *, uint16_t);
|
||||
static void cancel_dns_req(getdns_dns_req *);
|
||||
static void cancel_outstanding_requests(struct getdns_context*, int);
|
||||
static void cancel_outstanding_requests(getdns_context*);
|
||||
|
||||
/* unbound helpers */
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
|
@ -682,8 +681,7 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams)
|
|||
while (upstream->finished_dnsreqs) {
|
||||
dnsreq = upstream->finished_dnsreqs;
|
||||
upstream->finished_dnsreqs = dnsreq->finished_next;
|
||||
(void) _getdns_context_cancel_request(dnsreq->context,
|
||||
dnsreq->trans_id, 1);
|
||||
_getdns_context_cancel_request(dnsreq);
|
||||
}
|
||||
if (upstream->tls_obj != NULL) {
|
||||
if (upstream->tls_session != NULL)
|
||||
|
@ -1521,7 +1519,7 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
|
||||
context->destroying = 1;
|
||||
/* cancel all outstanding requests */
|
||||
cancel_outstanding_requests(context, 1);
|
||||
cancel_outstanding_requests(context);
|
||||
|
||||
/* Destroy listening addresses */
|
||||
(void) getdns_context_set_listen_addresses(context, NULL, NULL, NULL);
|
||||
|
@ -1705,7 +1703,7 @@ static getdns_return_t
|
|||
rebuild_ub_ctx(struct getdns_context* context) {
|
||||
if (context->unbound_ctx != NULL) {
|
||||
/* cancel all requests and delete */
|
||||
cancel_outstanding_requests(context, 1);
|
||||
cancel_outstanding_requests(context);
|
||||
ub_ctx_delete(context->unbound_ctx);
|
||||
context->unbound_ctx = NULL;
|
||||
}
|
||||
|
@ -2882,28 +2880,68 @@ getdns_context_set_memory_functions(struct getdns_context *context,
|
|||
context, MF_PLAIN, mf.ext.malloc, mf.ext.realloc, mf.ext.free);
|
||||
} /* getdns_context_set_memory_functions*/
|
||||
|
||||
/* cancel the request */
|
||||
static void
|
||||
cancel_dns_req(getdns_dns_req *req)
|
||||
void
|
||||
_getdns_context_track_outbound_request(getdns_dns_req *dnsreq)
|
||||
{
|
||||
/* Called only by getdns_general_ns() after successful allocation */
|
||||
assert(dnsreq);
|
||||
|
||||
dnsreq->node.key = &(dnsreq->trans_id);
|
||||
if (_getdns_rbtree_insert(
|
||||
&dnsreq->context->outbound_requests, &dnsreq->node))
|
||||
getdns_context_request_count_changed(dnsreq->context);
|
||||
}
|
||||
|
||||
void
|
||||
_getdns_context_clear_outbound_request(getdns_dns_req *dnsreq)
|
||||
{
|
||||
if (!dnsreq) return;
|
||||
|
||||
if (dnsreq->loop && dnsreq->loop->vmt && dnsreq->timeout.timeout_cb) {
|
||||
dnsreq->loop->vmt->clear(dnsreq->loop, &dnsreq->timeout);
|
||||
dnsreq->timeout.timeout_cb = NULL;
|
||||
}
|
||||
/* delete the node from the tree */
|
||||
if (_getdns_rbtree_delete(
|
||||
&dnsreq->context->outbound_requests, &dnsreq->trans_id))
|
||||
getdns_context_request_count_changed(dnsreq->context);
|
||||
|
||||
if (dnsreq->chain)
|
||||
_getdns_cancel_validation_chain(dnsreq);
|
||||
}
|
||||
|
||||
void
|
||||
_getdns_context_cancel_request(getdns_dns_req *dnsreq)
|
||||
{
|
||||
getdns_network_req *netreq, **netreq_p;
|
||||
|
||||
for (netreq_p = req->netreqs; (netreq = *netreq_p); netreq_p++)
|
||||
DEBUG_SCHED("%s(%p)\n", __FUNC__, (void *)dnsreq);
|
||||
if (!dnsreq) return;
|
||||
|
||||
_getdns_context_clear_outbound_request(dnsreq);
|
||||
|
||||
/* cancel network requests */
|
||||
for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p); netreq_p++)
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
if (netreq->unbound_id != -1) {
|
||||
ub_cancel(req->context->unbound_ctx,
|
||||
ub_cancel(dnsreq->context->unbound_ctx,
|
||||
netreq->unbound_id);
|
||||
netreq->unbound_id = -1;
|
||||
} else
|
||||
#endif
|
||||
_getdns_cancel_stub_request(netreq);
|
||||
|
||||
req->canceled = 1;
|
||||
/* clean up */
|
||||
_getdns_dns_req_free(dnsreq);
|
||||
}
|
||||
|
||||
/*
|
||||
* getdns_cancel_callback
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
_getdns_context_cancel_request(getdns_context *context,
|
||||
getdns_transaction_t transaction_id, int fire_callback)
|
||||
getdns_cancel_callback(getdns_context *context,
|
||||
getdns_transaction_t transaction_id)
|
||||
{
|
||||
getdns_dns_req *dnsreq;
|
||||
|
||||
|
@ -2915,37 +2953,69 @@ _getdns_context_cancel_request(getdns_context *context,
|
|||
&context->outbound_requests, &transaction_id)))
|
||||
return GETDNS_RETURN_UNKNOWN_TRANSACTION;
|
||||
|
||||
/* do the cancel */
|
||||
cancel_dns_req(dnsreq);
|
||||
|
||||
if (fire_callback) {
|
||||
context->processing = 1;
|
||||
dnsreq->user_callback(context, GETDNS_CALLBACK_CANCEL,
|
||||
NULL, dnsreq->user_pointer, transaction_id);
|
||||
context->processing = 0;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
_getdns_dns_req_free(dnsreq);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/*
|
||||
* getdns_cancel_callback
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_cancel_callback(getdns_context *context,
|
||||
getdns_transaction_t transaction_id)
|
||||
{
|
||||
if (!context)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
getdns_return_t r = _getdns_context_cancel_request(context, transaction_id, 1);
|
||||
getdns_context_request_count_changed(context);
|
||||
return r;
|
||||
|
||||
if (dnsreq->user_callback) {
|
||||
dnsreq->context->processing = 1;
|
||||
dnsreq->user_callback(dnsreq->context, GETDNS_CALLBACK_CANCEL,
|
||||
NULL, dnsreq->user_pointer, dnsreq->trans_id);
|
||||
dnsreq->context->processing = 0;
|
||||
}
|
||||
_getdns_context_cancel_request(dnsreq);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_cancel_callback */
|
||||
|
||||
void
|
||||
_getdns_context_request_timed_out(getdns_dns_req *dnsreq)
|
||||
{
|
||||
DEBUG_SCHED("%s(%p)\n", __FUNC__, (void *)dnsreq);
|
||||
|
||||
if (dnsreq->user_callback) {
|
||||
dnsreq->context->processing = 1;
|
||||
dnsreq->user_callback(dnsreq->context, GETDNS_CALLBACK_TIMEOUT,
|
||||
_getdns_create_getdns_response(dnsreq),
|
||||
dnsreq->user_pointer, dnsreq->trans_id);
|
||||
dnsreq->context->processing = 0;
|
||||
}
|
||||
_getdns_context_cancel_request(dnsreq);
|
||||
}
|
||||
|
||||
static void
|
||||
accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg)
|
||||
{
|
||||
*(*(getdns_dns_req ***)arg)++ = (getdns_dns_req *)node;
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_outstanding_requests(getdns_context* context)
|
||||
{
|
||||
getdns_dns_req **dnsreqs, **dnsreq_a, **dnsreq_i;
|
||||
|
||||
if (context->outbound_requests.count == 0)
|
||||
return;
|
||||
|
||||
dnsreq_i = dnsreq_a = dnsreqs = GETDNS_XMALLOC(context->my_mf,
|
||||
getdns_dns_req *, context->outbound_requests.count);
|
||||
|
||||
_getdns_traverse_postorder(&context->outbound_requests,
|
||||
accumulate_outstanding_transactions, &dnsreq_a);
|
||||
|
||||
while (dnsreq_i < dnsreq_a) {
|
||||
getdns_dns_req *dnsreq = *dnsreq_i;
|
||||
|
||||
if (dnsreq->user_callback) {
|
||||
dnsreq->context->processing = 1;
|
||||
dnsreq->user_callback(dnsreq->context,
|
||||
GETDNS_CALLBACK_CANCEL, NULL,
|
||||
dnsreq->user_pointer, dnsreq->trans_id);
|
||||
dnsreq->context->processing = 0;
|
||||
}
|
||||
_getdns_context_cancel_request(dnsreq);
|
||||
|
||||
dnsreq_i += 1;
|
||||
}
|
||||
GETDNS_FREE(context->my_mf, dnsreqs);
|
||||
}
|
||||
|
||||
#ifndef STUB_NATIVE_DNSSEC
|
||||
|
||||
|
@ -3231,54 +3301,6 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context,
|
|||
return r;
|
||||
} /* _getdns_context_prepare_for_resolution */
|
||||
|
||||
getdns_return_t
|
||||
_getdns_context_track_outbound_request(getdns_dns_req *dnsreq)
|
||||
{
|
||||
if (!dnsreq)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
dnsreq->node.key = &(dnsreq->trans_id);
|
||||
if (!_getdns_rbtree_insert(
|
||||
&dnsreq->context->outbound_requests, &dnsreq->node))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
getdns_context_request_count_changed(dnsreq->context);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
_getdns_context_clear_outbound_request(getdns_dns_req *dnsreq)
|
||||
{
|
||||
if (!dnsreq)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (!_getdns_rbtree_delete(
|
||||
&dnsreq->context->outbound_requests, &dnsreq->trans_id))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
getdns_context_request_count_changed(dnsreq->context);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
_getdns_context_request_timed_out(getdns_dns_req *req)
|
||||
{
|
||||
/* Don't use req after callback */
|
||||
getdns_context* context = req->context;
|
||||
getdns_transaction_t trans_id = req->trans_id;
|
||||
getdns_callback_t cb = req->user_callback;
|
||||
void *user_arg = req->user_pointer;
|
||||
getdns_dict *response = _getdns_create_getdns_response(req);
|
||||
|
||||
/* cancel the req - also clears it from outbound and cleans up*/
|
||||
_getdns_context_cancel_request(context, trans_id, 0);
|
||||
context->processing = 1;
|
||||
cb(context, GETDNS_CALLBACK_TIMEOUT, response, user_arg, trans_id);
|
||||
context->processing = 0;
|
||||
getdns_context_request_count_changed(context);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
char *
|
||||
_getdns_strdup(const struct mem_funcs *mfs, const char *s)
|
||||
{
|
||||
|
@ -3360,33 +3382,6 @@ getdns_context_run(getdns_context *context)
|
|||
context->extension->vmt->run(context->extension);
|
||||
}
|
||||
|
||||
typedef struct timeout_accumulator {
|
||||
getdns_transaction_t* ids;
|
||||
int idx;
|
||||
} timeout_accumulator;
|
||||
|
||||
static void
|
||||
accumulate_outstanding_transactions(_getdns_rbnode_t* node, void* arg) {
|
||||
timeout_accumulator* acc = (timeout_accumulator*) arg;
|
||||
acc->ids[acc->idx] = *((getdns_transaction_t*) node->key);
|
||||
acc->idx++;
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_outstanding_requests(struct getdns_context* context, int fire_callback) {
|
||||
if (context->outbound_requests.count > 0) {
|
||||
timeout_accumulator acc;
|
||||
int i;
|
||||
acc.idx = 0;
|
||||
acc.ids = GETDNS_XMALLOC(context->my_mf, getdns_transaction_t, context->outbound_requests.count);
|
||||
_getdns_traverse_postorder(&context->outbound_requests, accumulate_outstanding_transactions, &acc);
|
||||
for (i = 0; i < acc.idx; ++i) {
|
||||
_getdns_context_cancel_request(context, acc.ids[i], fire_callback);
|
||||
}
|
||||
GETDNS_FREE(context->my_mf, acc.ids);
|
||||
}
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_detach_eventloop(struct getdns_context* context)
|
||||
{
|
||||
|
@ -3400,7 +3395,7 @@ getdns_context_detach_eventloop(struct getdns_context* context)
|
|||
* and they may destroy the context )
|
||||
*/
|
||||
/* cancel all outstanding requests */
|
||||
cancel_outstanding_requests(context, 1);
|
||||
cancel_outstanding_requests(context);
|
||||
context->extension->vmt->cleanup(context->extension);
|
||||
context->extension = &context->default_eventloop.loop;
|
||||
_getdns_default_eventloop_init(&context->mf, &context->default_eventloop);
|
||||
|
@ -3418,7 +3413,7 @@ getdns_context_set_eventloop(getdns_context* context, getdns_eventloop* loop)
|
|||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (context->extension) {
|
||||
cancel_outstanding_requests(context, 1);
|
||||
cancel_outstanding_requests(context);
|
||||
context->extension->vmt->cleanup(context->extension);
|
||||
}
|
||||
context->extension = loop;
|
||||
|
|
|
@ -349,19 +349,34 @@ struct getdns_context {
|
|||
getdns_return_t _getdns_context_prepare_for_resolution(struct getdns_context *context,
|
||||
int usenamespaces);
|
||||
|
||||
/* track an outbound request */
|
||||
getdns_return_t _getdns_context_track_outbound_request(struct getdns_dns_req
|
||||
*req);
|
||||
/* clear the outbound request from being tracked - does not cancel it */
|
||||
getdns_return_t _getdns_context_clear_outbound_request(struct getdns_dns_req
|
||||
*req);
|
||||
/* Register a getdns_dns_req with context.
|
||||
* - Without pluggable unbound event API,
|
||||
* ub_fd() is scheduled when this was the first request.
|
||||
*/
|
||||
void _getdns_context_track_outbound_request(getdns_dns_req *dnsreq);
|
||||
|
||||
getdns_return_t _getdns_context_request_timed_out(struct getdns_dns_req
|
||||
*req);
|
||||
/* Deregister getdns_dns_req from the context.
|
||||
* - Without pluggable unbound event API,
|
||||
* ub_fd() is scheduled when this was the first request.
|
||||
* - Potential timeout events will be cleared.
|
||||
* - All associated getdns_dns_reqs (to get the validation chain)
|
||||
* will be canceled.
|
||||
*/
|
||||
void _getdns_context_clear_outbound_request(getdns_dns_req *dnsreq);
|
||||
|
||||
/* cancel callback internal - flag to indicate if req should be freed and callback fired */
|
||||
getdns_return_t _getdns_context_cancel_request(struct getdns_context *context,
|
||||
getdns_transaction_t transaction_id, int fire_callback);
|
||||
/* Cancels and frees a getdns_dns_req (without calling user callbacks)
|
||||
* - Deregisters getdns_dns_req with _getdns_context_clear_outbound_request()
|
||||
* - Cancels associated getdns_network_reqs
|
||||
* (by calling ub_cancel() or _getdns_cancel_stub_request())
|
||||
* - Frees the getdns_dns_req
|
||||
*/
|
||||
void _getdns_context_cancel_request(getdns_dns_req *dnsreq);
|
||||
|
||||
|
||||
/* Calls user callback (with GETDNS_CALLBACK_TIMEOUT + response dict), then
|
||||
* cancels and frees the getdns_dns_req with _getdns_context_cancel_request()
|
||||
*/
|
||||
void _getdns_context_request_timed_out(getdns_dns_req *dnsreq);
|
||||
|
||||
char *_getdns_strdup(const struct mem_funcs *mfs, const char *str);
|
||||
|
||||
|
|
50
src/dnssec.c
50
src/dnssec.c
|
@ -1044,7 +1044,6 @@ static void val_chain_node_cb(getdns_dns_req *dnsreq)
|
|||
_getdns_rrsig_iter *rrsig, rrsig_spc;
|
||||
size_t n_signers;
|
||||
|
||||
_getdns_context_clear_outbound_request(dnsreq);
|
||||
switch (netreq->request_type) {
|
||||
case GETDNS_RRTYPE_DS : node->ds.pkt = netreq->response;
|
||||
node->ds.pkt_len = netreq->response_len;
|
||||
|
@ -1094,7 +1093,6 @@ static void val_chain_node_soa_cb(getdns_dns_req *dnsreq)
|
|||
_getdns_rrset_iter i_spc, *i;
|
||||
_getdns_rrset *rrset;
|
||||
|
||||
_getdns_context_clear_outbound_request(dnsreq);
|
||||
/* A SOA query is always scheduled with a node as the user argument.
|
||||
*/
|
||||
assert(node != NULL);
|
||||
|
@ -1121,8 +1119,10 @@ static void val_chain_node_soa_cb(getdns_dns_req *dnsreq)
|
|||
} else {
|
||||
/* SOA for a different name */
|
||||
node = (chain_node *)dnsreq->user_pointer;
|
||||
node->lock++;
|
||||
val_chain_sched_soa_node(node->parent);
|
||||
if (node->parent) {
|
||||
node->lock++;
|
||||
val_chain_sched_soa_node(node->parent);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (node->parent) {
|
||||
|
@ -3049,7 +3049,10 @@ static void check_chain_complete(chain_head *chain)
|
|||
val_chain_list = dnsreq->dnssec_return_validation_chain
|
||||
? getdns_list_create_with_context(context) : NULL;
|
||||
|
||||
/* Walk chain to add values to val_chain_list and to cleanup */
|
||||
/* Walk chain to add values to val_chain_list. We do not cleanup yet.
|
||||
* The chain will eventually be freed when the dns request is descheduled
|
||||
* with getdns_context_clear_outbound_request().
|
||||
*/
|
||||
for ( head = chain; head ; head = next ) {
|
||||
next = head->next;
|
||||
if (dnsreq->dnssec_return_full_validation_chain &&
|
||||
|
@ -3076,7 +3079,6 @@ static void check_chain_complete(chain_head *chain)
|
|||
context, val_chain_list,
|
||||
node->dnskey_req,
|
||||
node->dnskey_signer);
|
||||
_getdns_dns_req_free(node->dnskey_req->owner);
|
||||
}
|
||||
if (node->ds_req) {
|
||||
if (val_chain_list)
|
||||
|
@ -3094,13 +3096,8 @@ static void check_chain_complete(chain_head *chain)
|
|||
context, val_chain_list,
|
||||
&node->ds);
|
||||
}
|
||||
_getdns_dns_req_free(node->ds_req->owner);
|
||||
}
|
||||
if (node->soa_req) {
|
||||
_getdns_dns_req_free(node->soa_req->owner);
|
||||
}
|
||||
}
|
||||
GETDNS_FREE(head->my_mf, head);
|
||||
}
|
||||
|
||||
response_dict = _getdns_create_getdns_response(dnsreq);
|
||||
|
@ -3115,6 +3112,36 @@ static void check_chain_complete(chain_head *chain)
|
|||
_getdns_call_user_callback(dnsreq, response_dict);
|
||||
}
|
||||
|
||||
void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
|
||||
{
|
||||
chain_head *head = dnsreq->chain, *next;
|
||||
chain_node *node;
|
||||
size_t node_count;
|
||||
|
||||
dnsreq->chain = NULL;
|
||||
while (head) {
|
||||
next = head->next;
|
||||
|
||||
for ( node_count = head->node_count, node = head->parent
|
||||
; node_count
|
||||
; node_count--, node = node->parent ) {
|
||||
|
||||
if (node->dnskey_req)
|
||||
_getdns_context_cancel_request(
|
||||
node->dnskey_req->owner);
|
||||
|
||||
if (node->ds_req)
|
||||
_getdns_context_cancel_request(
|
||||
node->ds_req->owner);
|
||||
|
||||
if (node->soa_req)
|
||||
_getdns_context_cancel_request(
|
||||
node->soa_req->owner);
|
||||
}
|
||||
GETDNS_FREE(head->my_mf, head);
|
||||
head = next;
|
||||
}
|
||||
}
|
||||
|
||||
void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
||||
{
|
||||
|
@ -3152,6 +3179,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
|||
for (chain_p = chain; chain_p; chain_p = chain_p->next) {
|
||||
if (chain_p->lock) chain_p->lock--;
|
||||
}
|
||||
dnsreq->chain = chain;
|
||||
check_chain_complete(chain);
|
||||
} else {
|
||||
dnsreq->validating = 0;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
/* Do some additional requests to fetch the complete validation chain */
|
||||
void _getdns_get_validation_chain(getdns_dns_req *dns_req);
|
||||
void _getdns_cancel_validation_chain(getdns_dns_req *dns_req);
|
||||
|
||||
uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);
|
||||
|
||||
|
|
|
@ -38,38 +38,106 @@
|
|||
#include "extension/poll_eventloop.h"
|
||||
#include "debug.h"
|
||||
|
||||
static _getdns_eventloop_info *
|
||||
find_event(_getdns_eventloop_info** events, int id)
|
||||
enum { init_fd_events_capacity = 64
|
||||
, init_to_events_capacity = 64 };
|
||||
|
||||
static void *get_to_event(_getdns_poll_eventloop *loop,
|
||||
getdns_eventloop_event *event, uint64_t timeout_time)
|
||||
{
|
||||
_getdns_eventloop_info* ev;
|
||||
if (loop->to_events_free == loop->to_events_capacity) {
|
||||
if (loop->to_events_free) {
|
||||
_getdns_poll_event *to_events = GETDNS_XREALLOC(
|
||||
loop->mf, loop->to_events, _getdns_poll_event,
|
||||
loop->to_events_free * 2);
|
||||
if (!to_events)
|
||||
return NULL;
|
||||
(void) memset(&to_events[loop->to_events_free],
|
||||
0, sizeof(_getdns_poll_event)
|
||||
* loop->to_events_free);
|
||||
|
||||
HASH_FIND_INT(*events, &id, ev);
|
||||
loop->to_events_capacity = loop->to_events_free * 2;
|
||||
loop->to_events = to_events;
|
||||
} else {
|
||||
if (!(loop->to_events = GETDNS_XMALLOC(loop->mf,
|
||||
_getdns_poll_event, init_to_events_capacity)))
|
||||
return NULL;
|
||||
|
||||
return ev;
|
||||
(void) memset(loop->to_events, 0,
|
||||
sizeof(_getdns_poll_event)
|
||||
* init_to_events_capacity);
|
||||
|
||||
loop->to_events_capacity = init_to_events_capacity;
|
||||
}
|
||||
}
|
||||
loop->to_events[loop->to_events_free].event = event;
|
||||
loop->to_events[loop->to_events_free].timeout_time = timeout_time;
|
||||
loop->to_events_n_used++;
|
||||
return (void *) (intptr_t) (++loop->to_events_free);
|
||||
}
|
||||
|
||||
static _getdns_eventloop_info *
|
||||
add_event(struct mem_funcs *mf, _getdns_eventloop_info** events,
|
||||
int id, getdns_eventloop_event *event, uint64_t timeout_time)
|
||||
static void *get_fd_event(_getdns_poll_eventloop *loop, int fd,
|
||||
getdns_eventloop_event *event, uint64_t timeout_time)
|
||||
{
|
||||
DEBUG_SCHED("poll_eventloop: add_event with id %d\n", id);
|
||||
_getdns_eventloop_info* myevent = GETDNS_MALLOC(*mf, _getdns_eventloop_info);
|
||||
/* not necessary -- (void) memset(myevent, 0, sizeof(_getdns_eventloop_info)); */
|
||||
size_t i;
|
||||
|
||||
myevent->id = id;
|
||||
myevent->event = event;
|
||||
myevent->timeout_time = timeout_time;
|
||||
HASH_ADD_INT(*events, id, myevent);
|
||||
return myevent;
|
||||
}
|
||||
if (loop->fd_events_free == loop->fd_events_capacity) {
|
||||
if (loop->fd_events_free) {
|
||||
_getdns_poll_event *fd_events = GETDNS_XREALLOC(
|
||||
loop->mf, loop->fd_events, _getdns_poll_event,
|
||||
loop->fd_events_free * 2);
|
||||
struct pollfd *pfds = GETDNS_XREALLOC(
|
||||
loop->mf, loop->pfds, struct pollfd,
|
||||
loop->fd_events_free * 2);
|
||||
|
||||
static void
|
||||
delete_event(struct mem_funcs *mf,
|
||||
_getdns_eventloop_info** events, _getdns_eventloop_info* ev)
|
||||
{
|
||||
DEBUG_SCHED("poll_eventloop: delete_event with id %d\n", ev->id);
|
||||
HASH_DEL(*events, ev);
|
||||
GETDNS_FREE(*mf, ev);
|
||||
if (!fd_events || !pfds) {
|
||||
if (fd_events)
|
||||
GETDNS_FREE(loop->mf, fd_events);
|
||||
if (pfds)
|
||||
GETDNS_FREE(loop->mf, pfds);
|
||||
return NULL;
|
||||
}
|
||||
(void) memset(&fd_events[loop->fd_events_free],
|
||||
0, sizeof(_getdns_poll_event)
|
||||
* loop->fd_events_free);
|
||||
for ( i = loop->fd_events_free
|
||||
; i < loop->fd_events_free * 2
|
||||
; i++) {
|
||||
pfds[i].fd = -1;
|
||||
pfds[i].events = 0;
|
||||
pfds[i].revents = 0;
|
||||
}
|
||||
loop->fd_events_capacity = loop->fd_events_free * 2;
|
||||
loop->fd_events = fd_events;
|
||||
loop->pfds = pfds;
|
||||
} else {
|
||||
if (!(loop->fd_events = GETDNS_XMALLOC(loop->mf,
|
||||
_getdns_poll_event, init_fd_events_capacity)) ||
|
||||
!(loop->pfds = GETDNS_XMALLOC(loop->mf,
|
||||
struct pollfd, init_fd_events_capacity))) {
|
||||
GETDNS_NULL_FREE(loop->mf, loop->fd_events);
|
||||
return NULL;
|
||||
}
|
||||
(void) memset(loop->fd_events, 0,
|
||||
sizeof(_getdns_poll_event)
|
||||
* init_fd_events_capacity);
|
||||
for (i = 0; i < init_fd_events_capacity; i++) {
|
||||
loop->pfds[i].fd = -1;
|
||||
loop->pfds[i].events = 0;
|
||||
loop->pfds[i].revents = 0;
|
||||
}
|
||||
loop->fd_events_capacity = init_fd_events_capacity;
|
||||
}
|
||||
}
|
||||
loop->pfds[loop->fd_events_free].fd = fd;
|
||||
loop->pfds[loop->fd_events_free].events = 0;
|
||||
if (event->read_cb)
|
||||
loop->pfds[loop->fd_events_free].events |= POLLIN;
|
||||
if (event->write_cb)
|
||||
loop->pfds[loop->fd_events_free].events |= POLLOUT;
|
||||
loop->fd_events[loop->fd_events_free].event = event;
|
||||
loop->fd_events[loop->fd_events_free].timeout_time = timeout_time;
|
||||
loop->fd_events_n_used++;
|
||||
return (void *) (intptr_t) (++loop->fd_events_free);
|
||||
}
|
||||
|
||||
static uint64_t get_now_plus(uint64_t amount)
|
||||
|
@ -92,50 +160,26 @@ poll_eventloop_schedule(getdns_eventloop *loop,
|
|||
int fd, uint64_t timeout, getdns_eventloop_event *event)
|
||||
{
|
||||
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
|
||||
struct mem_funcs *mf = &poll_loop->mf;
|
||||
size_t i;
|
||||
|
||||
DEBUG_SCHED( "%s(loop: %p, fd: %d, timeout: %"PRIu64", event: %p, max_fds: %d)\n"
|
||||
, __FUNC__, (void *)loop, fd, timeout, (void *)event, poll_loop->max_fds);
|
||||
DEBUG_SCHED( "%s(loop: %p, fd: %d, timeout: %"PRIu64", event: %p)\n"
|
||||
, __FUNC__, (void *)loop, fd, timeout, (void *)event);
|
||||
|
||||
if (!loop || !event)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
if (fd >= (int)poll_loop->max_fds) {
|
||||
DEBUG_SCHED( "ERROR: fd %d >= max_fds: %d!\n"
|
||||
, fd, poll_loop->max_fds);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
#endif
|
||||
if (fd >= 0 && !(event->read_cb || event->write_cb)) {
|
||||
DEBUG_SCHED("WARNING: fd event without "
|
||||
"read or write cb!\n");
|
||||
fd = -1;
|
||||
}
|
||||
if (fd >= 0) {
|
||||
_getdns_eventloop_info* fd_event = find_event(&poll_loop->fd_events, fd);
|
||||
#if defined(SCHED_DEBUG) && SCHED_DEBUG
|
||||
if (fd_event) {
|
||||
if (fd_event->event == event) {
|
||||
DEBUG_SCHED("WARNING: Event %p not cleared "
|
||||
"before being rescheduled!\n"
|
||||
, (void *)fd_event->event);
|
||||
} else {
|
||||
DEBUG_SCHED("ERROR: A different event is "
|
||||
"already present at fd slot: %p!\n"
|
||||
, (void *)fd_event->event);
|
||||
}
|
||||
if (!(event->ev = get_fd_event(
|
||||
poll_loop, fd, event, get_now_plus(timeout)))) {
|
||||
DEBUG_SCHED("ERROR: scheduled read/write slots!\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
#endif
|
||||
/* cleanup the old event if it exists */
|
||||
if (fd_event) {
|
||||
delete_event(mf, &poll_loop->fd_events, fd_event);
|
||||
}
|
||||
event->ev = add_event(mf, &poll_loop->fd_events, fd, event, get_now_plus(timeout));
|
||||
|
||||
DEBUG_SCHED( "scheduled read/write at fd %d\n", fd);
|
||||
DEBUG_SCHED( "scheduled read/write at for %d at %p\n"
|
||||
, fd, (void *)event->ev);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
if (!event->timeout_cb) {
|
||||
|
@ -150,37 +194,73 @@ poll_eventloop_schedule(getdns_eventloop *loop,
|
|||
DEBUG_SCHED("ERROR: timeout event with write_cb! Clearing.\n");
|
||||
event->write_cb = NULL;
|
||||
}
|
||||
for (i = poll_loop->timeout_id + 1; i != poll_loop->timeout_id; i++) {
|
||||
if (find_event(&poll_loop->timeout_events, i) == NULL) {
|
||||
event->ev = add_event(mf, &poll_loop->timeout_events, i, event, get_now_plus(timeout));
|
||||
|
||||
DEBUG_SCHED( "scheduled timeout at slot %d\n", (int)i);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
if (!(event->ev = get_to_event(poll_loop, event, get_now_plus(timeout)))) {
|
||||
DEBUG_SCHED("ERROR: Out of timeout slots!\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
DEBUG_SCHED("ERROR: Out of timeout slots!\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
DEBUG_SCHED("scheduled timeout at slot %p\n", (void *)event->ev);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
poll_eventloop_clear(getdns_eventloop *loop, getdns_eventloop_event *event)
|
||||
{
|
||||
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
|
||||
struct mem_funcs *mf = &poll_loop->mf;
|
||||
|
||||
if (!loop || !event)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
DEBUG_SCHED( "%s(loop: %p, event: %p)\n", __FUNC__, (void *)loop, (void *)event);
|
||||
|
||||
assert(event->ev);
|
||||
if (!event->ev)
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
||||
delete_event(mf,
|
||||
( event->timeout_cb && !event->read_cb && !event->write_cb
|
||||
? &poll_loop->timeout_events : &poll_loop->fd_events
|
||||
), event->ev);
|
||||
else if (event->timeout_cb && !event->read_cb && !event->write_cb) {
|
||||
size_t i = ((size_t) (intptr_t) event->ev) - 1;
|
||||
|
||||
/* This may happen with full recursive synchronous requests
|
||||
* with the unbound pluggable event API, because the default
|
||||
* poll_eventloop is temporarily replaced by a poll_eventloop
|
||||
* used only in synchronous calls. When the synchronous request
|
||||
* had an answer, the poll_eventloop for the synchronous is
|
||||
* cleaned, however it could still have outstanding events.
|
||||
*/
|
||||
if (i >= poll_loop->to_events_capacity ||
|
||||
poll_loop->to_events[i].event != event) {
|
||||
event->ev = NULL;
|
||||
DEBUG_SCHED( "ERROR: Event mismatch %p\n", (void *)event->ev);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
poll_loop->to_events[i].event = NULL;
|
||||
if (--poll_loop->to_events_n_used == 0) {
|
||||
poll_loop->to_events_free = 0;
|
||||
}
|
||||
DEBUG_SCHED( "cleared timeout at slot %p\n", (void *)event->ev);
|
||||
} else {
|
||||
size_t i = ((size_t) (intptr_t) event->ev) - 1;
|
||||
|
||||
/* This may happen with full recursive synchronous requests
|
||||
* with the unbound pluggable event API, because the default
|
||||
* poll_eventloop is temporarily replaced by a poll_eventloop
|
||||
* used only in synchronous calls. When the synchronous request
|
||||
* had an answer, the poll_eventloop for the synchronous is
|
||||
* cleaned, however it could still have outstanding events.
|
||||
*/
|
||||
if (i >= poll_loop->fd_events_capacity ||
|
||||
poll_loop->fd_events[i].event != event) {
|
||||
event->ev = NULL;
|
||||
DEBUG_SCHED( "ERROR: Event mismatch %p\n", (void *)event->ev);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
poll_loop->fd_events[i].event = NULL;
|
||||
if (--poll_loop->fd_events_n_used == 0) {
|
||||
poll_loop->fd_events_free = 0;
|
||||
}
|
||||
DEBUG_SCHED( "cleared read/write for %d at slot %p\n"
|
||||
, poll_loop->pfds[i].fd, (void *)event->ev);
|
||||
poll_loop->pfds[i].fd = -1; /* Not necessary, but to be sure */
|
||||
}
|
||||
event->ev = NULL;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
@ -190,13 +270,21 @@ poll_eventloop_cleanup(getdns_eventloop *loop)
|
|||
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
|
||||
struct mem_funcs *mf = &poll_loop->mf;
|
||||
|
||||
if (poll_loop->pfds) {
|
||||
GETDNS_FREE(*mf, poll_loop->pfds);
|
||||
poll_loop->pfds = NULL;
|
||||
poll_loop->pfds_capacity = 0;
|
||||
GETDNS_NULL_FREE(*mf, poll_loop->pfds);
|
||||
if (poll_loop->fd_events) {
|
||||
GETDNS_FREE(*mf, poll_loop->fd_events);
|
||||
poll_loop->fd_events = NULL;
|
||||
poll_loop->fd_events_capacity = 0;
|
||||
poll_loop->fd_events_free = 0;
|
||||
poll_loop->fd_events_n_used = 0;
|
||||
}
|
||||
if (poll_loop->to_events) {
|
||||
GETDNS_FREE(*mf, poll_loop->to_events);
|
||||
poll_loop->to_events = NULL;
|
||||
poll_loop->to_events_capacity = 0;
|
||||
poll_loop->to_events_free = 0;
|
||||
poll_loop->to_events_n_used = 0;
|
||||
}
|
||||
HASH_CLEAR(hh, poll_loop->fd_events);
|
||||
HASH_CLEAR(hh, poll_loop->timeout_events);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -220,154 +308,176 @@ poll_write_cb(int fd, getdns_eventloop_event *event)
|
|||
}
|
||||
|
||||
static void
|
||||
poll_timeout_cb(int fd, getdns_eventloop_event *event)
|
||||
poll_timeout_cb(getdns_eventloop_event *event)
|
||||
{
|
||||
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
|
||||
(void)fd;
|
||||
#endif
|
||||
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
|
||||
DEBUG_SCHED( "%s(event: %p)\n", __FUNC__, (void *)event);
|
||||
event->timeout_cb(event->userarg);
|
||||
}
|
||||
|
||||
static unsigned long up_pow2(unsigned long v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
return v + 1;
|
||||
}
|
||||
|
||||
static void
|
||||
poll_eventloop_run_once(getdns_eventloop *loop, int blocking)
|
||||
{
|
||||
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
|
||||
struct mem_funcs *mf = &poll_loop->mf;
|
||||
_getdns_eventloop_info *s, *tmp;
|
||||
uint64_t now, timeout = TIMEOUT_FOREVER;
|
||||
size_t i=0;
|
||||
size_t i = 0, j;
|
||||
int poll_timeout = 0;
|
||||
unsigned int num_pfds = 0;
|
||||
_getdns_eventloop_info* timeout_timeout_cbs = NULL;
|
||||
_getdns_eventloop_info* fd_timeout_cbs = NULL;
|
||||
|
||||
if (!loop)
|
||||
return;
|
||||
|
||||
now = get_now_plus(0);
|
||||
|
||||
HASH_ITER(hh, poll_loop->timeout_events, s, tmp) {
|
||||
if (now > s->timeout_time)
|
||||
(void) add_event(mf, &timeout_timeout_cbs, s->id, s->event, s->timeout_time);
|
||||
else if (s->timeout_time < timeout)
|
||||
timeout = s->timeout_time;
|
||||
for (i = 0, j = 0; i < poll_loop->to_events_free; i++, j++) {
|
||||
while (poll_loop->to_events[i].event == NULL) {
|
||||
if (++i == poll_loop->to_events_free) {
|
||||
poll_loop->to_events_free = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < i) {
|
||||
if (j >= poll_loop->to_events_free)
|
||||
break;
|
||||
poll_loop->to_events[j] = poll_loop->to_events[i];
|
||||
poll_loop->to_events[i].event = NULL;
|
||||
poll_loop->to_events[j].event->ev =
|
||||
(void *) (intptr_t) (j + 1);
|
||||
}
|
||||
if (poll_loop->to_events[j].timeout_time < now)
|
||||
poll_timeout_cb(poll_loop->to_events[j].event);
|
||||
}
|
||||
/* this is in case the timeout callback deletes the event
|
||||
and thus messes with the iteration */
|
||||
HASH_ITER(hh, timeout_timeout_cbs, s, tmp) {
|
||||
getdns_eventloop_event* event = s->event;
|
||||
delete_event(mf, &timeout_timeout_cbs, s);
|
||||
poll_timeout_cb(-1, event);
|
||||
for (i = 0, j = 0; i < poll_loop->to_events_free; i++, j++) {
|
||||
while (poll_loop->to_events[i].event == NULL) {
|
||||
if (++i == poll_loop->to_events_free) {
|
||||
poll_loop->to_events_free = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < i) {
|
||||
if (j >= poll_loop->to_events_free)
|
||||
break;
|
||||
poll_loop->to_events[j] = poll_loop->to_events[i];
|
||||
poll_loop->to_events[i].event = NULL;
|
||||
poll_loop->to_events[j].event->ev =
|
||||
(void *) (intptr_t) (j + 1);
|
||||
}
|
||||
if (poll_loop->to_events[j].timeout_time < timeout)
|
||||
timeout = poll_loop->to_events[j].timeout_time;
|
||||
}
|
||||
/* first we count the number of fds that will be active */
|
||||
HASH_ITER(hh, poll_loop->fd_events, s, tmp) {
|
||||
if (s->event->read_cb ||
|
||||
s->event->write_cb)
|
||||
num_pfds++;
|
||||
if (s->timeout_time < timeout)
|
||||
timeout = s->timeout_time;
|
||||
}
|
||||
|
||||
if ((timeout == TIMEOUT_FOREVER) && (num_pfds == 0))
|
||||
if ((timeout == TIMEOUT_FOREVER) && (poll_loop->fd_events_free == 0))
|
||||
return;
|
||||
|
||||
if (num_pfds >= poll_loop->pfds_capacity) {
|
||||
poll_loop->pfds_capacity = up_pow2(num_pfds + 1);
|
||||
if (!poll_loop->pfds) {
|
||||
poll_loop->pfds = GETDNS_XMALLOC(poll_loop->mf, struct pollfd, poll_loop->pfds_capacity);
|
||||
} else
|
||||
poll_loop->pfds = GETDNS_XREALLOC(poll_loop->mf, poll_loop->pfds, struct pollfd, poll_loop->pfds_capacity);
|
||||
if (poll_loop->pfds == 0) {
|
||||
poll_loop->pfds_capacity = 0;
|
||||
return;
|
||||
for (i = 0, j = 0; i < poll_loop->fd_events_free; i++, j++) {
|
||||
while (poll_loop->fd_events[i].event == NULL) {
|
||||
if (++i == poll_loop->fd_events_free) {
|
||||
poll_loop->fd_events_free = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < i) {
|
||||
if (j >= poll_loop->fd_events_free)
|
||||
break;
|
||||
poll_loop->fd_events[j] = poll_loop->fd_events[i];
|
||||
poll_loop->fd_events[i].event = NULL;
|
||||
poll_loop->fd_events[j].event->ev =
|
||||
(void *) (intptr_t) (j + 1);
|
||||
poll_loop->pfds[j] = poll_loop->pfds[i];
|
||||
poll_loop->pfds[i].fd = -1;
|
||||
}
|
||||
if (poll_loop->fd_events[j].timeout_time < timeout)
|
||||
timeout = poll_loop->fd_events[j].timeout_time;
|
||||
}
|
||||
i = 0;
|
||||
HASH_ITER(hh, poll_loop->fd_events, s, tmp) {
|
||||
if (!s->event->read_cb && !s->event->write_cb)
|
||||
continue;
|
||||
poll_loop->pfds[i].fd = s->id;
|
||||
poll_loop->pfds[i].events = 0;
|
||||
poll_loop->pfds[i].revents = 0; /* <-- probably not needed */
|
||||
if (s->event->read_cb)
|
||||
poll_loop->pfds[i].events |= POLLIN;
|
||||
if (s->event->write_cb)
|
||||
poll_loop->pfds[i].events |= POLLOUT;
|
||||
i++;
|
||||
}
|
||||
assert(i == num_pfds);
|
||||
|
||||
if (timeout == TIMEOUT_FOREVER) {
|
||||
poll_timeout = -1;
|
||||
}
|
||||
else if (! blocking || now > timeout) {
|
||||
|
||||
} else if (! blocking || now > timeout) {
|
||||
poll_timeout = 0;
|
||||
} else {
|
||||
poll_timeout = (timeout - now) / 1000; /* turn microseconds into milliseconds */
|
||||
/* turn microseconds into milliseconds */
|
||||
poll_timeout = (timeout - now) / 1000;
|
||||
}
|
||||
DEBUG_SCHED( "poll(fd_free: %d, fd_used: %d, to_free: %d, to_used: %d, timeout: %d)\n"
|
||||
, (int)poll_loop->fd_events_free, (int)poll_loop->fd_events_n_used
|
||||
, (int)poll_loop->to_events_free, (int)poll_loop->to_events_n_used
|
||||
, poll_timeout
|
||||
);
|
||||
#ifdef USE_WINSOCK
|
||||
if (WSAPoll(poll_loop->pfds, num_pfds, poll_timeout) < 0) {
|
||||
if (WSAPoll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
|
||||
#else
|
||||
if (poll(poll_loop->pfds, num_pfds, poll_timeout) < 0) {
|
||||
if (poll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
|
||||
#endif
|
||||
perror("poll() failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
now = get_now_plus(0);
|
||||
for (i = 0; i < num_pfds; i++) {
|
||||
int fd = poll_loop->pfds[i].fd;
|
||||
_getdns_eventloop_info* fd_event = find_event(&poll_loop->fd_events, fd);
|
||||
if (fd_event && fd_event->event) {
|
||||
getdns_eventloop_event* event = fd_event->event;
|
||||
if (event->write_cb &&
|
||||
(poll_loop->pfds[i].revents & POLLOUT))
|
||||
poll_write_cb(fd, event);
|
||||
|
||||
else if (event->read_cb &&
|
||||
(poll_loop->pfds[i].revents & POLLIN))
|
||||
poll_read_cb(fd, event);
|
||||
for (i = 0, j = 0; i < poll_loop->fd_events_free; i++, j++) {
|
||||
while (poll_loop->fd_events[i].event == NULL) {
|
||||
if (++i == poll_loop->fd_events_free) {
|
||||
poll_loop->fd_events_free = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < i) {
|
||||
if (j >= poll_loop->fd_events_free)
|
||||
break;
|
||||
poll_loop->fd_events[j] = poll_loop->fd_events[i];
|
||||
poll_loop->fd_events[i].event = NULL;
|
||||
poll_loop->fd_events[j].event->ev =
|
||||
(void *) (intptr_t) (j + 1);
|
||||
poll_loop->pfds[j] = poll_loop->pfds[i];
|
||||
poll_loop->pfds[i].fd = -1;
|
||||
}
|
||||
if (poll_loop->fd_events[j].event->write_cb &&
|
||||
poll_loop->pfds[j].revents & POLLOUT)
|
||||
poll_write_cb( poll_loop->pfds[j].fd
|
||||
, poll_loop->fd_events[j].event);
|
||||
|
||||
if (poll_loop->fd_events[j].event &&
|
||||
poll_loop->fd_events[j].event->read_cb &&
|
||||
poll_loop->pfds[j].revents & POLLIN)
|
||||
poll_read_cb( poll_loop->pfds[j].fd
|
||||
, poll_loop->fd_events[j].event);
|
||||
}
|
||||
HASH_ITER(hh, poll_loop->fd_events, s, tmp) {
|
||||
if (s->event &&
|
||||
s->event->timeout_cb &&
|
||||
now > s->timeout_time)
|
||||
(void) add_event(mf, &fd_timeout_cbs, s->id, s->event, s->timeout_time);
|
||||
}
|
||||
/* this is in case the timeout callback deletes the event
|
||||
and thus messes with the iteration */
|
||||
HASH_ITER(hh, fd_timeout_cbs, s, tmp) {
|
||||
int fd = s->id;
|
||||
getdns_eventloop_event* event = s->event;
|
||||
delete_event(mf, &fd_timeout_cbs, s);
|
||||
poll_timeout_cb(fd, event);
|
||||
}
|
||||
HASH_ITER(hh, poll_loop->timeout_events, s, tmp) {
|
||||
if (s->event &&
|
||||
s->event->timeout_cb &&
|
||||
now > s->timeout_time)
|
||||
(void) add_event(mf, &timeout_timeout_cbs, s->id, s->event, s->timeout_time);
|
||||
}
|
||||
/* this is in case the timeout callback deletes the event
|
||||
and thus messes with the iteration */
|
||||
HASH_ITER(hh, timeout_timeout_cbs, s, tmp) {
|
||||
getdns_eventloop_event* event = s->event;
|
||||
delete_event(mf, &timeout_timeout_cbs, s);
|
||||
poll_timeout_cb(-1, event);
|
||||
for (i = 0, j = 0; i < poll_loop->fd_events_free; i++, j++) {
|
||||
while (poll_loop->fd_events[i].event == NULL) {
|
||||
if (++i == poll_loop->fd_events_free) {
|
||||
poll_loop->fd_events_free = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < i) {
|
||||
if (j >= poll_loop->fd_events_free)
|
||||
break;
|
||||
poll_loop->fd_events[j] = poll_loop->fd_events[i];
|
||||
poll_loop->fd_events[i].event = NULL;
|
||||
poll_loop->fd_events[j].event->ev =
|
||||
(void *) (intptr_t) (j + 1);
|
||||
poll_loop->pfds[j] = poll_loop->pfds[i];
|
||||
poll_loop->pfds[i].fd = -1;
|
||||
}
|
||||
if (poll_loop->fd_events[j].timeout_time < now)
|
||||
poll_timeout_cb(poll_loop->fd_events[j].event);
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < poll_loop->to_events_free; i++, j++) {
|
||||
while (poll_loop->to_events[i].event == NULL) {
|
||||
if (++i == poll_loop->to_events_free) {
|
||||
poll_loop->to_events_free = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < i) {
|
||||
if (j >= poll_loop->to_events_free)
|
||||
break;
|
||||
poll_loop->to_events[j] = poll_loop->to_events[i];
|
||||
poll_loop->to_events[i].event = NULL;
|
||||
poll_loop->to_events[j].event->ev =
|
||||
(void *) (intptr_t) (j + 1);
|
||||
}
|
||||
if (poll_loop->to_events[j].timeout_time < now)
|
||||
poll_timeout_cb(poll_loop->to_events[j].event);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -379,7 +489,7 @@ poll_eventloop_run(getdns_eventloop *loop)
|
|||
return;
|
||||
|
||||
/* keep going until all the events are cleared */
|
||||
while (poll_loop->fd_events || poll_loop->timeout_events) {
|
||||
while (poll_loop->fd_events_n_used || poll_loop->to_events_n_used) {
|
||||
poll_eventloop_run_once(loop, 1);
|
||||
}
|
||||
}
|
||||
|
@ -387,9 +497,6 @@ poll_eventloop_run(getdns_eventloop *loop)
|
|||
void
|
||||
_getdns_poll_eventloop_init(struct mem_funcs *mf, _getdns_poll_eventloop *loop)
|
||||
{
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
struct rlimit rl;
|
||||
#endif
|
||||
static getdns_eventloop_vmt poll_eventloop_vmt = {
|
||||
poll_eventloop_cleanup,
|
||||
poll_eventloop_schedule,
|
||||
|
@ -401,19 +508,38 @@ _getdns_poll_eventloop_init(struct mem_funcs *mf, _getdns_poll_eventloop *loop)
|
|||
loop->loop.vmt = &poll_eventloop_vmt;
|
||||
loop->mf = *mf;
|
||||
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
|
||||
loop->max_fds = rl.rlim_cur;
|
||||
loop->to_events_capacity = init_to_events_capacity;
|
||||
if ((loop->to_events = GETDNS_XMALLOC(
|
||||
*mf, _getdns_poll_event, init_to_events_capacity)))
|
||||
(void) memset(loop->to_events, 0,
|
||||
sizeof(_getdns_poll_event) * init_to_events_capacity);
|
||||
else
|
||||
loop->to_events_capacity = 0;
|
||||
loop->to_events_free = 0;
|
||||
loop->to_events_n_used = 0;
|
||||
|
||||
loop->fd_events_capacity = init_fd_events_capacity;
|
||||
if ((loop->fd_events = GETDNS_XMALLOC(
|
||||
*mf, _getdns_poll_event, init_fd_events_capacity)) &&
|
||||
(loop->pfds = GETDNS_XMALLOC(
|
||||
*mf, struct pollfd, init_fd_events_capacity))) {
|
||||
size_t i;
|
||||
|
||||
(void) memset(loop->fd_events, 0,
|
||||
sizeof(_getdns_poll_event) * init_fd_events_capacity);
|
||||
for (i = 0; i < init_fd_events_capacity; i++) {
|
||||
loop->pfds[i].fd = -1;
|
||||
loop->pfds[i].events = 0;
|
||||
loop->pfds[i].revents = 0;
|
||||
}
|
||||
} else {
|
||||
DEBUG_SCHED("ERROR: could not obtain RLIMIT_NOFILE from getrlimit()\n");
|
||||
#endif
|
||||
loop->max_fds = 0;
|
||||
#if HAVE_GETRLIMIT
|
||||
loop->fd_events_capacity = 0;
|
||||
if (loop->fd_events) {
|
||||
GETDNS_FREE(*mf, loop->fd_events);
|
||||
loop->fd_events = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
loop->timeout_id = 0;
|
||||
loop->pfds = NULL;
|
||||
loop->pfds_capacity = 0;
|
||||
loop->fd_events = NULL;
|
||||
loop->timeout_events = NULL;
|
||||
loop->fd_events_free = 0;
|
||||
loop->fd_events_n_used = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,28 +36,27 @@
|
|||
#include "getdns/getdns_extra.h"
|
||||
#include "types-internal.h"
|
||||
|
||||
#define uthash_malloc(sz) ((void *)GETDNS_XMALLOC(*mf, unsigned char, sz))
|
||||
#define uthash_free(ptr,sz) GETDNS_FREE(*mf, ptr)
|
||||
#include "util/uthash.h"
|
||||
|
||||
/* Eventloop based on poll */
|
||||
|
||||
typedef struct _getdns_eventloop_info {
|
||||
int id;
|
||||
typedef struct _getdns_poll_event {
|
||||
getdns_eventloop_event *event;
|
||||
uint64_t timeout_time;
|
||||
UT_hash_handle hh;
|
||||
} _getdns_eventloop_info;
|
||||
} _getdns_poll_event;
|
||||
|
||||
typedef struct _getdns_poll_eventloop {
|
||||
getdns_eventloop loop;
|
||||
struct mem_funcs mf;
|
||||
unsigned int max_fds;
|
||||
unsigned int timeout_id;
|
||||
struct pollfd *pfds;
|
||||
unsigned long pfds_capacity;
|
||||
_getdns_eventloop_info *fd_events;
|
||||
_getdns_eventloop_info *timeout_events;
|
||||
getdns_eventloop loop;
|
||||
struct mem_funcs mf;
|
||||
|
||||
struct pollfd *pfds;
|
||||
size_t fd_events_capacity;
|
||||
_getdns_poll_event *fd_events;
|
||||
size_t fd_events_free;
|
||||
size_t fd_events_n_used;
|
||||
|
||||
size_t to_events_capacity;
|
||||
_getdns_poll_event *to_events;
|
||||
size_t to_events_free;
|
||||
size_t to_events_n_used;
|
||||
} _getdns_poll_eventloop;
|
||||
|
||||
void
|
||||
|
|
|
@ -54,14 +54,6 @@
|
|||
#include "dict.h"
|
||||
#include "mdns.h"
|
||||
|
||||
/* cancel, cleanup and send timeout to callback */
|
||||
static void
|
||||
ub_resolve_timeout(void *arg)
|
||||
{
|
||||
getdns_dns_req *dns_req = (getdns_dns_req *) arg;
|
||||
(void) _getdns_context_request_timed_out(dns_req);
|
||||
}
|
||||
|
||||
void _getdns_call_user_callback(getdns_dns_req *dns_req,
|
||||
struct getdns_dict *response)
|
||||
{
|
||||
|
@ -72,13 +64,14 @@ void _getdns_call_user_callback(getdns_dns_req *dns_req,
|
|||
|
||||
/* clean up */
|
||||
_getdns_context_clear_outbound_request(dns_req);
|
||||
_getdns_dns_req_free(dns_req);
|
||||
|
||||
context->processing = 1;
|
||||
cb(context,
|
||||
(response ? GETDNS_CALLBACK_COMPLETE : GETDNS_CALLBACK_ERROR),
|
||||
response, user_arg, trans_id);
|
||||
context->processing = 0;
|
||||
|
||||
_getdns_dns_req_free(dns_req);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -186,9 +179,10 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (dns_req->internal_cb)
|
||||
if (dns_req->internal_cb) {
|
||||
_getdns_context_clear_outbound_request(dns_req);
|
||||
dns_req->internal_cb(dns_req);
|
||||
else if (! results_found)
|
||||
} else if (! results_found)
|
||||
_getdns_call_user_callback(dns_req, NULL);
|
||||
else if (dns_req->dnssec_return_validation_chain
|
||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
|
@ -290,7 +284,9 @@ _getdns_submit_netreq(getdns_network_req *netreq)
|
|||
dns_req->timeout.userarg = dns_req;
|
||||
dns_req->timeout.read_cb = NULL;
|
||||
dns_req->timeout.write_cb = NULL;
|
||||
dns_req->timeout.timeout_cb = ub_resolve_timeout;
|
||||
dns_req->timeout.timeout_cb =
|
||||
(getdns_eventloop_callback)
|
||||
_getdns_context_request_timed_out;
|
||||
dns_req->timeout.ev = NULL;
|
||||
if ((r = dns_req->loop->vmt->schedule(dns_req->loop, -1,
|
||||
dns_req->context->timeout, &dns_req->timeout)))
|
||||
|
|
|
@ -644,7 +644,7 @@ _getdns_dns_req_free(getdns_dns_req * req)
|
|||
network_req_cleanup(*net_req);
|
||||
|
||||
/* clear timeout event */
|
||||
if (req->timeout.timeout_cb) {
|
||||
if (req->loop && req->loop->vmt && req->timeout.timeout_cb) {
|
||||
req->loop->vmt->clear(req->loop, &req->timeout);
|
||||
req->timeout.timeout_cb = NULL;
|
||||
}
|
||||
|
@ -896,9 +896,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
}
|
||||
result->context = context;
|
||||
result->loop = loop;
|
||||
result->canceled = 0;
|
||||
result->trans_id = (((uint64_t)arc4random()) << 32) |
|
||||
((uint64_t)arc4random());
|
||||
result->trans_id = (uint64_t) (intptr_t) result;
|
||||
result->dnssec_return_status = dnssec_return_status;
|
||||
result->dnssec_return_only_secure = dnssec_return_only_secure;
|
||||
result->dnssec_return_all_statuses = dnssec_return_all_statuses;
|
||||
|
@ -934,6 +932,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
result->finished_next = NULL;
|
||||
result->freed = NULL;
|
||||
result->validating = 0;
|
||||
result->chain = NULL;
|
||||
|
||||
network_req_init(result->netreqs[0], result,
|
||||
request_type, dnssec_extension_set, with_opt,
|
||||
|
|
|
@ -602,7 +602,7 @@ stub_timeout_cb(void *userarg)
|
|||
if (netreq->owner->user_callback) {
|
||||
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
||||
/* Note this calls cancel_request which calls stub_cleanup again....!*/
|
||||
(void) _getdns_context_request_timed_out(netreq->owner);
|
||||
_getdns_context_request_timed_out(netreq->owner);
|
||||
} else
|
||||
_getdns_check_dns_req_complete(netreq->owner);
|
||||
}
|
||||
|
@ -1299,8 +1299,6 @@ stub_udp_read_cb(void *userarg)
|
|||
DEBUG_STUB("%s %-35s: MSG: %p \n", STUB_DEBUG_READ,
|
||||
__FUNC__, (void*)netreq);
|
||||
|
||||
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
||||
|
||||
read = recvfrom(netreq->fd, (void *)netreq->response,
|
||||
netreq->max_udp_payload_size + 1, /* If read == max_udp_payload_size
|
||||
* then all is good. If read ==
|
||||
|
@ -1322,6 +1320,8 @@ stub_udp_read_cb(void *userarg)
|
|||
upstream, netreq->response, read))
|
||||
return; /* Client cookie didn't match? */
|
||||
|
||||
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(netreq->fd);
|
||||
#else
|
||||
|
|
|
@ -267,6 +267,7 @@ typedef struct getdns_network_req
|
|||
static inline int _getdns_netreq_finished(getdns_network_req *req)
|
||||
{ return !req || (req->state & NET_REQ_FINISHED); }
|
||||
|
||||
struct chain_head;
|
||||
/**
|
||||
* dns request - manages a number of network requests and
|
||||
* the initial data passed to getdns_general
|
||||
|
@ -289,9 +290,6 @@ typedef struct getdns_dns_req {
|
|||
size_t suffix_len;
|
||||
unsigned suffix_appended : 1;
|
||||
|
||||
/* canceled flag */
|
||||
unsigned canceled : 1;
|
||||
|
||||
/* request extensions */
|
||||
unsigned dnssec_return_status : 1;
|
||||
unsigned dnssec_return_only_secure : 1;
|
||||
|
@ -322,6 +320,9 @@ typedef struct getdns_dns_req {
|
|||
unsigned validating : 1;
|
||||
int *freed;
|
||||
|
||||
/* Validation chain to be canceled when this request is canceled */
|
||||
struct chain_head *chain;
|
||||
|
||||
uint16_t tls_query_padding_blocksize;
|
||||
|
||||
/* internally scheduled request */
|
||||
|
|
1074
src/util/uthash.h
1074
src/util/uthash.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue