1 /* $NetBSD: loop.h,v 1.3 2026/08/29 14:55:19 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/job.h> 21 #include <isc/lang.h> 22 #include <isc/mem.h> 23 #include <isc/refcount.h> 24 #include <isc/types.h> 25 #include <isc/urcu.h> 26 #include <isc/work.h> 27 28 typedef void (*isc_job_cb)(void *); 29 30 /* Add -DISC_LOOP_TRACE=1 to CFLAGS for detailed reference tracing */ 31 32 ISC_LANG_BEGINDECLS 33 34 /*%< 35 * Returns the current running loop. 36 */ 37 38 extern thread_local isc_loop_t *isc__loop_local; 39 40 static inline isc_loop_t * 41 isc_loop(void) { 42 return isc__loop_local; 43 } 44 void 45 isc_loopmgr_create(isc_mem_t *mctx, uint32_t nloops, isc_loopmgr_t **loopmgrp); 46 /*%< 47 * Create a loop manager supporting 'nloops' loops. 48 * 49 * Requires: 50 *\li 'nloops' is greater than 0. 51 */ 52 53 void 54 isc_loopmgr_destroy(isc_loopmgr_t **loopmgrp); 55 /*%< 56 * Destroy the loop manager pointed to by 'loopmgrp'. 57 * 58 * Requires: 59 *\li 'loopmgr' points to a valid loop manager. 60 */ 61 62 void 63 isc_loopmgr_shutdown(isc_loopmgr_t *loopmgr); 64 /*%< 65 * Request shutdown of the loop manager 'loopmgr'. 66 * 67 * This will stop all signal handlers and send shutdown events to 68 * all active loops. As a final action on shutting down, each loop 69 * will run the function (or functions) set by isc_loopmgr_teardown() 70 * or isc_loop_teardown(). 71 * 72 * Requires: 73 *\li 'loopmgr' is a valid loop manager. 74 */ 75 76 void 77 isc_loopmgr_run(isc_loopmgr_t *loopmgr); 78 /*%< 79 * Run the loops in 'loopmgr'. Each loop will start by running the 80 * function (or functions) set by isc_loopmgr_setup() or isc_loop_setup(). 81 * 82 * Requires: 83 *\li 'loopmgr' is a valid loop manager. 84 */ 85 86 void 87 isc_loopmgr_pause(isc_loopmgr_t *loopmgr); 88 /*%< 89 * Send pause events to all running loops in 'loopmgr' except the 90 * current one. This can only be called from a running loop. 91 * All the paused loops will wait until isc_loopmgr_resume() is 92 * run in the calling loop before continuing. 93 * 94 * Requires: 95 *\li 'loopmgr' is a valid loop manager. 96 *\li We are in a running loop. 97 */ 98 99 void 100 isc_loopmgr_resume(isc_loopmgr_t *loopmgr); 101 /*%< 102 * Send resume events to all paused loops in 'loopmgr'. This can 103 * only be called by a running loop (which must therefore be the 104 * loop that called isc_loopmgr_pause()). 105 * 106 * Requires: 107 *\li 'loopmgr' is a valid loop manager. 108 *\li We are in a running loop. 109 */ 110 111 uint32_t 112 isc_loopmgr_nloops(isc_loopmgr_t *loopmgr); 113 114 isc_job_t * 115 isc_loop_setup(isc_loop_t *loop, isc_job_cb cb, void *cbarg); 116 isc_job_t * 117 isc_loop_teardown(isc_loop_t *loop, isc_job_cb cb, void *cbarg); 118 /*%< 119 * Schedule actions to be run when starting, and when shutting down, 120 * one of the loops in a loop manager. 121 * 122 * Requires: 123 *\li 'loop' is a valid loop. 124 *\li The loop manager associated with 'loop' is paused or has not 125 * yet been started. 126 */ 127 128 void 129 isc_loopmgr_setup(isc_loopmgr_t *loopmgr, isc_job_cb cb, void *cbarg); 130 void 131 isc_loopmgr_teardown(isc_loopmgr_t *loopmgr, isc_job_cb cb, void *cbarg); 132 /*%< 133 * Schedule actions to be run when starting, and when shutting down, 134 * *all* of the loops in loopmgr. 135 * 136 * This is the same as running isc_loop_setup() or 137 * isc_loop_teardown() on each of the loops in turn. 138 * 139 * Requires: 140 *\li 'loopmgr' is a valid loop manager. 141 *\li 'loopmgr' is paused or has not yet been started. 142 */ 143 144 isc_mem_t * 145 isc_loop_getmctx(isc_loop_t *loop); 146 /*%< 147 * Return a pointer to the a memory context that was created for 148 * 'loop' when it was initialized. 149 * 150 * Requires: 151 *\li 'loop' is a valid loop. 152 */ 153 154 isc_loop_t * 155 isc_loop_main(isc_loopmgr_t *loopmgr); 156 /*%< 157 * Returns the main loop for the 'loopmgr' (which is 'loopmgr->loops[0]', 158 * regardless of how many loops there are). 159 * 160 * Requires: 161 *\li 'loopmgr' is a valid loop manager. 162 */ 163 164 isc_loop_t * 165 isc_loop_get(isc_loopmgr_t *loopmgr, uint32_t tid); 166 /*%< 167 * Return the loop object associated with the 'tid' threadid 168 * 169 * Requires: 170 *\li 'loopmgr' is a valid loop manager. 171 *\li 'tid' is smaller than number of initialized loops 172 */ 173 174 # 175 176 #if ISC_LOOP_TRACE 177 #define isc_loop_ref(ptr) isc_loop__ref(ptr, __func__, __FILE__, __LINE__) 178 #define isc_loop_unref(ptr) isc_loop__unref(ptr, __func__, __FILE__, __LINE__) 179 #define isc_loop_attach(ptr, ptrp) \ 180 isc_loop__attach(ptr, ptrp, __func__, __FILE__, __LINE__) 181 #define isc_loop_detach(ptrp) \ 182 isc_loop__detach(ptrp, __func__, __FILE__, __LINE__) 183 ISC_REFCOUNT_TRACE_DECL(isc_loop); 184 #else 185 ISC_REFCOUNT_DECL(isc_loop); 186 #endif 187 /*%< 188 * Reference counting functions for isc_loop 189 */ 190 191 void 192 isc_loopmgr_blocking(isc_loopmgr_t *loopmgr); 193 void 194 isc_loopmgr_nonblocking(isc_loopmgr_t *loopmgr); 195 /*%< 196 * isc_loopmgr_blocking() stops the SIGINT and SIGTERM signal handlers 197 * during blocking operations, for example while waiting for user 198 * interaction; isc_loopmgr_nonblocking() restarts them. 199 * 200 * Requires: 201 *\li 'loopmgr' is a valid loop manager. 202 */ 203 204 isc_loopmgr_t * 205 isc_loop_getloopmgr(isc_loop_t *loop); 206 /*%< 207 * Return the loopmgr associated with 'loop'. 208 * 209 * Requires: 210 *\li 'loop' is a valid loop. 211 */ 212 213 isc_time_t 214 isc_loop_now(isc_loop_t *loop); 215 /*%< 216 * Returns the start time of the current loop tick. 217 * 218 * Requires: 219 * 220 * \li 'loop' is a valid loop. 221 */ 222 223 bool 224 isc_loop_shuttingdown(isc_loop_t *loop); 225 /*%< 226 * Returns whether the loop is shutting down. 227 * 228 * Requires: 229 * 230 * \li 'loop' is a valid loop and the loop tid matches the current tid. 231 */ 232 233 ISC_LANG_ENDDECLS 234