1 /* $NetBSD: loop_p.h,v 1.2 2025/01/26 16:25:37 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 #pragma once 17 18 #include <inttypes.h> 19 20 #include <isc/barrier.h> 21 #include <isc/job.h> 22 #include <isc/lang.h> 23 #include <isc/loop.h> 24 #include <isc/magic.h> 25 #include <isc/mem.h> 26 #include <isc/refcount.h> 27 #include <isc/result.h> 28 #include <isc/signal.h> 29 #include <isc/thread.h> 30 #include <isc/types.h> 31 #include <isc/urcu.h> 32 #include <isc/uv.h> 33 #include <isc/work.h> 34 35 #include "async_p.h" 36 #include "job_p.h" 37 38 /* 39 * Per-thread loop 40 */ 41 #define LOOP_MAGIC ISC_MAGIC('L', 'O', 'O', 'P') 42 #define VALID_LOOP(t) ISC_MAGIC_VALID(t, LOOP_MAGIC) 43 44 struct isc_loop { 45 int magic; 46 isc_refcount_t references; 47 isc_thread_t thread; 48 49 isc_loopmgr_t *loopmgr; 50 51 uv_loop_t loop; 52 uint32_t tid; 53 54 isc_mem_t *mctx; 55 56 /* states */ 57 bool paused; 58 bool shuttingdown; 59 60 /* Async queue */ 61 uv_async_t async_trigger; 62 isc_jobqueue_t async_jobs; 63 64 /* Jobs queue */ 65 uv_idle_t run_trigger; 66 isc_joblist_t run_jobs; 67 68 /* Pause */ 69 uv_async_t pause_trigger; 70 71 /* Shutdown */ 72 uv_async_t shutdown_trigger; 73 isc_jobqueue_t setup_jobs; 74 isc_jobqueue_t teardown_jobs; 75 76 /* Destroy */ 77 uv_async_t destroy_trigger; 78 79 /* safe memory reclamation */ 80 uv_prepare_t quiescent; 81 }; 82 83 /* 84 * Loop Manager 85 */ 86 #define LOOPMGR_MAGIC ISC_MAGIC('L', 'o', 'o', 'M') 87 #define VALID_LOOPMGR(t) ISC_MAGIC_VALID(t, LOOPMGR_MAGIC) 88 89 struct isc_loopmgr { 90 int magic; 91 isc_mem_t *mctx; 92 93 uint_fast32_t nloops; 94 95 atomic_bool shuttingdown; 96 atomic_bool running; 97 atomic_bool paused; 98 99 /* signal handling */ 100 isc_signal_t *sigint; 101 isc_signal_t *sigterm; 102 103 /* pause/resume */ 104 isc_barrier_t pausing; 105 isc_barrier_t resuming; 106 107 /* start/stop */ 108 isc_barrier_t starting; 109 110 /* stopping */ 111 isc_barrier_t stopping; 112 113 /* per-thread objects */ 114 isc_loop_t *loops; 115 isc_loop_t *helpers; 116 }; 117 118 /* 119 * Signal Handler 120 */ 121 #define SIGNAL_MAGIC ISC_MAGIC('S', 'I', 'G', ' ') 122 #define VALID_SIGNAL(t) ISC_MAGIC_VALID(t, SIGNAL_MAGIC) 123 124 struct isc_signal { 125 int magic; 126 uv_signal_t signal; 127 isc_loop_t *loop; 128 isc_signal_cb cb; 129 void *cbarg; 130 int signum; 131 }; 132 133 /* 134 * Job to be scheduled in an event loop 135 */ 136 #define JOB_MAGIC ISC_MAGIC('J', 'O', 'B', ' ') 137 #define VALID_JOB(t) ISC_MAGIC_VALID(t, JOB_MAGIC) 138 139 /* 140 * Work to be offloaded to an external thread. 141 */ 142 struct isc_work { 143 uv_work_t work; 144 isc_loop_t *loop; 145 isc_work_cb work_cb; 146 isc_after_work_cb after_work_cb; 147 void *cbarg; 148 }; 149 150 #define DEFAULT_LOOP(loopmgr) (&(loopmgr)->loops[0]) 151 #define CURRENT_LOOP(loopmgr) (&(loopmgr)->loops[isc_tid()]) 152 #define LOOP(loopmgr, tid) (&(loopmgr)->loops[tid]) 153 #define ON_LOOP(loop) ((loop) == CURRENT_LOOP((loop)->loopmgr)) 154