Miscelaneous fixes that came out of the unit tests

TODO: libuv still has issues.  Do we really need a close callback?
This commit is contained in:
Willem Toorop 2014-10-15 01:13:39 +02:00
parent 768d8fbf4d
commit a1be0c985d
19 changed files with 185 additions and 65 deletions

View File

@ -98,14 +98,14 @@ UTIL_OBJ=mini_event.lo rbtree.lo
.c.lo:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
$(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) libmini_event.lo:
@:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
default: all
all: libgetdns.la $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBUV_LIB) $(EXTENSION_LIBEV_LIB)
$(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) libmini_event.lo:
@:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
install: libgetdns.la
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)/getdns

View File

@ -260,7 +260,7 @@ upstreams_resize(getdns_upstreams *upstreams, size_t size)
static void
upstreams_dereference(getdns_upstreams *upstreams)
{
if (--upstreams->referenced == 0)
if (upstreams && --upstreams->referenced == 0)
GETDNS_FREE(upstreams->mf, upstreams);
}
@ -583,6 +583,7 @@ getdns_context_create_with_extended_memory_functions(
result->suffix = NULL;
result->dnssec_trust_anchors = NULL;
result->upstreams = NULL;
result->edns_extended_rcode = 0;
result->edns_version = 0;
@ -599,7 +600,7 @@ getdns_context_create_with_extended_memory_functions(
goto error;
result->dnssec_allowed_skew = 0;
result->edns_maximum_udp_payload_size = 512;
result->edns_maximum_udp_payload_size = 1232;
result->dns_transport = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP;
result->limit_outstanding_queries = 0;
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
@ -754,14 +755,26 @@ set_ub_number_opt(struct getdns_context *ctx, char *opt, uint16_t value)
static void
getdns_context_request_count_changed(getdns_context *context)
{
if (context->outbound_requests->count && !context->ub_event.ev)
DEBUG_SCHED("getdns_context_request_count_changed(%d)\n",
(int) context->outbound_requests->count);
if (context->outbound_requests->count) {
if (context->ub_event.ev) return;
DEBUG_SCHED("gc_request_count_changed "
"-> ub schedule(el_ev = %p, el_ev->ev = %p)\n",
&context->ub_event, context->ub_event.ev);
context->extension->vmt->schedule(
context->extension, ub_fd(context->unbound_ctx),
TIMEOUT_FOREVER, &context->ub_event);
}
else if (context->ub_event.ev) /* Only test if count == 0! */ {
DEBUG_SCHED("gc_request_count_changed "
"-> ub clear(el_ev = %p, el_ev->ev = %p)\n",
&context->ub_event, context->ub_event.ev);
else if (context->ub_event.ev)
context->extension->vmt->clear(
context->extension, &context->ub_event);
}
}
static void
@ -769,8 +782,20 @@ getdns_context_ub_read_cb(void *userarg)
{
getdns_context *context = (getdns_context *)userarg;
if (getdns_context_process_async(context)) return;
(void) getdns_context_get_num_pending_requests(context, NULL);
/* getdns_context_process_async, but without reinvoking an eventloop
* (with context->extension->vmt->run*), because we are already
* called from a running eventloop.
*/
context->processing = 1;
if (ub_poll(context->unbound_ctx) && ub_process(context->unbound_ctx)){
/* need an async return code? */
context->processing = 0;
return;
}
context->processing = 0;
/* No need to handle timeouts. They are handled by the extension. */
getdns_context_request_count_changed(context);
}
@ -800,10 +825,11 @@ rebuild_ub_ctx(struct getdns_context* context) {
context->unbound_ctx, TRUST_ANCHOR_FILE);
}
context->ub_event.userarg = context;
context->ub_event.read_cb = getdns_context_ub_read_cb;
context->ub_event.write_cb = NULL;
context->ub_event.userarg = context;
context->ub_event.read_cb = getdns_context_ub_read_cb;
context->ub_event.write_cb = NULL;
context->ub_event.timeout_cb = NULL;
context->ub_event.ev = NULL;
return GETDNS_RETURN_GOOD;
}
@ -1300,7 +1326,7 @@ invalid_parameter:
r = GETDNS_RETURN_INVALID_PARAMETER;
error:
upstreams_dereference(upstreams);
return r;
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} /* getdns_context_set_upstream_recursive_servers */
@ -1491,6 +1517,24 @@ getdns_context_cancel_request(struct getdns_context *context,
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;
context->processing = 1;
getdns_return_t r = getdns_context_cancel_request(context, transaction_id, 1);
context->processing = 0;
getdns_context_request_count_changed(context);
return r;
} /* getdns_cancel_callback */
static getdns_return_t
ub_setup_stub(struct ub_ctx *ctx, getdns_upstreams *upstreams)
{
@ -1803,6 +1847,8 @@ uint32_t
getdns_context_get_num_pending_requests(struct getdns_context* context,
struct timeval* next_timeout)
{
struct timeval dispose;
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
if (context->outbound_requests->count)
@ -1810,7 +1856,7 @@ getdns_context_get_num_pending_requests(struct getdns_context* context,
/* TODO: Remove this when next_timeout is gone */
getdns_handle_timeouts(context->mini_event.base,
&context->mini_event.time_tv, next_timeout);
&context->mini_event.time_tv, next_timeout ? next_timeout : &dispose);
return context->outbound_requests->count;
}
@ -1836,7 +1882,9 @@ getdns_context_process_async(struct getdns_context* context)
void
getdns_context_run(getdns_context *context)
{
context->extension->vmt->run(context->extension);
if (getdns_context_get_num_pending_requests(context, NULL) > 0 &&
!getdns_context_process_async(context))
context->extension->vmt->run(context->extension);
}
typedef struct timeout_accumulator {

View File

@ -106,7 +106,7 @@ getdns_libev_write_cb(struct ev_loop *l, struct ev_io *io, int revents)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)io->data;
assert(el_ev->write_cb);
el_ev->read_cb(el_ev->userarg);
el_ev->write_cb(el_ev->userarg);
}
static void
@ -169,20 +169,18 @@ getdns_extension_set_libev_loop(getdns_context *context,
getdns_libev_run_once
};
getdns_libev *ext;
getdns_return_t r;
if (!context)
return GETDNS_RETURN_BAD_CONTEXT;
if (!loop)
return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_context_detach_eventloop(context)))
return r;
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libev);
if (!ext)
return GETDNS_RETURN_MEMORY_ERROR;
ext->vmt = &getdns_libev_vmt;
ext->loop = loop;
ext->mf = *priv_getdns_context_mf(context);
return getdns_context_set_eventloop(context, (getdns_eventloop *)&ext);
return getdns_context_set_eventloop(context, (getdns_eventloop *)ext);
}

