mirror of https://github.com/getdnsapi/getdns.git
Possible fix for #21 and tests
This commit is contained in:
parent
6ab9ce861b
commit
3f8e8ac098
|
@ -541,6 +541,9 @@ getdns_context_destroy(struct getdns_context *context)
|
||||||
context->processing++;
|
context->processing++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (context->destroying) {
|
||||||
|
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);
|
||||||
|
@ -1210,11 +1213,18 @@ getdns_cancel_callback(struct getdns_context *context,
|
||||||
getdns_transaction_t transaction_id)
|
getdns_transaction_t transaction_id)
|
||||||
{
|
{
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
context->processing = 1;
|
||||||
getdns_return_t r = getdns_context_cancel_request(context, transaction_id, 1);
|
getdns_return_t r = getdns_context_cancel_request(context, transaction_id, 1);
|
||||||
if (context->extension) {
|
if (context->extension) {
|
||||||
context->extension->request_count_changed(context,
|
context->extension->request_count_changed(context,
|
||||||
context->outbound_requests->count, context->extension_data);
|
context->outbound_requests->count, context->extension_data);
|
||||||
}
|
}
|
||||||
|
if (context->processing > 1) {
|
||||||
|
context->processing = 0;
|
||||||
|
getdns_context_destroy(context);
|
||||||
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
}
|
||||||
|
context->processing = 0;
|
||||||
return r;
|
return r;
|
||||||
} /* getdns_cancel_callback */
|
} /* getdns_cancel_callback */
|
||||||
|
|
||||||
|
@ -1417,7 +1427,32 @@ getdns_context_clear_outbound_request(getdns_dns_req * req)
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_request_timed_out(struct getdns_dns_req
|
||||||
|
*req) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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, NULL, user_arg, trans_id);
|
||||||
|
if (context->processing > 1) {
|
||||||
|
// destroyed.
|
||||||
|
context->processing = 0;
|
||||||
|
getdns_context_destroy(context);
|
||||||
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
} else {
|
||||||
|
context->processing = 0;
|
||||||
|
if (context->extension) {
|
||||||
|
context->extension->request_count_changed(context,
|
||||||
|
context->outbound_requests->count, context->extension_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
getdns_strdup(const struct mem_funcs *mfs, const char *s)
|
getdns_strdup(const struct mem_funcs *mfs, const char *s)
|
||||||
|
@ -1543,7 +1578,8 @@ getdns_return_t getdns_context_process_async(struct getdns_context* context) {
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
ldns_rbnode_t* next_timeout = ldns_rbtree_first(context->timeouts_by_time);
|
ldns_rbnode_t* next_timeout = ldns_rbtree_first(context->timeouts_by_time);
|
||||||
while (next_timeout) {
|
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||||
|
while (next_timeout && r == GETDNS_RETURN_GOOD) {
|
||||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) next_timeout->data;
|
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) next_timeout->data;
|
||||||
if (timeout_cmp(timeout_data, &key) > 0) {
|
if (timeout_cmp(timeout_data, &key) > 0) {
|
||||||
/* no more timeouts need to be fired. */
|
/* no more timeouts need to be fired. */
|
||||||
|
@ -1560,10 +1596,10 @@ getdns_return_t getdns_context_process_async(struct getdns_context* context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fire the timeout */
|
/* fire the timeout */
|
||||||
timeout_data->callback(timeout_data->userarg);
|
r = timeout_data->callback(timeout_data->userarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GETDNS_RETURN_GOOD;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct timeout_accumulator {
|
typedef struct timeout_accumulator {
|
||||||
|
|
|
@ -157,6 +157,10 @@ getdns_return_t getdns_context_track_outbound_request(struct getdns_dns_req
|
||||||
/* clear the outbound request from being tracked - does not cancel it */
|
/* clear the outbound request from being tracked - does not cancel it */
|
||||||
getdns_return_t getdns_context_clear_outbound_request(struct getdns_dns_req
|
getdns_return_t getdns_context_clear_outbound_request(struct getdns_dns_req
|
||||||
*req);
|
*req);
|
||||||
|
|
||||||
|
getdns_return_t getdns_context_request_timed_out(struct getdns_dns_req
|
||||||
|
*req);
|
||||||
|
|
||||||
/* cancel callback internal - flag to indicate if req should be freed and callback fired */
|
/* 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_return_t getdns_context_cancel_request(struct getdns_context *context,
|
||||||
getdns_transaction_t transaction_id, int fire_callback);
|
getdns_transaction_t transaction_id, int fire_callback);
|
||||||
|
|
|
@ -73,10 +73,6 @@ static void
|
||||||
getdns_libev_timeout_cb(struct ev_loop *loop, struct ev_timer* handle, int status) {
|
getdns_libev_timeout_cb(struct ev_loop *loop, struct ev_timer* handle, int status) {
|
||||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) handle->data;
|
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) handle->data;
|
||||||
timeout_data->callback(timeout_data->userarg);
|
timeout_data->callback(timeout_data->userarg);
|
||||||
uint32_t rc = getdns_context_get_num_pending_requests(timeout_data->context, NULL);
|
|
||||||
struct getdns_libev_data* ev_data =
|
|
||||||
(struct getdns_libev_data*) getdns_context_get_extension_data(timeout_data->context);
|
|
||||||
request_count_changed(rc, ev_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* getdns extension functions */
|
/* getdns extension functions */
|
||||||
|
|
|
@ -102,10 +102,6 @@ static void
|
||||||
getdns_libevent_timeout_cb(evutil_socket_t fd, short what, void* userarg) {
|
getdns_libevent_timeout_cb(evutil_socket_t fd, short what, void* userarg) {
|
||||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) userarg;
|
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) userarg;
|
||||||
timeout_data->callback(timeout_data->userarg);
|
timeout_data->callback(timeout_data->userarg);
|
||||||
uint32_t rc = getdns_context_get_num_pending_requests(timeout_data->context, NULL);
|
|
||||||
struct event_data* ev_data =
|
|
||||||
(struct event_data*) getdns_context_get_extension_data(timeout_data->context);
|
|
||||||
request_count_changed(rc, ev_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* getdns extension functions */
|
/* getdns extension functions */
|
||||||
|
|
|
@ -75,10 +75,6 @@ static void
|
||||||
getdns_libuv_timeout_cb(uv_timer_t* handle, int status) {
|
getdns_libuv_timeout_cb(uv_timer_t* handle, int status) {
|
||||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) handle->data;
|
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) handle->data;
|
||||||
timeout_data->callback(timeout_data->userarg);
|
timeout_data->callback(timeout_data->userarg);
|
||||||
uint32_t rc = getdns_context_get_num_pending_requests(timeout_data->context, NULL);
|
|
||||||
struct getdns_libuv_data* uv_data =
|
|
||||||
(struct getdns_libuv_data*) getdns_context_get_extension_data(timeout_data->context);
|
|
||||||
request_count_changed(rc, uv_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -50,8 +50,8 @@
|
||||||
|
|
||||||
/* declarations */
|
/* declarations */
|
||||||
static void ub_resolve_callback(void* mydata, int err, struct ub_result* result);
|
static void ub_resolve_callback(void* mydata, int err, struct ub_result* result);
|
||||||
static void ub_resolve_timeout(void *arg);
|
static getdns_return_t ub_resolve_timeout(void *arg);
|
||||||
static void ub_local_resolve_timeout(void *arg);
|
static getdns_return_t ub_local_resolve_timeout(void *arg);
|
||||||
|
|
||||||
static void handle_network_request_error(getdns_network_req * netreq, int err);
|
static void handle_network_request_error(getdns_network_req * netreq, int err);
|
||||||
static void handle_dns_request_complete(getdns_dns_req * dns_req);
|
static void handle_dns_request_complete(getdns_dns_req * dns_req);
|
||||||
|
@ -65,22 +65,14 @@ typedef struct netreq_cb_data
|
||||||
} netreq_cb_data;
|
} netreq_cb_data;
|
||||||
|
|
||||||
/* cancel, cleanup and send timeout to callback */
|
/* cancel, cleanup and send timeout to callback */
|
||||||
static void
|
static getdns_return_t
|
||||||
ub_resolve_timeout(void *arg)
|
ub_resolve_timeout(void *arg)
|
||||||
{
|
{
|
||||||
getdns_dns_req *dns_req = (getdns_dns_req *) arg;
|
getdns_dns_req *dns_req = (getdns_dns_req *) arg;
|
||||||
struct getdns_context *context = dns_req->context;
|
return getdns_context_request_timed_out(dns_req);
|
||||||
getdns_transaction_t trans_id = dns_req->trans_id;
|
|
||||||
getdns_callback_t cb = dns_req->user_callback;
|
|
||||||
void *user_arg = dns_req->user_pointer;
|
|
||||||
|
|
||||||
/* cancel the req - also clears it from outbound and cleans up*/
|
|
||||||
getdns_context_cancel_request(context, trans_id, 0);
|
|
||||||
|
|
||||||
cb(context, GETDNS_CALLBACK_TIMEOUT, NULL, user_arg, trans_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static getdns_return_t
|
||||||
ub_local_resolve_timeout(void *arg)
|
ub_local_resolve_timeout(void *arg)
|
||||||
{
|
{
|
||||||
netreq_cb_data *cb_data = (netreq_cb_data *) arg;
|
netreq_cb_data *cb_data = (netreq_cb_data *) arg;
|
||||||
|
@ -99,6 +91,7 @@ ub_local_resolve_timeout(void *arg)
|
||||||
|
|
||||||
/* cleanup the state */
|
/* cleanup the state */
|
||||||
GETDNS_FREE(dnsreq->my_mf, cb_data);
|
GETDNS_FREE(dnsreq->my_mf, cb_data);
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
void priv_getdns_call_user_callback(getdns_dns_req *dns_req,
|
void priv_getdns_call_user_callback(getdns_dns_req *dns_req,
|
||||||
|
|
|
@ -63,7 +63,7 @@ getdns_return_t getdns_context_process_async(getdns_context* context);
|
||||||
getdns_return_t getdns_context_set_use_threads(getdns_context* context, int use_threads);
|
getdns_return_t getdns_context_set_use_threads(getdns_context* context, int use_threads);
|
||||||
|
|
||||||
/* extensions */
|
/* extensions */
|
||||||
typedef void (*getdns_timeout_callback) (void* userarg);
|
typedef getdns_return_t (*getdns_timeout_callback) (void* userarg);
|
||||||
|
|
||||||
/* context timeout data */
|
/* context timeout data */
|
||||||
typedef struct getdns_timeout_data {
|
typedef struct getdns_timeout_data {
|
||||||
|
|
|
@ -202,6 +202,61 @@
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (getdns_context_destroy_8)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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()");
|
||||||
|
getdns_cancel_callback(context, transaction_id);
|
||||||
|
RUN_EVENT_LOOP;
|
||||||
|
|
||||||
|
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (getdns_context_destroy_9)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
// set timeout to something unreasonable
|
||||||
|
getdns_context_set_timeout(context, 1);
|
||||||
|
EVENT_BASE_CREATE;
|
||||||
|
|
||||||
|
ASSERT_RC(getdns_address(context, "google.com", NULL,
|
||||||
|
&flag, &transaction_id, destroy_callbackfn),
|
||||||
|
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
|
||||||
|
ASSERT_RC(getdns_address(context, "getdnsapi.net", 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)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -234,6 +289,8 @@
|
||||||
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);
|
tcase_add_test(tc_pos, getdns_context_destroy_7);
|
||||||
|
tcase_add_test(tc_pos, getdns_context_destroy_8);
|
||||||
|
tcase_add_test(tc_pos, getdns_context_destroy_9);
|
||||||
suite_add_tcase(s, tc_pos);
|
suite_add_tcase(s, tc_pos);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
Loading…
Reference in New Issue