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