View File

@ -177,20 +177,19 @@ getdns_extension_set_libevent_base(getdns_context *context,
getdns_libevent_run_once
};
getdns_libevent *ext;
getdns_return_t r;
if (!context)
return GETDNS_RETURN_BAD_CONTEXT;
if (!base)
return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_context_detach_eventloop(context)))
return r;
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libevent);
if (!ext)
return GETDNS_RETURN_MEMORY_ERROR;
ext->vmt = &getdns_libevent_vmt;
ext->base = base;
ext->mf = *priv_getdns_context_mf(context);
return getdns_context_set_eventloop(context, (getdns_eventloop *)&ext);
return getdns_context_set_eventloop(context, (getdns_eventloop *)ext);
}

View File

@ -107,19 +107,20 @@ getdns_mini_event_run_once(getdns_eventloop *loop, int blocking)
static getdns_return_t
getdns_mini_event_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
{
getdns_return_t r;
getdns_mini_event *ext = (getdns_mini_event *)loop;
assert(el_ev->ev);
if (getdns_event_del(el_ev->ev) != 0)
return GETDNS_RETURN_GENERIC_ERROR;
r = GETDNS_RETURN_GENERIC_ERROR;
GETDNS_FREE(ext->mf, el_ev->ev);
el_ev->ev = NULL;
ext->n_events--;
return GETDNS_RETURN_GOOD;
return r;
}
static void

View File

