From c658b55d738109d175afc107f16ae12fd3f04c17 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Fri, 31 Jan 2014 15:48:00 -0500 Subject: [PATCH] Add support for getting next timeout and number of pending events --- src/context.c | 18 +++++++++++ src/context.h | 4 +++ src/getdns/getdns.h | 6 ++-- src/test/check_getdns_common.h | 59 ++++++++++++++++++---------------- src/test/tests_stub_async.c | 9 +++--- 5 files changed, 60 insertions(+), 36 deletions(-) diff --git a/src/context.c b/src/context.c index 7c07a1a6..2d92afca 100644 --- a/src/context.c +++ b/src/context.c @@ -1182,6 +1182,24 @@ int getdns_context_fd(struct getdns_context* context) { return ub_fd(context->unbound_ctx); } +int +getdns_context_get_num_pending_requests(struct getdns_context* context, + struct timeval* next_timeout) { + RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT); + int r = context->outbound_requests->count; + if (r > 0) { + if (!context->extension && next_timeout) { + /* get the first timeout */ + ldns_rbnode_t* first = ldns_rbtree_first(context->timeouts_by_time); + if (first) { + getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) first->data; + *next_timeout = (timeout_data->timeout_time); + } + } + } + return r; +} + /* process async reqs */ getdns_return_t getdns_context_process_async(struct getdns_context* context) { RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT); diff --git a/src/context.h b/src/context.h index 319ce571..e34d555f 100644 --- a/src/context.h +++ b/src/context.h @@ -135,6 +135,10 @@ void getdns_bindata_destroy( getdns_return_t getdns_extension_set_eventloop(struct getdns_context* context, getdns_eventloop_extension* extension, void* extension_data); +getdns_return_t +getdns_extension_detach_eventloop(struct getdns_context* context); + + /* timeout scheduling */ getdns_return_t getdns_context_schedule_timeout(struct getdns_context* context, getdns_transaction_t id, uint16_t timeout, getdns_timeout_callback callback, diff --git a/src/getdns/getdns.h b/src/getdns/getdns.h index 566e0fa5..122fab9f 100644 --- a/src/getdns/getdns.h +++ b/src/getdns/getdns.h @@ -872,9 +872,9 @@ getdns_context_set_extended_memory_functions(struct getdns_context *context, void (*free) (void *userarg, void *ptr) ); -/* Extension */ -getdns_return_t -getdns_extension_detach_eventloop(struct getdns_context* context); +/* Async support */ +struct timeval; +int getdns_context_get_num_pending_requests(struct getdns_context* context, struct timeval* next_timeout); /* get the fd */ int getdns_context_fd(struct getdns_context* context); diff --git a/src/test/check_getdns_common.h b/src/test/check_getdns_common.h index 31f1e536..52858e0a 100644 --- a/src/test/check_getdns_common.h +++ b/src/test/check_getdns_common.h @@ -9,7 +9,7 @@ extern int callback_completed; extern int callback_canceled; extern uint16_t expected_changed_item; - + struct extracted_response { uint32_t top_answer_type; struct getdns_bindata *top_canonical_name; @@ -26,7 +26,7 @@ struct getdns_dict *question; uint32_t status; }; - + /* * The ASSERT_RC macro is used to assert * whether the return code from the last @@ -42,12 +42,12 @@ "%s: expecting %s: %d, but received: %d: %s", \ prefix, #expected_rc, expected_rc, evaluated_rc, error_string); \ } - + /* - * The CONTEXT_CREATE macro is used to + * The CONTEXT_CREATE macro is used to * create a context and assert the proper - * return code is returned. - */ + * return code is returned. + */ #define CONTEXT_CREATE(set_from_os) \ ASSERT_RC(getdns_context_create(&context, set_from_os), \ GETDNS_RETURN_GOOD, \ @@ -60,24 +60,27 @@ #define CONTEXT_DESTROY getdns_context_destroy(context); /* - * The EVENT_BASE_CREATE macro is used to - * create an event base and put it in the - * context. - */ + * The EVENT_BASE_CREATE macro is used to + * create an event base and put it in the + * context. + */ #define EVENT_BASE_CREATE \ event_base = event_base_new(); \ ck_assert_msg(event_base != NULL, "Event base creation failed"); \ ASSERT_RC(getdns_extension_set_libevent_base(context, event_base), \ GETDNS_RETURN_GOOD, \ "Return code from getdns_extension_set_libevent_base()"); - + /* * The RUN_EVENT_LOOP macro calls the event loop. */ - #define RUN_EVENT_LOOP event_base_dispatch(event_base); + #define RUN_EVENT_LOOP \ + while (getdns_context_get_num_pending_requests(context, NULL) > 0) { \ + event_base_loop(event_base, EVLOOP_ONCE); \ + } /* - * The LIST_CREATE macro simply creates a + * The LIST_CREATE macro simply creates a * list and verifies the returned pointer * is not NULL. */ @@ -92,7 +95,7 @@ #define LIST_DESTROY(list) getdns_list_destroy(list); /* - * The DICT_CREATE macro simply creates a + * The DICT_CREATE macro simply creates a * dict and verifies the returned pointer * is not NULL. */ @@ -105,8 +108,8 @@ * The DICT_DESTROY macro destroys a dict. */ #define DICT_DESTROY(dict) getdns_dict_destroy(dict); - - /* + + /* * The process_response macro declares the * variables needed to house the response and * calls the function that extracts it. @@ -116,14 +119,14 @@ extract_response(response, &ex_response); // - // FUNCTION DECLARATIONS - // + // FUNCTION DECLARATIONS + // /* * extract_response extracts all of the various information * a test may want to look at from the response. */ - void extract_response(struct getdns_dict *response, struct extracted_response *ex_response); + void extract_response(struct getdns_dict *response, struct extracted_response *ex_response); /* * assert_noerror asserts that the rcode is 0. @@ -137,10 +140,10 @@ void assert_nodata(struct extracted_response *ex_response); /* - * assert_address_records_in_answer asserts that ancount in - * the header * is >= 1, ancount is equal to the length - * of "answer", and that all of * the records in the - * answer section are A and/or AAAA resource records based + * assert_address_records_in_answer asserts that ancount in + * the header * is >= 1, ancount is equal to the length + * of "answer", and that all of * the records in the + * answer section are A and/or AAAA resource records based * on the value of the a/aaaa arguments. */ void assert_address_in_answer(struct extracted_response *ex_response, int a, int aaaa); @@ -169,17 +172,17 @@ * be called for positive tests and will verify the * response that is returned. */ - void callbackfn(struct getdns_context *context, + void callbackfn(struct getdns_context *context, uint16_t callback_type, - struct getdns_dict *response, + struct getdns_dict *response, void *userarg, getdns_transaction_t transaction_id); /* - * update_callbackfn is the callback function given to - * getdns_context_set_context_update_callback tests. + * update_callbackfn is the callback function given to + * getdns_context_set_context_update_callback tests. */ - void update_callbackfn(struct getdns_context *context, + void update_callbackfn(struct getdns_context *context, uint16_t changed_item); #endif diff --git a/src/test/tests_stub_async.c b/src/test/tests_stub_async.c index c9034aba..d43d3c4e 100644 --- a/src/test/tests_stub_async.c +++ b/src/test/tests_stub_async.c @@ -122,12 +122,11 @@ main(int argc, char** argv) // return(GETDNS_RETURN_GENERIC_ERROR); // } else { - struct timeval tv; - tv.tv_sec = 10; - tv.tv_usec = 0; /* Call the event loop */ - event_base_loopexit(this_event_base, &tv); - event_base_dispatch(this_event_base); + event_base_loop(this_event_base, EVLOOP_ONCE); + while (getdns_context_get_num_pending_requests(this_context, NULL) > 0) { + event_base_loop(this_event_base, EVLOOP_ONCE); + } // TODO: check the return value above } /* Clean up */