2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

refactor plugin hook resumption to use loop callbacks

plugins supporting asynchronous operation now use a loop callback
to resume operation in query_hookresume() rather than a task.
This commit is contained in:
Evan Hunt
2022-10-27 09:54:27 -07:00
committed by Ondřej Surý
parent 773d47c95c
commit b061c7e27f
8 changed files with 102 additions and 90 deletions

View File

@@ -19,6 +19,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <isc/async.h>
#include <isc/buffer.h> #include <isc/buffer.h>
#include <isc/hash.h> #include <isc/hash.h>
#include <isc/ht.h> #include <isc/ht.h>
@@ -30,7 +31,6 @@
#include <isc/util.h> #include <isc/util.h>
#include <ns/client.h> #include <ns/client.h>
#include <ns/events.h>
#include <ns/hooks.h> #include <ns/hooks.h>
#include <ns/log.h> #include <ns/log.h>
#include <ns/query.h> #include <ns/query.h>
@@ -59,7 +59,7 @@ typedef struct async_instance {
typedef struct state { typedef struct state {
bool async; bool async;
ns_hook_resevent_t *rev; ns_hook_resume_t *rev;
ns_hookpoint_t hookpoint; ns_hookpoint_t hookpoint;
isc_result_t origresult; isc_result_t origresult;
} state_t; } state_t;
@@ -277,29 +277,31 @@ destroyasync(ns_hookasync_t **ctxp) {
} }
static isc_result_t static isc_result_t
doasync(query_ctx_t *qctx, isc_mem_t *mctx, void *arg, isc_task_t *task, doasync(query_ctx_t *qctx, isc_mem_t *mctx, void *arg, isc_loop_t *loop,
isc_taskaction_t action, void *evarg, ns_hookasync_t **ctxp) { isc_job_cb cb, void *evarg, ns_hookasync_t **ctxp) {
ns_hook_resevent_t *rev = (ns_hook_resevent_t *)isc_event_allocate( ns_hook_resume_t *rev = isc_mem_get(mctx, sizeof(*rev));
mctx, task, NS_EVENT_HOOKASYNCDONE, action, evarg,
sizeof(*rev));
ns_hookasync_t *ctx = isc_mem_get(mctx, sizeof(*ctx)); ns_hookasync_t *ctx = isc_mem_get(mctx, sizeof(*ctx));
state_t *state = (state_t *)arg; state_t *state = (state_t *)arg;
logmsg("doasync"); logmsg("doasync");
*ctx = (ns_hookasync_t){ .mctx = NULL }; *ctx = (ns_hookasync_t){
.cancel = cancelasync,
.destroy = destroyasync,
};
isc_mem_attach(mctx, &ctx->mctx); isc_mem_attach(mctx, &ctx->mctx);
ctx->cancel = cancelasync;
ctx->destroy = destroyasync;
rev->hookpoint = state->hookpoint;
rev->origresult = state->origresult;
qctx->result = DNS_R_NOTIMP; qctx->result = DNS_R_NOTIMP;
rev->saved_qctx = qctx; *rev = (ns_hook_resume_t){
rev->ctx = ctx; .hookpoint = state->hookpoint,
.origresult = qctx->result,
.saved_qctx = qctx,
.ctx = ctx,
.arg = evarg,
};
state->rev = rev; state->rev = rev;
isc_task_send(task, (isc_event_t **)&rev); isc_async_run(loop, cb, rev);
*ctxp = ctx; *ctxp = ctx;
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);

View File

@@ -115,7 +115,7 @@ typedef struct resctx {
dns_fetch_t *fetch; dns_fetch_t *fetch;
dns_namelist_t namelist; dns_namelist_t namelist;
isc_result_t result; isc_result_t result;
dns_clientresevent_t *event; dns_clientresume_t *event;
dns_rdataset_t *rdataset; dns_rdataset_t *rdataset;
dns_rdataset_t *sigrdataset; dns_rdataset_t *sigrdataset;
} resctx_t; } resctx_t;
@@ -878,7 +878,7 @@ client_resfind(resctx_t *rctx, dns_fetchevent_t *event) {
static void static void
resolve_done(isc_task_t *task, isc_event_t *event) { resolve_done(isc_task_t *task, isc_event_t *event) {
resarg_t *resarg = event->ev_arg; resarg_t *resarg = event->ev_arg;
dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_clientresume_t *rev = (dns_clientresume_t *)event;
dns_name_t *name = NULL; dns_name_t *name = NULL;
isc_result_t result; isc_result_t result;
@@ -955,7 +955,7 @@ dns_client_startresolve(dns_client_t *client, const dns_name_t *name,
unsigned int options, isc_task_t *task, unsigned int options, isc_task_t *task,
isc_taskaction_t action, void *arg, isc_taskaction_t action, void *arg,
dns_clientrestrans_t **transp) { dns_clientrestrans_t **transp) {
dns_clientresevent_t *event = NULL; dns_clientresume_t *event = NULL;
resctx_t *rctx = NULL; resctx_t *rctx = NULL;
isc_task_t *tclone = NULL; isc_task_t *tclone = NULL;
isc_mem_t *mctx; isc_mem_t *mctx;
@@ -980,7 +980,7 @@ dns_client_startresolve(dns_client_t *client, const dns_name_t *name,
*/ */
tclone = NULL; tclone = NULL;
isc_task_attach(task, &tclone); isc_task_attach(task, &tclone);
event = (dns_clientresevent_t *)isc_event_allocate( event = (dns_clientresume_t *)isc_event_allocate(
mctx, tclone, DNS_EVENT_CLIENTRESDONE, action, arg, mctx, tclone, DNS_EVENT_CLIENTRESDONE, action, arg,
sizeof(*event)); sizeof(*event));
event->result = DNS_R_SERVFAIL; event->result = DNS_R_SERVFAIL;

View File

@@ -73,7 +73,7 @@ ISC_LANG_BEGINDECLS
#define DNS_CLIENTVIEW_NAME "_dnsclient" #define DNS_CLIENTVIEW_NAME "_dnsclient"
/*% /*%
* A dns_clientresevent_t is sent when name resolution performed by a client * A dns_clientresume_t is sent when name resolution performed by a client
* completes. 'result' stores the result code of the entire resolution * completes. 'result' stores the result code of the entire resolution
* procedure. 'vresult' specifically stores the result code of DNSSEC * procedure. 'vresult' specifically stores the result code of DNSSEC
* validation if it is performed. When name resolution successfully completes, * validation if it is performed. When name resolution successfully completes,
@@ -81,12 +81,12 @@ ISC_LANG_BEGINDECLS
* RRsets. It is the receiver's responsibility to free this list by calling * RRsets. It is the receiver's responsibility to free this list by calling
* dns_client_freeresanswer() before freeing the event structure. * dns_client_freeresanswer() before freeing the event structure.
*/ */
typedef struct dns_clientresevent { typedef struct dns_clientresume {
ISC_EVENT_COMMON(struct dns_clientresevent); ISC_EVENT_COMMON(struct dns_clientresume);
isc_result_t result; isc_result_t result;
isc_result_t vresult; isc_result_t vresult;
dns_namelist_t answerlist; dns_namelist_t answerlist;
} dns_clientresevent_t; /* too long? */ } dns_clientresume_t; /* too long? */
isc_result_t isc_result_t
dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
@@ -232,7 +232,7 @@ dns_client_startresolve(dns_client_t *client, const dns_name_t *name,
* *
* dns_client_startresolve() is an asynchronous version of dns_client_resolve() * dns_client_startresolve() is an asynchronous version of dns_client_resolve()
* and does not block. When name resolution is completed, 'action' will be * and does not block. When name resolution is completed, 'action' will be
* called with the argument of a 'dns_clientresevent_t' object, which contains * called with the argument of a 'dns_clientresume_t' object, which contains
* the resulting list of answer names (on success). On return, '*transp' is * the resulting list of answer names (on success). On return, '*transp' is
* set to an opaque transaction ID so that the caller can cancel this * set to an opaque transaction ID so that the caller can cancel this
* resolution process. * resolution process.

View File

@@ -52,6 +52,7 @@
#include <isc/lang.h> #include <isc/lang.h>
#include <isc/refcount.h> #include <isc/refcount.h>
#include <isc/stats.h> #include <isc/stats.h>
#include <isc/tls.h>
#include <isc/types.h> #include <isc/types.h>
#include <dns/fixedname.h> #include <dns/fixedname.h>

View File

@@ -22,7 +22,6 @@
#include <isc/magic.h> #include <isc/magic.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/result.h> #include <isc/result.h>
#include <isc/task.h>
#include <dns/rdatatype.h> #include <dns/rdatatype.h>
@@ -198,15 +197,15 @@
* asynchronous event by calling ns_query_hookasync(). This is similar * asynchronous event by calling ns_query_hookasync(). This is similar
* to ns_query_recurse(), but more generic. ns_query_hookasync() will * to ns_query_recurse(), but more generic. ns_query_hookasync() will
* call the 'runasync' function with a specified 'arg' (both passed to * call the 'runasync' function with a specified 'arg' (both passed to
* ns_query_hookasync()) and a set of task and associated event arguments * ns_query_hookasync()) and a set of loop and associated event arguments
* to be called to resume query handling upon completion of the * to be called to resume query handling upon completion of the
* asynchronous event. * asynchronous event.
* *
* The implementation of 'runasync' is assumed to allocate and build an * The implementation of 'runasync' is assumed to allocate and build an
* instance of ns_hook_resevent_t whose action, arg, and task are set to * instance of ns_hook_resume_t whose callback, arg, and loop are set to
* the passed values from ns_query_hookasync(). Other fields of * the passed values from ns_query_hookasync(). Other fields of
* ns_hook_resevent_t must be correctly set in the hook implementation * ns_hook_resume_t must be correctly set in the hook implementation
* by the time it's sent to the specified task: * by the time it's sent to the specified loop:
* *
* - hookpoint: the point from which the query handling should be resumed * - hookpoint: the point from which the query handling should be resumed
* (which should usually be the hook point that triggered the asynchronous * (which should usually be the hook point that triggered the asynchronous
@@ -229,7 +228,7 @@
* NS_HOOK_RETURN to suspend the query handling. * NS_HOOK_RETURN to suspend the query handling.
* *
* On the completion of the asynchronous event, the hook implementation is * On the completion of the asynchronous event, the hook implementation is
* supposed to send the resumeevent to the corresponding task. The query * supposed to send the resumeevent to the corresponding loop. The query
* module resumes the query handling so that the hook action of the * module resumes the query handling so that the hook action of the
* specified hook point will be called, skipping some intermediate query * specified hook point will be called, skipping some intermediate query
* handling steps. So, typically, the same hook action will be called * handling steps. So, typically, the same hook action will be called
@@ -242,7 +241,7 @@
* *
* typedef struct hookstate { * typedef struct hookstate {
* bool async; * bool async;
* ns_hook_resevent_t *rev * ns_hook_resume_t *rev
* ns_hookpoint_t hookpoint; * ns_hookpoint_t hookpoint;
* isc_result_t origresult; * isc_result_t origresult;
* } hookstate_t; * } hookstate_t;
@@ -276,28 +275,30 @@
* And the 'runasync' function would be something like this: * And the 'runasync' function would be something like this:
* *
* static isc_result_t * static isc_result_t
* runasync(query_ctx_t *qctx, void *arg, isc_taskaction_t action, * runasync(query_ctx_t *qctx, void *arg, isc_job_cb cb, void *evarg,
* void *evarg, isc_task_t *task, ns_hookasync_t **ctxp) { * isc_loop_t *loop, ns_hookasync_t **ctxp) {
* hookstate_t *state = arg; * hookstate_t *state = arg;
* ns_hook_resevent_t *rev = isc_event_allocate( * ns_hook_resume_t *rev isc_mem_get(mctx, sizeof(*rev));
* mctx, task, NS_EVENT_HOOKASYNCDONE, action, evarg,
* sizeof(*rev));
* ns_hookasync_t *ctx = isc_mem_get(mctx, sizeof(*ctx)); * ns_hookasync_t *ctx = isc_mem_get(mctx, sizeof(*ctx));
* *
* *ctx = (ns_hookasync_t){ .private = NULL }; * *ctx = (ns_hookasync_t){ .private = NULL
* .hookpoint = state->hookpoint,
* .origresult = state->origresult,
* .saved_ctx = qctx,
* .ctx = ctx,
* .loop = loop,
* .cb = cb,
* .arg = cbarg
* };
* isc_mem_attach(mctx, &ctx->mctx); * isc_mem_attach(mctx, &ctx->mctx);
*
* ctx->cancel = ...; // set the cancel function, which cancels the * ctx->cancel = ...; // set the cancel function, which cancels the
* // internal asynchronous event (if necessary). * // internal asynchronous event (if necessary).
* // it should eventually result in sending * // it should eventually result in sending
* // the 'rev' event to the calling task. * // the 'rev' event to the calling loop.
* ctx->destroy = ...; // set the destroy function, which frees 'ctx' * ctx->destroy = ...; // set the destroy function, which frees 'ctx'
* *
* rev->hookpoint = state->hookpoint; * state->rev = rev; // store the resume state so we can send it later
* rev->origresult = state->origresult;
* rev->saved_qctx = qctx;
* rev->ctx = ctx;
*
* state->rev = rev; // store the resume event so we can send it later
* *
* // initiate some asynchronous process here - for example, a * // initiate some asynchronous process here - for example, a
* // recursive fetch. * // recursive fetch.
@@ -312,8 +313,7 @@
* *
* static void * static void
* asyncproc_done(hookstate_t *state) { * asyncproc_done(hookstate_t *state) {
* isc_event_t *ev = (isc_event_t *)state->rev; * isc_async_run(state->rev->loop, state->rev->cb, state->rev->arg);
* isc_task_send(ev->ev_sender, &ev);
* } * }
* *
* Caveats: * Caveats:
@@ -438,13 +438,15 @@ struct ns_hookasync {
* isc_event to be sent on the completion of a hook-initiated asyncronous * isc_event to be sent on the completion of a hook-initiated asyncronous
* process, similar to dns_fetchevent_t. * process, similar to dns_fetchevent_t.
*/ */
typedef struct ns_hook_resevent { typedef struct ns_hook_resume {
ISC_EVENT_COMMON(struct ns_hook_resevent);
ns_hookasync_t *ctx; /* asynchronous processing context */ ns_hookasync_t *ctx; /* asynchronous processing context */
ns_hookpoint_t hookpoint; /* hook point from which to resume */ ns_hookpoint_t hookpoint; /* hook point from which to resume */
isc_result_t origresult; /* result code at the point of call to hook */ isc_result_t origresult; /* result code at the point of call to hook */
query_ctx_t *saved_qctx; /* qctx at the point of call to hook */ query_ctx_t *saved_qctx; /* qctx at the point of call to hook */
} ns_hook_resevent_t; isc_loop_t *loop; /* loopmgr loop to resume in */
isc_job_cb cb; /* callback function */
void *arg; /* argument to pass to the callback */
} ns_hook_resume_t;
/* /*
* Plugin API version * Plugin API version
@@ -455,7 +457,7 @@ typedef struct ns_hook_resevent {
* as well; if not, set NS_PLUGIN_AGE to 0. * as well; if not, set NS_PLUGIN_AGE to 0.
*/ */
#ifndef NS_PLUGIN_VERSION #ifndef NS_PLUGIN_VERSION
#define NS_PLUGIN_VERSION 1 #define NS_PLUGIN_VERSION 2
#define NS_PLUGIN_AGE 0 #define NS_PLUGIN_AGE 0
#endif /* ifndef NS_PLUGIN_VERSION */ #endif /* ifndef NS_PLUGIN_VERSION */

View File

@@ -19,7 +19,6 @@
#include <isc/buffer.h> #include <isc/buffer.h>
#include <isc/netaddr.h> #include <isc/netaddr.h>
#include <isc/task.h>
#include <isc/types.h> #include <isc/types.h>
#include <dns/rdataset.h> #include <dns/rdataset.h>
@@ -243,9 +242,11 @@ struct query_ctx {
int line; /* line to report error */ int line; /* line to report error */
}; };
typedef isc_result_t (*ns_query_starthookasync_t)( typedef isc_result_t (*ns_query_starthookasync_t)(query_ctx_t *qctx,
query_ctx_t *qctx, isc_mem_t *mctx, void *arg, isc_task_t *task, isc_mem_t *mctx, void *arg,
isc_taskaction_t action, void *evarg, ns_hookasync_t **ctxp); isc_loop_t *loop,
isc_job_cb cb, void *evarg,
ns_hookasync_t **ctxp);
/* /*
* The following functions are expected to be used only within query.c * The following functions are expected to be used only within query.c

View File

@@ -6761,18 +6761,16 @@ cleanup:
} }
static void static void
query_hookresume(isc_task_t *task, isc_event_t *event) { query_hookresume(void *arg) {
ns_hook_resevent_t *rev = (ns_hook_resevent_t *)event; ns_hook_resume_t *rev = (ns_hook_resume_t *)arg;
ns_hookasync_t *hctx = NULL; ns_hookasync_t *hctx = NULL;
ns_client_t *client = rev->ev_arg; ns_client_t *client = rev->arg;
query_ctx_t *qctx = rev->saved_qctx; query_ctx_t *qctx = rev->saved_qctx;
bool canceled; bool canceled;
CTRACE(ISC_LOG_DEBUG(3), "query_hookresume"); CTRACE(ISC_LOG_DEBUG(3), "query_hookresume");
REQUIRE(NS_CLIENT_VALID(client)); REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(task == client->manager->task);
REQUIRE(event->ev_type == NS_EVENT_HOOKASYNCDONE);
LOCK(&client->query.fetchlock); LOCK(&client->query.fetchlock);
if (client->query.hookactx != NULL) { if (client->query.hookactx != NULL) {
@@ -6898,10 +6896,10 @@ query_hookresume(isc_task_t *task, isc_event_t *event) {
} }
} }
isc_mem_put(hctx->mctx, rev, sizeof(*rev));
hctx->destroy(&hctx); hctx->destroy(&hctx);
qctx_destroy(qctx); qctx_destroy(qctx);
isc_mem_put(client->manager->mctx, qctx, sizeof(*qctx)); isc_mem_put(client->manager->mctx, qctx, sizeof(*qctx));
isc_event_free(&event);
} }
isc_result_t isc_result_t
@@ -6925,7 +6923,7 @@ ns_query_hookasync(query_ctx_t *qctx, ns_query_starthookasync_t runasync,
saved_qctx = isc_mem_get(client->manager->mctx, sizeof(*saved_qctx)); saved_qctx = isc_mem_get(client->manager->mctx, sizeof(*saved_qctx));
qctx_save(qctx, saved_qctx); qctx_save(qctx, saved_qctx);
result = runasync(saved_qctx, client->manager->mctx, arg, result = runasync(saved_qctx, client->manager->mctx, arg,
client->manager->task, query_hookresume, client, client->manager->loop, query_hookresume, client,
&client->query.hookactx); &client->query.hookactx);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto cleanup_and_detach_from_quota; goto cleanup_and_detach_from_quota;

View File

@@ -611,7 +611,7 @@ typedef struct hookasync_data {
* asynchronous process */ * asynchronous process */
bool canceled; /* true if the query has been canceled */ bool canceled; /* true if the query has been canceled */
isc_result_t start_result; /* result of 'runasync' */ isc_result_t start_result; /* result of 'runasync' */
ns_hook_resevent_t *rev; /* resume event sent on completion */ ns_hook_resume_t *rev; /* resume state sent on completion */
query_ctx_t qctx; /* shallow copy of qctx passed to hook */ query_ctx_t qctx; /* shallow copy of qctx passed to hook */
ns_hookpoint_t hookpoint; /* specifies where to resume */ ns_hookpoint_t hookpoint; /* specifies where to resume */
ns_hookpoint_t lasthookpoint; /* remember the last hook point called */ ns_hookpoint_t lasthookpoint; /* remember the last hook point called */
@@ -640,31 +640,36 @@ cancel_hookactx(ns_hookasync_t *ctx) {
/* 'runasync' callback passed to ns_query_hookasync */ /* 'runasync' callback passed to ns_query_hookasync */
static isc_result_t static isc_result_t
test_hookasync(query_ctx_t *qctx, isc_mem_t *memctx, void *arg, test_hookasync(query_ctx_t *qctx, isc_mem_t *memctx, void *arg,
isc_task_t *task, isc_taskaction_t action, void *evarg, isc_loop_t *loop, isc_job_cb cb, void *evarg,
ns_hookasync_t **ctxp) { ns_hookasync_t **ctxp) {
hookasync_data_t *asdata = arg; hookasync_data_t *asdata = arg;
ns_hookasync_t *ctx = NULL; ns_hookasync_t *ctx = NULL;
ns_hook_resevent_t *rev = NULL; ns_hook_resume_t *rev = NULL;
if (asdata->start_result != ISC_R_SUCCESS) { if (asdata->start_result != ISC_R_SUCCESS) {
return (asdata->start_result); return (asdata->start_result);
} }
ctx = isc_mem_get(memctx, sizeof(*ctx)); ctx = isc_mem_get(memctx, sizeof(*ctx));
rev = (ns_hook_resevent_t *)isc_event_allocate( rev = isc_mem_get(memctx, sizeof(*rev));
memctx, task, NS_EVENT_HOOKASYNCDONE, action, evarg, *rev = (ns_hook_resume_t){
sizeof(*rev)); .hookpoint = asdata->hookpoint,
.origresult = DNS_R_NXDOMAIN,
.saved_qctx = qctx,
.ctx = ctx,
.loop = loop,
.cb = cb,
.arg = evarg,
};
rev->hookpoint = asdata->hookpoint;
rev->origresult = DNS_R_NXDOMAIN;
rev->saved_qctx = qctx;
rev->ctx = ctx;
asdata->rev = rev; asdata->rev = rev;
*ctx = (ns_hookasync_t){ .private = asdata }; *ctx = (ns_hookasync_t){
.destroy = destroy_hookactx,
.cancel = cancel_hookactx,
.private = asdata,
};
isc_mem_attach(memctx, &ctx->mctx); isc_mem_attach(memctx, &ctx->mctx);
ctx->destroy = destroy_hookactx;
ctx->cancel = cancel_hookactx;
*ctxp = ctx; *ctxp = ctx;
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
@@ -948,8 +953,7 @@ run_hookasync_test(const ns__query_hookasync_test_params_t *test) {
/* If async event has started, manually invoke the 'done' event. */ /* If async event has started, manually invoke the 'done' event. */
if (asdata.async) { if (asdata.async) {
qctx->client->now = 0; /* set to sentinel before resume */ qctx->client->now = 0; /* set to sentinel before resume */
asdata.rev->ev_action(asdata.rev->ev_sender, asdata.rev->cb(asdata.rev);
(isc_event_t *)asdata.rev);
/* Confirm necessary cleanup has been performed. */ /* Confirm necessary cleanup has been performed. */
INSIST(qctx->client->query.hookactx == NULL); INSIST(qctx->client->query.hookactx == NULL);
@@ -1266,7 +1270,7 @@ typedef struct {
typedef struct hookasync_e2e_data { typedef struct hookasync_e2e_data {
bool async; /* true if in a hook-triggered bool async; /* true if in a hook-triggered
* asynchronous process */ * asynchronous process */
ns_hook_resevent_t *rev; /* resume event sent on completion */ ns_hook_resume_t *rev; /* resume state sent on completion */
ns_hookpoint_t hookpoint; /* specifies where to resume */ ns_hookpoint_t hookpoint; /* specifies where to resume */
isc_result_t start_result; /* result of 'runasync' */ isc_result_t start_result; /* result of 'runasync' */
dns_rcode_t expected_rcode; dns_rcode_t expected_rcode;
@@ -1282,10 +1286,10 @@ cancel_e2ehookactx(ns_hookasync_t *ctx) {
/* 'runasync' callback passed to ns_query_hookasync */ /* 'runasync' callback passed to ns_query_hookasync */
static isc_result_t static isc_result_t
test_hookasync_e2e(query_ctx_t *qctx, isc_mem_t *memctx, void *arg, test_hookasync_e2e(query_ctx_t *qctx, isc_mem_t *memctx, void *arg,
isc_task_t *task, isc_taskaction_t action, void *evarg, isc_loop_t *loop, isc_job_cb cb, void *evarg,
ns_hookasync_t **ctxp) { ns_hookasync_t **ctxp) {
ns_hookasync_t *ctx = NULL; ns_hookasync_t *ctx = NULL;
ns_hook_resevent_t *rev = NULL; ns_hook_resume_t *rev = NULL;
hookasync_e2e_data_t *asdata = arg; hookasync_e2e_data_t *asdata = arg;
if (asdata->start_result != ISC_R_SUCCESS) { if (asdata->start_result != ISC_R_SUCCESS) {
@@ -1293,19 +1297,24 @@ test_hookasync_e2e(query_ctx_t *qctx, isc_mem_t *memctx, void *arg,
} }
ctx = isc_mem_get(memctx, sizeof(*ctx)); ctx = isc_mem_get(memctx, sizeof(*ctx));
rev = (ns_hook_resevent_t *)isc_event_allocate( rev = isc_mem_get(memctx, sizeof(*rev));
memctx, task, NS_EVENT_HOOKASYNCDONE, action, evarg, *rev = (ns_hook_resume_t){
sizeof(*rev)); .hookpoint = asdata->hookpoint,
.saved_qctx = qctx,
.ctx = ctx,
.loop = loop,
.cb = cb,
.arg = evarg,
};
rev->hookpoint = asdata->hookpoint;
rev->saved_qctx = qctx;
rev->ctx = ctx;
asdata->rev = rev; asdata->rev = rev;
*ctx = (ns_hookasync_t){ .private = asdata }; *ctx = (ns_hookasync_t){
.destroy = destroy_hookactx,
.cancel = cancel_e2ehookactx,
.private = asdata,
};
isc_mem_attach(memctx, &ctx->mctx); isc_mem_attach(memctx, &ctx->mctx);
ctx->destroy = destroy_hookactx;
ctx->cancel = cancel_e2ehookactx;
*ctxp = ctx; *ctxp = ctx;
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
@@ -1413,8 +1422,7 @@ run_hookasync_e2e_test(const ns__query_hookasync_e2e_test_params_t *test) {
* If async event has started, manually invoke the done event. * If async event has started, manually invoke the done event.
*/ */
INSIST(asdata.async); INSIST(asdata.async);
asdata.rev->ev_action(asdata.rev->ev_sender, asdata.rev->cb(asdata.rev);
(isc_event_t *)asdata.rev);
/* /*
* Usually 'async' is reset to false on the 2nd call to * Usually 'async' is reset to false on the 2nd call to