@ -75,6 +75,8 @@ getdns_libuv_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
assert(my_ev);
DEBUG_SCHED("enter libuv_clear(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
if (el_ev->read_cb) {
uv_poll_stop(&my_ev->read);
uv_close((uv_handle_t *)&my_ev->read, NULL);
@ -83,12 +85,13 @@ getdns_libuv_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
uv_poll_stop(&my_ev->write);
uv_close((uv_handle_t *)&my_ev->write, NULL);
}
if (el_ev->timeout_cb)
if (el_ev->timeout_cb) {
uv_timer_stop(&my_ev->timer);
uv_close((uv_handle_t *)&my_ev->timer, NULL);
}
GETDNS_FREE(ext->mf, el_ev->ev);
el_ev->ev = NULL;
DEBUG_SCHED("exit libuv_clear(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
return GETDNS_RETURN_GOOD;
}
@ -97,7 +100,9 @@ getdns_libuv_read_cb(uv_poll_t *poll, int status, int events)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)poll->data;
assert(el_ev->read_cb);
DEBUG_SCHED("enter libuv_read_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
el_ev->read_cb(el_ev->userarg);
DEBUG_SCHED("exit libuv_read_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
}
static void
@ -105,7 +110,9 @@ getdns_libuv_write_cb(uv_poll_t *poll, int status, int events)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)poll->data;
assert(el_ev->write_cb);
DEBUG_SCHED("enter libuv_write_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
el_ev->write_cb(el_ev->userarg);
DEBUG_SCHED("exit libuv_write_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
}
static void
@ -113,7 +120,9 @@ getdns_libuv_timeout_cb(uv_timer_t *timer, int status)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
assert(el_ev->timeout_cb);
DEBUG_SCHED("enter libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
el_ev->timeout_cb(el_ev->userarg);
DEBUG_SCHED("exit libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
}
static getdns_return_t
@ -129,6 +138,8 @@ getdns_libuv_schedule(getdns_eventloop *loop,
assert(!(el_ev->read_cb || el_ev->write_cb) || fd >= 0);
assert( el_ev->read_cb || el_ev->write_cb || el_ev->timeout_cb);
DEBUG_SCHED("enter libuv_schedule(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
if (!(my_ev = GETDNS_MALLOC(ext->mf, poll_timer)))
return GETDNS_RETURN_MEMORY_ERROR;
@ -152,6 +163,7 @@ getdns_libuv_schedule(getdns_eventloop *loop,
my_timer->data = el_ev;
uv_timer_start(my_timer, getdns_libuv_timeout_cb, timeout, 0);
}
DEBUG_SCHED("exit libuv_schedule(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
return GETDNS_RETURN_GOOD;
}
@ -166,20 +178,18 @@ getdns_extension_set_libuv_loop(getdns_context *context, uv_loop_t *loop)
getdns_libuv_run_once
};
getdns_libuv *ext;
getdns_return_t r;
if (!context)
return GETDNS_RETURN_BAD_CONTEXT;
if (!loop)
return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_context_detach_eventloop(context)))
return r;
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libuv);
if (!ext)
return GETDNS_RETURN_MEMORY_ERROR;
ext->vmt = &getdns_libuv_vmt;
ext->loop = loop;
ext->mf = *priv_getdns_context_mf(context);
return getdns_context_set_eventloop(context, (getdns_eventloop *)&ext);
return getdns_context_set_eventloop(context, (getdns_eventloop *)ext);
}

View File

