Merge branch '4380-keep-the-offloaded-work-result-local' into 'main'

Don't set the offloaded work result from main thread

Closes #4380

See merge request isc-projects/bind9!8407
This commit is contained in:
Ondřej Surý 2023-10-24 10:49:42 +00:00
commit efbdee5b3a

View file

@ -134,7 +134,6 @@ struct dns_xfrin {
bool diff_running;
struct __cds_wfcq_head diff_head;
struct cds_wfcq_tail diff_tail;
isc_result_t result;
_Atomic xfrin_state_t state;
uint32_t expireopt;
@ -196,6 +195,11 @@ struct dns_xfrin {
#define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
#define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
typedef struct xfrin_work {
dns_xfrin_t *xfr;
isc_result_t result;
} xfrin_work_t;
/**************************************************************************/
/*
* Forward declarations.
@ -328,10 +332,13 @@ failure:
*/
static void
axfr_apply(void *arg) {
dns_xfrin_t *xfr = arg;
xfrin_work_t *work = arg;
dns_xfrin_t *xfr = work->xfr;
isc_result_t result = ISC_R_SUCCESS;
uint64_t records;
REQUIRE(VALID_XFRIN(xfr));
if (atomic_load(&xfr->shuttingdown)) {
result = ISC_R_SHUTTINGDOWN;
goto failure;
@ -348,13 +355,16 @@ axfr_apply(void *arg) {
failure:
dns_diff_clear(&xfr->diff);
xfr->result = result;
work->result = result;
}
static void
axfr_apply_done(void *arg) {
dns_xfrin_t *xfr = arg;
isc_result_t result = xfr->result;
xfrin_work_t *work = arg;
dns_xfrin_t *xfr = work->xfr;
isc_result_t result = work->result;
REQUIRE(VALID_XFRIN(xfr));
if (atomic_load(&xfr->shuttingdown)) {
result = ISC_R_SHUTTINGDOWN;
@ -371,6 +381,8 @@ axfr_apply_done(void *arg) {
failure:
xfr->diff_running = false;
isc_mem_put(xfr->mctx, work, sizeof(*work));
if (result == ISC_R_SUCCESS) {
if (atomic_load(&xfr->state) == XFRST_AXFR_END) {
xfrin_end(xfr, result);
@ -384,11 +396,16 @@ failure:
static void
axfr_commit(dns_xfrin_t *xfr) {
INSIST(!xfr->diff_running);
REQUIRE(!xfr->diff_running);
xfrin_work_t *work = isc_mem_get(xfr->mctx, sizeof(*work));
*work = (xfrin_work_t){
.xfr = dns_xfrin_ref(xfr),
.result = ISC_R_UNSET,
};
xfr->diff_running = true;
dns_xfrin_ref(xfr);
isc_work_enqueue(dns_zone_getloop(xfr->zone), axfr_apply,
axfr_apply_done, xfr);
axfr_apply_done, work);
}
static isc_result_t
@ -409,7 +426,6 @@ axfr_finalize(dns_xfrin_t *xfr) {
typedef struct ixfr_apply_data {
dns_diff_t diff; /*%< Pending database changes */
isc_result_t result;
struct cds_wfcq_node wfcq_node;
} ixfr_apply_data_t;
@ -514,9 +530,12 @@ failure:
static void
ixfr_apply(void *arg) {
dns_xfrin_t *xfr = arg;
xfrin_work_t *work = arg;
dns_xfrin_t *xfr = work->xfr;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(VALID_XFRIN(xfr));
struct __cds_wfcq_head diff_head;
struct cds_wfcq_tail diff_tail;
@ -547,14 +566,16 @@ ixfr_apply(void *arg) {
isc_mem_put(xfr->mctx, data, sizeof(*data));
}
/* FIXME: This might need a barrier or smth */
xfr->result = result;
work->result = result;
}
static void
ixfr_apply_done(void *arg) {
dns_xfrin_t *xfr = arg;
isc_result_t result = xfr->result;
xfrin_work_t *work = arg;
dns_xfrin_t *xfr = work->xfr;
isc_result_t result = work->result;
REQUIRE(VALID_XFRIN(xfr));
if (atomic_load(&xfr->shuttingdown)) {
result = ISC_R_SHUTTINGDOWN;
@ -567,13 +588,15 @@ ixfr_apply_done(void *arg) {
/* Reschedule */
if (!cds_wfcq_empty(&xfr->diff_head, &xfr->diff_tail)) {
isc_work_enqueue(dns_zone_getloop(xfr->zone), ixfr_apply,
ixfr_apply_done, xfr);
ixfr_apply_done, work);
return;
}
failure:
xfr->diff_running = false;
isc_mem_put(xfr->mctx, work, sizeof(*work));
if (result == ISC_R_SUCCESS) {
dns_db_closeversion(xfr->db, &xfr->ver, true);
dns_zone_markdirty(xfr->zone);
@ -613,10 +636,14 @@ ixfr_commit(dns_xfrin_t *xfr) {
&data->wfcq_node);
if (!xfr->diff_running) {
dns_xfrin_ref(xfr);
xfrin_work_t *work = isc_mem_get(xfr->mctx, sizeof(*work));
*work = (xfrin_work_t){
.xfr = dns_xfrin_ref(xfr),
.result = ISC_R_UNSET,
};
xfr->diff_running = true;
isc_work_enqueue(dns_zone_getloop(xfr->zone), ixfr_apply,
ixfr_apply_done, xfr);
ixfr_apply_done, work);
}
failure:
@ -1973,7 +2000,6 @@ xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg) {
failure:
if (result != ISC_R_SUCCESS) {
xfr->result = result;
xfrin_fail(xfr, result, "failed while receiving responses");
}