mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'master' of https://github.com/getdnsapi/getdns
This commit is contained in:
commit
29641b186c
|
@ -416,6 +416,7 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
result->processing = 0;
|
||||||
result->destroying = 0;
|
result->destroying = 0;
|
||||||
result->my_mf.mf_arg = userarg;
|
result->my_mf.mf_arg = userarg;
|
||||||
result->my_mf.mf.ext.malloc = malloc;
|
result->my_mf.mf.ext.malloc = malloc;
|
||||||
|
@ -534,6 +535,12 @@ getdns_context_destroy(struct getdns_context *context)
|
||||||
if (context == NULL) {
|
if (context == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// If being destroyed during getdns callback, just flag it
|
||||||
|
// and destroy. See getdns_context_process_async
|
||||||
|
if (context->processing > 0) {
|
||||||
|
context->processing++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
context->destroying = 1;
|
context->destroying = 1;
|
||||||
cancel_outstanding_requests(context, 1);
|
cancel_outstanding_requests(context, 1);
|
||||||
getdns_extension_detach_eventloop(context);
|
getdns_extension_detach_eventloop(context);
|
||||||
|
@ -1505,12 +1512,24 @@ getdns_context_get_num_pending_requests(struct getdns_context* context,
|
||||||
/* process async reqs */
|
/* process async reqs */
|
||||||
getdns_return_t getdns_context_process_async(struct getdns_context* context) {
|
getdns_return_t getdns_context_process_async(struct getdns_context* context) {
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
context->processing = 1;
|
||||||
if (ub_poll(context->unbound_ctx)) {
|
if (ub_poll(context->unbound_ctx)) {
|
||||||
if (ub_process(context->unbound_ctx) != 0) {
|
if (ub_process(context->unbound_ctx) != 0) {
|
||||||
/* need an async return code? */
|
/* need an async return code? */
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (context->processing > 1) {
|
||||||
|
// destroyed during callbacks
|
||||||
|
// clear flag so destroy continues
|
||||||
|
context->processing = 0;
|
||||||
|
getdns_context_destroy(context);
|
||||||
|
// return bad context now that the context
|
||||||
|
// is destroyed
|
||||||
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
}
|
||||||
|
// reset the processing flag
|
||||||
|
context->processing = 0;
|
||||||
if (context->extension != NULL) {
|
if (context->extension != NULL) {
|
||||||
/* no need to process timeouts since it is delegated
|
/* no need to process timeouts since it is delegated
|
||||||
* to the extension */
|
* to the extension */
|
||||||
|
|
|
@ -90,6 +90,7 @@ struct getdns_context {
|
||||||
|
|
||||||
getdns_update_callback update_callback;
|
getdns_update_callback update_callback;
|
||||||
|
|
||||||
|
int processing;
|
||||||
int destroying;
|
int destroying;
|
||||||
|
|
||||||
struct mem_funcs mf;
|
struct mem_funcs mf;
|
||||||
|
|
|
@ -59,7 +59,10 @@ request_count_changed(uint32_t request_count, struct getdns_libev_data *ev_data)
|
||||||
static void
|
static void
|
||||||
getdns_libev_cb(struct ev_loop *loop, struct ev_io *handle, int revents) {
|
getdns_libev_cb(struct ev_loop *loop, struct ev_io *handle, int revents) {
|
||||||
struct getdns_context* context = (struct getdns_context*) handle->data;
|
struct getdns_context* context = (struct getdns_context*) handle->data;
|
||||||
getdns_context_process_async(context);
|
if (getdns_context_process_async(context) == GETDNS_RETURN_BAD_CONTEXT) {
|
||||||
|
// context destroyed
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint32_t rc = getdns_context_get_num_pending_requests(context, NULL);
|
uint32_t rc = getdns_context_get_num_pending_requests(context, NULL);
|
||||||
struct getdns_libev_data* ev_data =
|
struct getdns_libev_data* ev_data =
|
||||||
(struct getdns_libev_data*) getdns_context_get_extension_data(context);
|
(struct getdns_libev_data*) getdns_context_get_extension_data(context);
|
||||||
|
|
|
@ -88,7 +88,10 @@ request_count_changed(uint32_t request_count, struct event_data *ev_data) {
|
||||||
static void
|
static void
|
||||||
getdns_libevent_cb(evutil_socket_t fd, short what, void *userarg) {
|
getdns_libevent_cb(evutil_socket_t fd, short what, void *userarg) {
|
||||||
struct getdns_context* context = (struct getdns_context*) userarg;
|
struct getdns_context* context = (struct getdns_context*) userarg;
|
||||||
getdns_context_process_async(context);
|
if (getdns_context_process_async(context) == GETDNS_RETURN_BAD_CONTEXT) {
|
||||||
|
// context destroyed
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint32_t rc = getdns_context_get_num_pending_requests(context, NULL);
|
uint32_t rc = getdns_context_get_num_pending_requests(context, NULL);
|
||||||
struct event_data* ev_data =
|
struct event_data* ev_data =
|
||||||
(struct event_data*) getdns_context_get_extension_data(context);
|
(struct event_data*) getdns_context_get_extension_data(context);
|
||||||
|
|
|
@ -53,7 +53,10 @@ static void request_count_changed(uint32_t request_count, struct getdns_libuv_da
|
||||||
static void
|
static void
|
||||||
getdns_libuv_cb(uv_poll_t* handle, int status, int events) {
|
getdns_libuv_cb(uv_poll_t* handle, int status, int events) {
|
||||||
struct getdns_context* context = (struct getdns_context*) handle->data;
|
struct getdns_context* context = (struct getdns_context*) handle->data;
|
||||||
getdns_context_process_async(context);
|
if (getdns_context_process_async(context) == GETDNS_RETURN_BAD_CONTEXT) {
|
||||||
|
// context destroyed
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint32_t rc = getdns_context_get_num_pending_requests(context, NULL);
|
uint32_t rc = getdns_context_get_num_pending_requests(context, NULL);
|
||||||
struct getdns_libuv_data* uv_data =
|
struct getdns_libuv_data* uv_data =
|
||||||
(struct getdns_libuv_data*) getdns_context_get_extension_data(context);
|
(struct getdns_libuv_data*) getdns_context_get_extension_data(context);
|
||||||
|
|
|
@ -258,6 +258,17 @@ void assert_ptr_in_answer(struct extracted_response *ex_response)
|
||||||
ck_assert_msg(ptr_records == 1, "Expected to find one PTR record in answer section, got %d", ptr_records);
|
ck_assert_msg(ptr_records == 1, "Expected to find one PTR record in answer section, got %d", ptr_records);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroy_callbackfn(struct getdns_context *context,
|
||||||
|
getdns_callback_type_t callback_type,
|
||||||
|
struct getdns_dict *response,
|
||||||
|
void *userarg,
|
||||||
|
getdns_transaction_t transaction_id) {
|
||||||
|
int* flag = (int*)userarg;
|
||||||
|
*flag = 1;
|
||||||
|
getdns_dict_destroy(response);
|
||||||
|
getdns_context_destroy(context);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* callbackfn is the callback function given to all
|
* callbackfn is the callback function given to all
|
||||||
* asynchronous query tests. It is expected to only
|
* asynchronous query tests. It is expected to only
|
||||||
|
|
|
@ -186,6 +186,12 @@
|
||||||
*/
|
*/
|
||||||
void assert_ptr_in_answer(struct extracted_response *ex_response);
|
void assert_ptr_in_answer(struct extracted_response *ex_response);
|
||||||
|
|
||||||
|
|
||||||
|
void destroy_callbackfn(struct getdns_context *context,
|
||||||
|
getdns_callback_type_t callback_type,
|
||||||
|
struct getdns_dict *response,
|
||||||
|
void *userarg,
|
||||||
|
getdns_transaction_t transaction_id);
|
||||||
/*
|
/*
|
||||||
* callbackfn is the callback function given to all
|
* callbackfn is the callback function given to all
|
||||||
* asynchronous query tests. It is expected to only
|
* asynchronous query tests. It is expected to only
|
||||||
|
|
|
@ -177,6 +177,31 @@
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (getdns_context_destroy_7)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* destroy called immediately following getdns_address
|
||||||
|
* expect: callback should be called before getdns_context_destroy() returns
|
||||||
|
*/
|
||||||
|
struct getdns_context *context = NULL;
|
||||||
|
void* eventloop = NULL;
|
||||||
|
getdns_transaction_t transaction_id = 0;
|
||||||
|
|
||||||
|
int flag = 0; /* Initialize flag */
|
||||||
|
|
||||||
|
CONTEXT_CREATE(TRUE);
|
||||||
|
EVENT_BASE_CREATE;
|
||||||
|
|
||||||
|
ASSERT_RC(getdns_address(context, "google.com", NULL,
|
||||||
|
&flag, &transaction_id, destroy_callbackfn),
|
||||||
|
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
|
||||||
|
|
||||||
|
RUN_EVENT_LOOP;
|
||||||
|
|
||||||
|
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
void verify_getdns_context_destroy(struct extracted_response *ex_response)
|
void verify_getdns_context_destroy(struct extracted_response *ex_response)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -208,6 +233,7 @@
|
||||||
tcase_add_test(tc_pos, getdns_context_destroy_4);
|
tcase_add_test(tc_pos, getdns_context_destroy_4);
|
||||||
tcase_add_test(tc_pos, getdns_context_destroy_5);
|
tcase_add_test(tc_pos, getdns_context_destroy_5);
|
||||||
tcase_add_test(tc_pos, getdns_context_destroy_6);
|
tcase_add_test(tc_pos, getdns_context_destroy_6);
|
||||||
|
tcase_add_test(tc_pos, getdns_context_destroy_7);
|
||||||
suite_add_tcase(s, tc_pos);
|
suite_add_tcase(s, tc_pos);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
|
@ -44,7 +44,10 @@ void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_SET(fd, &read_fds);
|
FD_SET(fd, &read_fds);
|
||||||
select(fd + 1, &read_fds, NULL, NULL, &tv);
|
select(fd + 1, &read_fds, NULL, NULL, &tv);
|
||||||
getdns_context_process_async(context);
|
if (getdns_context_process_async(context) != GETDNS_RETURN_GOOD) {
|
||||||
|
// context destroyed
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue