From a83c54387dcc7cb80594965bdb05d5380d6405e7 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 9 Mar 2016 11:16:19 +0100 Subject: [PATCH] Reuse sync eventloop per context So recursive resolution can depend on and continue with outstanding queries it depends on --- src/context.c | 5 ++- src/context.h | 1 + src/sync.c | 116 +++++++++++++++++++++++--------------------------- 3 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/context.c b/src/context.c index 8501f730..89af5673 100644 --- a/src/context.c +++ b/src/context.c @@ -1156,6 +1156,7 @@ getdns_context_create_with_extended_memory_functions( result->extension = &result->default_eventloop.loop; _getdns_default_eventloop_init(&result->default_eventloop); + _getdns_default_eventloop_init(&result->sync_eventloop); result->fchg_resolvconf = NULL; result->fchg_hosts = NULL; @@ -1260,13 +1261,13 @@ getdns_context_destroy(struct getdns_context *context) */ _getdns_upstreams_dereference(context->upstreams); + context->sync_eventloop.loop.vmt->cleanup(&context->sync_eventloop.loop); + context->extension->vmt->cleanup(context->extension); #ifdef HAVE_LIBUNBOUND if (context->unbound_ctx) ub_ctx_delete(context->unbound_ctx); #endif - context->extension->vmt->cleanup(context->extension); - if (context->namespaces) GETDNS_FREE(context->my_mf, context->namespaces); diff --git a/src/context.h b/src/context.h index d3bff070..51457632 100644 --- a/src/context.h +++ b/src/context.h @@ -249,6 +249,7 @@ struct getdns_context { /* The default extension */ _getdns_default_eventloop default_eventloop; + _getdns_default_eventloop sync_eventloop; /* * state data used to detect changes to the system config files diff --git a/src/sync.c b/src/sync.c index 3dd4af86..2b15c445 100644 --- a/src/sync.c +++ b/src/sync.c @@ -45,36 +45,33 @@ #include "stub.h" #include "gldns/wire2str.h" -typedef struct getdns_sync_loop { - _getdns_default_eventloop loop; +typedef struct getdns_sync_data { #ifdef HAVE_LIBUNBOUND getdns_eventloop_event ub_event; #endif getdns_context *context; int to_run; getdns_dict *response; -} getdns_sync_loop; +} getdns_sync_data; static getdns_return_t -getdns_sync_loop_init(getdns_context *context, getdns_sync_loop *loop) +getdns_sync_data_init(getdns_context *context, getdns_sync_data *data) { #ifdef HAVE_LIBUNBOUND - getdns_eventloop *ext = &loop->loop.loop; + getdns_eventloop *ext = &context->sync_eventloop.loop; #endif - loop->response = NULL; - loop->to_run = 1; - loop->context = context; - - _getdns_default_eventloop_init(&loop->loop); + data->context = context; + data->to_run = 1; + data->response = NULL; #ifdef HAVE_LIBUNBOUND # ifndef USE_WINSOCK - loop->ub_event.userarg = loop->context; - loop->ub_event.read_cb = _getdns_context_ub_read_cb; - loop->ub_event.write_cb = NULL; - loop->ub_event.timeout_cb = NULL; - loop->ub_event.ev = NULL; + data->ub_event.userarg = data->context; + data->ub_event.read_cb = _getdns_context_ub_read_cb; + data->ub_event.write_cb = NULL; + data->ub_event.timeout_cb = NULL; + data->ub_event.ev = NULL; # endif # ifdef HAVE_UNBOUND_EVENT_API if (_getdns_ub_loop_enabled(&context->ub_loop)) { @@ -83,7 +80,7 @@ getdns_sync_loop_init(getdns_context *context, getdns_sync_loop *loop) # endif # ifndef USE_WINSOCK return ext->vmt->schedule(ext, ub_fd(context->unbound_ctx), - TIMEOUT_FOREVER, &loop->ub_event); + TIMEOUT_FOREVER, &data->ub_event); # else /* No sync full recursion requests on windows without * UNBOUND_EVENT_API because ub_fd() doesn't work on windows. @@ -95,66 +92,61 @@ getdns_sync_loop_init(getdns_context *context, getdns_sync_loop *loop) } static void -getdns_sync_loop_cleanup(getdns_sync_loop *loop) +getdns_sync_data_cleanup(getdns_sync_data *data) { - getdns_eventloop *ext = &loop->loop.loop; - #if defined(HAVE_LIBUNBOUND) && !defined(USE_WINSOCK) # ifdef HAVE_UNBOUND_EVENT_API - if (_getdns_ub_loop_enabled(&loop->context->ub_loop)) { - loop->context->ub_loop.extension = loop->context->extension; + if (_getdns_ub_loop_enabled(&data->context->ub_loop)) { + data->context->ub_loop.extension = data->context->extension; } else # endif - ext->vmt->clear(ext, &loop->ub_event); + data->context->sync_eventloop.loop.vmt->clear( + &data->context->sync_eventloop.loop, &data->ub_event); #endif - ext->vmt->cleanup(ext); } static void -getdns_sync_loop_run(getdns_sync_loop *loop) +getdns_sync_loop_run(getdns_sync_data *data) { - getdns_eventloop *ext = &loop->loop.loop; - - while (loop->to_run) - ext->vmt->run_once(ext, 1); - - getdns_sync_loop_cleanup(loop); + while (data->to_run) + data->context->sync_eventloop.loop.vmt->run_once( + &data->context->sync_eventloop.loop, 1); } static void getdns_sync_cb(getdns_context *context, getdns_callback_type_t callback_type, getdns_dict *response, void *userarg, getdns_transaction_t transaction_id) { - getdns_sync_loop *loop = (getdns_sync_loop *)userarg; + getdns_sync_data *data = (getdns_sync_data *)userarg; - assert(loop); + assert(data); - loop->response = response; - loop->to_run = 0; + data->response = response; + data->to_run = 0; } getdns_return_t getdns_general_sync(getdns_context *context, const char *name, uint16_t request_type, getdns_dict *extensions, getdns_dict **response) { - getdns_sync_loop loop; + getdns_sync_data data; getdns_return_t r; if (!context || !name || !response) return GETDNS_RETURN_INVALID_PARAMETER; - if ((r = getdns_sync_loop_init(context, &loop))) + if ((r = getdns_sync_data_init(context, &data))) return r; - if ((r = _getdns_general_loop(context, &loop.loop.loop, name, - request_type, extensions, &loop, NULL, getdns_sync_cb, NULL))) { + if ((r = _getdns_general_loop(context, &context->sync_eventloop.loop, + name, request_type, extensions, &data, NULL, getdns_sync_cb, NULL))) { - getdns_sync_loop_cleanup(&loop); + getdns_sync_data_cleanup(&data); return r; } - getdns_sync_loop_run(&loop); + getdns_sync_loop_run(&data); - return (*response = loop.response) ? + return (*response = data.response) ? GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR; } @@ -162,24 +154,24 @@ getdns_return_t getdns_address_sync(getdns_context *context, const char *name, getdns_dict *extensions, getdns_dict **response) { - getdns_sync_loop loop; + getdns_sync_data data; getdns_return_t r; if (!context || !name || !response) return GETDNS_RETURN_INVALID_PARAMETER; - if ((r = getdns_sync_loop_init(context, &loop))) + if ((r = getdns_sync_data_init(context, &data))) return r; - if ((r = _getdns_address_loop(context, &loop.loop.loop, name, - extensions, &loop, NULL, getdns_sync_cb))) { + if ((r = _getdns_address_loop(context, &context->sync_eventloop.loop, + name, extensions, &data, NULL, getdns_sync_cb))) { - getdns_sync_loop_cleanup(&loop); + getdns_sync_data_cleanup(&data); return r; } - getdns_sync_loop_run(&loop); + getdns_sync_loop_run(&data); - return (*response = loop.response) ? + return (*response = data.response) ? GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR; } @@ -187,24 +179,24 @@ getdns_return_t getdns_hostname_sync(getdns_context *context, getdns_dict *address, getdns_dict *extensions, getdns_dict **response) { - getdns_sync_loop loop; + getdns_sync_data data; getdns_return_t r; if (!context || !address || !response) return GETDNS_RETURN_INVALID_PARAMETER; - if ((r = getdns_sync_loop_init(context, &loop))) + if ((r = getdns_sync_data_init(context, &data))) return r; - if ((r = _getdns_hostname_loop(context, &loop.loop.loop, address, - extensions, &loop, NULL, getdns_sync_cb))) { + if ((r = _getdns_hostname_loop(context, &context->sync_eventloop.loop, + address, extensions, &data, NULL, getdns_sync_cb))) { - getdns_sync_loop_cleanup(&loop); + getdns_sync_data_cleanup(&data); return r; } - getdns_sync_loop_run(&loop); + getdns_sync_loop_run(&data); - return (*response = loop.response) ? + return (*response = data.response) ? GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR; } @@ -212,24 +204,24 @@ getdns_return_t getdns_service_sync(getdns_context *context, const char *name, getdns_dict *extensions, getdns_dict **response) { - getdns_sync_loop loop; + getdns_sync_data data; getdns_return_t r; if (!context || !name || !response) return GETDNS_RETURN_INVALID_PARAMETER; - if ((r = getdns_sync_loop_init(context, &loop))) + if ((r = getdns_sync_data_init(context, &data))) return r; - if ((r = _getdns_service_loop(context, &loop.loop.loop, name, - extensions, &loop, NULL, getdns_sync_cb))) { + if ((r = _getdns_service_loop(context, &context->sync_eventloop.loop, + name, extensions, &data, NULL, getdns_sync_cb))) { - getdns_sync_loop_cleanup(&loop); + getdns_sync_data_cleanup(&data); return r; } - getdns_sync_loop_run(&loop); + getdns_sync_loop_run(&data); - return (*response = loop.response) ? + return (*response = data.response) ? GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR; }