@ -126,7 +126,7 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
// char *bogus)
{
getdns_network_req *netreq = (getdns_network_req *) arg;
getdns_dns_req *dnsreq = netreq->owner;
getdns_dns_req *dns_req = netreq->owner;
netreq->state = NET_REQ_FINISHED;
if (err != 0) {
@ -141,14 +141,14 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
}
ub_resolve_free(ub_res);
netreq = dnsreq->first_req;
netreq = dns_req->first_req;
while (netreq) {
if (netreq->state != NET_REQ_FINISHED &&
netreq->state != NET_REQ_CANCELED)
return;
netreq = netreq->next;
}
handle_dns_request_complete(dnsreq);
handle_dns_request_complete(dns_req);
} /* ub_resolve_callback */
getdns_return_t
@ -163,7 +163,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
getdns_dict *localnames_response;
size_t i;
if (!context || !name)
if (!context || !name || !callbackfn)
return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = validate_dname(name)))
@ -210,18 +210,19 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) {
if (!(r = getdns_context_local_namespace_resolve(
req, &localnames_response, context)))
req, &localnames_response, context))) {
priv_getdns_call_user_callback
( req, localnames_response);
break;
break;
}
} else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) {
/* TODO: We will get a good return code here even if
the name is not found (NXDOMAIN). We should consider
if this means we go onto the next namespace instead
of returning */
r = GETDNS_RETURN_GOOD;
netreq = req->first_req;
while (!r && netreq) {
r = submit_network_request(netreq);
@ -289,6 +290,7 @@ getdns_general(getdns_context *context,
void *userarg, getdns_transaction_t * transaction_id,
getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_general_loop(context, context->extension,
name, request_type, extensions,
userarg, transaction_id, callback);
@ -304,6 +306,7 @@ getdns_address(getdns_context *context,
const char *name, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_address_loop(context, context->extension,
name, extensions, userarg,
transaction_id, callback);

View File

@ -96,6 +96,7 @@ getdns_hostname(getdns_context *context,
getdns_dict *address, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_hostname_loop(context, context->extension,
address, extensions, userarg, transaction_id, callback);
} /* getdns_hostname */

View File

@ -98,3 +98,5 @@ getdns_context_process_async
getdns_context_set_eventloop
getdns_context_detach_eventloop
getdns_context_run
plain_mem_funcs_user_arg
priv_getdns_context_mf

View File

@ -8,6 +8,8 @@ write_symbols() {
}
write_symbols libgetdns.symbols getdns/getdns.h.in getdns/getdns_extra.h
echo plain_mem_funcs_user_arg >> libgetdns.symbols
echo priv_getdns_context_mf >> libgetdns.symbols
write_symbols extension/libevent.symbols getdns/getdns_ext_libevent.h
write_symbols extension/libev.symbols getdns/getdns_ext_libev.h
write_symbols extension/libuv.symbols getdns/getdns_ext_libuv.h

View File

@ -125,7 +125,7 @@ dns_req_new(struct getdns_context *context, getdns_eventloop *loop,
result->canceled = 0;
result->current_req = NULL;
result->first_req = NULL;
result->trans_id = (((uint64_t) ldns_get_random()) << 32)
result->trans_id = ((uint64_t) ldns_get_random())
^ ((intptr_t) result);
getdns_dict_copy(extensions, &result->extensions);

View File

@ -60,6 +60,7 @@ getdns_service(getdns_context *context,
const char *name, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_service_loop(context, context->extension,
name, extensions, userarg, transaction_id, callback);
} /* getdns_service */

View File

@ -118,6 +118,10 @@ query_ns(stub_resolver *resolver)
*/
/* TODO: Check how to connect first (udp or tcp) */
if (resolver->context->dns_transport != GETDNS_TRANSPORT_UDP_ONLY &&
resolver->context->dns_transport !=
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP)
return GETDNS_RETURN_GENERIC_ERROR;
resolver->udp_fd = socket(upstream->addr.ss_family, SOCK_DGRAM,
IPPROTO_UDP);

View File

@ -72,6 +72,9 @@ default: all
all: $(PROGRAMS)
check_getdns_libuv.lo: check_getdns_libuv.c
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -D_GNU_SOURCE -c $< -o $@
tests_dict: tests_dict.lo testmessages.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_dict.lo testmessages.lo

View File

@ -201,8 +201,7 @@
void verify_getdns_address_7(struct extracted_response *ex_response)
{
assert_noerror(ex_response);
assert_address_in_answer(ex_response, TRUE, TRUE);
assert_address_in_just_address_answers(ex_response);
}
START_TEST (getdns_address_8)

View File

@ -49,10 +49,22 @@ int event_loop_type = 0;
*/
void extract_response(struct getdns_dict *response, struct extracted_response *ex_response)
{
ck_assert_msg(response != NULL, "Response should not be NULL");
int have_answer_type = 0;
ASSERT_RC(getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type),
GETDNS_RETURN_GOOD, "Failed to extract \"top answer_type\"");
ck_assert_msg(response != NULL, "Response should not be NULL");
/* fprintf(stderr, "%s\n", getdns_pretty_print_dict(response)); */
/* answer_type is optional. See spec section 4:
* "The top level of replies_tree can optionally have the following names:
* canonical_name (a bindata), intermediate_aliases (a list),
* answer_ipv4_address (a bindata), answer_ipv6_address (a bindata),
* and answer_type (an int)."
*
* If it is absent, do not try to decompose the replies_tree, because the
* answer most likely came not from DNS.
*/
have_answer_type = getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type) ==
GETDNS_RETURN_GOOD;
ASSERT_RC(getdns_dict_get_bindata(response, "canonical_name", &ex_response->top_canonical_name),
GETDNS_RETURN_GOOD, "Failed to extract \"top canonical_name\"");
@ -69,6 +81,21 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree\"");
ck_assert_msg(ex_response->replies_tree != NULL, "replies_tree should not be NULL");
ASSERT_RC(getdns_dict_get_int(response, "status", &ex_response->status),
GETDNS_RETURN_GOOD, "Failed to extract \"status\"");
if (!have_answer_type || ex_response->top_answer_type != GETDNS_NAMETYPE_DNS) {
ex_response->replies_tree_sub_dict = NULL;
ex_response->additional = NULL;
ex_response->answer = NULL;
ex_response->answer_type = 0;
ex_response->authority = NULL;
ex_response->canonical_name = NULL;
ex_response->header = NULL;
ex_response->question = NULL;
return;
}
ASSERT_RC(getdns_list_get_dict(ex_response->replies_tree, 0, &ex_response->replies_tree_sub_dict),
GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree[0]\"");
ck_assert_msg(ex_response->replies_tree_sub_dict != NULL, "replies_tree[0] dict should not be NULL");
@ -98,9 +125,6 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "question", &ex_response->question),
GETDNS_RETURN_GOOD, "Failed to extract \"question\"");
ck_assert_msg(ex_response->question != NULL, "question should not be NULL");
ASSERT_RC(getdns_dict_get_int(response, "status", &ex_response->status),
GETDNS_RETURN_GOOD, "Failed to extract \"status\"");
}
/*
@ -195,6 +219,19 @@ void assert_address_in_answer(struct extracted_response *ex_response, int a, int
ancount, address_records);
}
/*
* assert_address_in_just_address_answers asserts that just_address_answers
* contains at least one address.
*/
void assert_address_in_just_address_answers(struct extracted_response *ex_response)
{
size_t length;
ASSERT_RC(getdns_list_get_length(ex_response->just_address_answers, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\" length");
ck_assert_msg(length > 0, "Expected \"just_address_answers\" length > 0, got %d", length);
}
/*
* assert_nxdomain asserts that an NXDOMAIN response was
* was returned for the DNS query meaning:

View File

@ -183,6 +183,12 @@
*/
void assert_address_in_answer(struct extracted_response *ex_response, int a, int aaaa);
/*
* assert_address_in_just_address_answers asserts that
* just_address_answers contains at least one address.
*/
void assert_address_in_just_address_answers(struct extracted_response *ex_response);
/*
* assert_nxdomain asserts that an NXDOMAIN response was
* was returned for the DNS query meaning rcode == 3.

View File

@ -37,21 +37,9 @@
#include "getdns/getdns_extra.h"
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
struct timeval tv;
while (getdns_context_get_num_pending_requests(context, &tv) > 0) {
int fd = getdns_context_fd(context);
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
select(fd + 1, &read_fds, NULL, NULL, &tv);
if (getdns_context_process_async(context) != GETDNS_RETURN_GOOD) {
// context destroyed
break;
}
}
getdns_context_run(context);
}
void* create_eventloop_impl(struct getdns_context* context) {
return NULL;
}

View File

@ -257,4 +257,22 @@ void dns_req_free(getdns_dns_req * req);
#endif
#define SCHED_DEBUG 0
#if defined(SCHED_DEBUG) && SCHED_DEBUG
#include <time.h>
#define DEBUG_SCHED(...) do { \
struct timeval tv; \
struct tm tm; \
char buf[10]; \
\
gettimeofday(&tv, NULL); \
gmtime_r(&tv.tv_sec, &tm); \
strftime(buf, 10, "%T", &tm); \
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
fprintf(stderr, __VA_ARGS__); \
} while (false)
#else
#define DEBUG_SCHED(...) do {} while (false)
#endif
/* types-internal.h */