1 /* $NetBSD: work.c,v 1.2 2025/01/26 16:25:39 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #include <stdlib.h> 17 18 #include <isc/job.h> 19 #include <isc/loop.h> 20 #include <isc/urcu.h> 21 #include <isc/uv.h> 22 #include <isc/work.h> 23 24 #include "loop_p.h" 25 26 static void 27 isc__work_cb(uv_work_t *req) { 28 isc_work_t *work = uv_req_get_data((uv_req_t *)req); 29 30 rcu_register_thread(); 31 32 work->work_cb(work->cbarg); 33 34 rcu_unregister_thread(); 35 } 36 37 static void 38 isc__after_work_cb(uv_work_t *req, int status) { 39 isc_work_t *work = uv_req_get_data((uv_req_t *)req); 40 isc_loop_t *loop = work->loop; 41 42 UV_RUNTIME_CHECK(uv_after_work_cb, status); 43 44 work->after_work_cb(work->cbarg); 45 46 isc_mem_put(loop->mctx, work, sizeof(*work)); 47 48 isc_loop_detach(&loop); 49 } 50 51 void 52 isc_work_enqueue(isc_loop_t *loop, isc_work_cb work_cb, 53 isc_after_work_cb after_work_cb, void *cbarg) { 54 isc_work_t *work = NULL; 55 int r; 56 57 REQUIRE(VALID_LOOP(loop)); 58 REQUIRE(work_cb != NULL); 59 REQUIRE(after_work_cb != NULL); 60 61 work = isc_mem_get(loop->mctx, sizeof(*work)); 62 *work = (isc_work_t){ 63 .work_cb = work_cb, 64 .after_work_cb = after_work_cb, 65 .cbarg = cbarg, 66 }; 67 68 isc_loop_attach(loop, &work->loop); 69 70 uv_req_set_data((uv_req_t *)&work->work, work); 71 72 r = uv_queue_work(&loop->loop, &work->work, isc__work_cb, 73 isc__after_work_cb); 74 UV_RUNTIME_CHECK(uv_queue_work, r); 75 } 76