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