Set processing flag around user callbacks

To fix destroying contexts from user callbacks in stub mode.
The complete test suite runs in stub mode now too.
This commit is contained in:
Willem Toorop 2015-09-03 15:07:29 +02:00
parent 9586418522
commit 0e66d28be8
3 changed files with 23 additions and 29 deletions

View File

@ -951,7 +951,6 @@ getdns_context_destroy(struct getdns_context *context)
return; return;
context->destroying = 1; context->destroying = 1;
context->processing = 1;
/* cancel all outstanding requests */ /* cancel all outstanding requests */
cancel_outstanding_requests(context, 1); cancel_outstanding_requests(context, 1);
@ -966,7 +965,6 @@ getdns_context_destroy(struct getdns_context *context)
ub_ctx_delete(context->unbound_ctx); ub_ctx_delete(context->unbound_ctx);
#endif #endif
context->processing = 0;
context->extension->vmt->cleanup(context->extension); context->extension->vmt->cleanup(context->extension);
if (context->namespaces) if (context->namespaces)
@ -1090,10 +1088,8 @@ _getdns_context_ub_read_cb(void *userarg)
* (with context->extension->vmt->run*), because we are already * (with context->extension->vmt->run*), because we are already
* called from a running eventloop. * called from a running eventloop.
*/ */
context->processing = 1;
if (ub_poll(context->unbound_ctx)) if (ub_poll(context->unbound_ctx))
(void) ub_process(context->unbound_ctx); (void) ub_process(context->unbound_ctx);
context->processing = 0;
/* No need to handle timeouts. They are handled by the extension. */ /* No need to handle timeouts. They are handled by the extension. */
@ -1925,9 +1921,12 @@ _getdns_context_cancel_request(getdns_context *context,
/* do the cancel */ /* do the cancel */
cancel_dns_req(dnsreq); cancel_dns_req(dnsreq);
if (fire_callback) if (fire_callback) {
context->processing = 1;
dnsreq->user_callback(context, GETDNS_CALLBACK_CANCEL, dnsreq->user_callback(context, GETDNS_CALLBACK_CANCEL,
NULL, dnsreq->user_pointer, transaction_id); NULL, dnsreq->user_pointer, transaction_id);
context->processing = 0;
}
/* clean up */ /* clean up */
_getdns_dns_req_free(dnsreq); _getdns_dns_req_free(dnsreq);
@ -1945,9 +1944,7 @@ getdns_cancel_callback(getdns_context *context,
if (!context) if (!context)
return GETDNS_RETURN_INVALID_PARAMETER; return 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);
context->processing = 0;
getdns_context_request_count_changed(context); getdns_context_request_count_changed(context);
return r; return r;
} /* getdns_cancel_callback */ } /* getdns_cancel_callback */
@ -2222,22 +2219,22 @@ _getdns_context_clear_outbound_request(getdns_dns_req *dnsreq)
} }
getdns_return_t getdns_return_t
_getdns_context_request_timed_out(struct getdns_dns_req *req) _getdns_context_request_timed_out(getdns_dns_req *req)
{ {
/* Don't use req after callback */ /* Don't use req after callback */
getdns_context* context = req->context; getdns_context* context = req->context;
getdns_transaction_t trans_id = req->trans_id; getdns_transaction_t trans_id = req->trans_id;
getdns_callback_t cb = req->user_callback; getdns_callback_t cb = req->user_callback;
void *user_arg = req->user_pointer; void *user_arg = req->user_pointer;
getdns_dict *response = _getdns_create_getdns_response(req); getdns_dict *response = _getdns_create_getdns_response(req);
/* cancel the req - also clears it from outbound and cleans up*/ /* cancel the req - also clears it from outbound and cleans up*/
_getdns_context_cancel_request(context, trans_id, 0); _getdns_context_cancel_request(context, trans_id, 0);
context->processing = 1; context->processing = 1;
cb(context, GETDNS_CALLBACK_TIMEOUT, response, user_arg, trans_id); cb(context, GETDNS_CALLBACK_TIMEOUT, response, user_arg, trans_id);
context->processing = 0; context->processing = 0;
getdns_context_request_count_changed(context); getdns_context_request_count_changed(context);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
char * char *
@ -2321,13 +2318,10 @@ getdns_context_process_async(struct getdns_context* context)
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
#ifdef HAVE_LIBUNBOUND #ifdef HAVE_LIBUNBOUND
context->processing = 1;
if (ub_poll(context->unbound_ctx) && ub_process(context->unbound_ctx)){ if (ub_poll(context->unbound_ctx) && ub_process(context->unbound_ctx)){
/* need an async return code? */ /* need an async return code? */
context->processing = 0;
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
context->processing = 0;
#endif #endif
context->extension->vmt->run_once(context->extension, 0); context->extension->vmt->run_once(context->extension, 0);
@ -2381,10 +2375,8 @@ getdns_context_detach_eventloop(struct getdns_context* context)
* ( because callbacks occur in cancel_outstanding_requests, * ( because callbacks occur in cancel_outstanding_requests,
* and they may destroy the context ) * and they may destroy the context )
*/ */
context->processing = 1;
/* cancel all outstanding requests */ /* cancel all outstanding requests */
cancel_outstanding_requests(context, 1); cancel_outstanding_requests(context, 1);
context->processing = 0;
context->extension->vmt->cleanup(context->extension); context->extension->vmt->cleanup(context->extension);
context->extension = &context->mini_event.loop; context->extension = &context->mini_event.loop;
return _getdns_mini_event_init(context, &context->mini_event); return _getdns_mini_event_init(context, &context->mini_event);

View File

@ -65,9 +65,11 @@ void _getdns_call_user_callback(getdns_dns_req *dns_req,
_getdns_context_clear_outbound_request(dns_req); _getdns_context_clear_outbound_request(dns_req);
_getdns_dns_req_free(dns_req); _getdns_dns_req_free(dns_req);
context->processing = 1;
cb(context, cb(context,
(response ? GETDNS_CALLBACK_COMPLETE : GETDNS_CALLBACK_ERROR), (response ? GETDNS_CALLBACK_COMPLETE : GETDNS_CALLBACK_ERROR),
response, user_arg, trans_id); response, user_arg, trans_id);
context->processing = 0;
} }
void void

View File

@ -294,8 +294,8 @@
struct getdns_list *upstream_list = NULL; struct getdns_list *upstream_list = NULL;
struct getdns_dict *dict = NULL; struct getdns_dict *dict = NULL;
struct getdns_dict *response = NULL; struct getdns_dict *response = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" }; struct getdns_bindata address_type = { 4, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x0A\xAA\x0C\x38" }; struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
size_t index = 0; size_t index = 0;
CONTEXT_CREATE(TRUE); CONTEXT_CREATE(TRUE);
@ -393,8 +393,8 @@
struct getdns_list *upstream_list = NULL; struct getdns_list *upstream_list = NULL;
struct getdns_dict *dict = NULL; struct getdns_dict *dict = NULL;
struct getdns_dict *response = NULL; struct getdns_dict *response = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv4" }; struct getdns_bindata address_type = { 4, (void *)"IPv4" };
struct getdns_bindata address_data = { 4, (void *)"\x0A\xAA\x0C\x38" }; struct getdns_bindata address_data = { 4, (void *)"\x08\x08\x08\x08" };
struct getdns_bindata port = { 3, (void *)"53" }; struct getdns_bindata port = { 3, (void *)"53" };
size_t index = 0; size_t index = 0;