Home | History | Annotate | Line # | Download | only in isc
      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