Home | History | Annotate | Line # | Download | only in isc
      1 /*	$NetBSD: loop_p.h,v 1.3 2026/08/29 14:55:18 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 	/* thread pools */
     83 	isc__workthread_t *workthreads[ISC_WORKLANE_COUNT];
     84 };
     85 
     86 /*
     87  * Loop Manager
     88  */
     89 #define LOOPMGR_MAGIC	 ISC_MAGIC('L', 'o', 'o', 'M')
     90 #define VALID_LOOPMGR(t) ISC_MAGIC_VALID(t, LOOPMGR_MAGIC)
     91 
     92 struct isc_loopmgr {
     93 	int magic;
     94 	isc_mem_t *mctx;
     95 
     96 	uint_fast32_t nloops;
     97 
     98 	atomic_bool shuttingdown;
     99 	atomic_bool running;
    100 	atomic_bool paused;
    101 
    102 	/* signal handling */
    103 	isc_signal_t *sigint;
    104 	isc_signal_t *sigterm;
    105 
    106 	/* pause/resume */
    107 	isc_barrier_t pausing;
    108 	isc_barrier_t resuming;
    109 
    110 	/* start/stop */
    111 	isc_barrier_t starting;
    112 
    113 	/* stopping */
    114 	isc_barrier_t stopping;
    115 
    116 	/* per-thread objects */
    117 	isc_loop_t *loops;
    118 };
    119 
    120 /*
    121  * Signal Handler
    122  */
    123 #define SIGNAL_MAGIC	ISC_MAGIC('S', 'I', 'G', ' ')
    124 #define VALID_SIGNAL(t) ISC_MAGIC_VALID(t, SIGNAL_MAGIC)
    125 
    126 struct isc_signal {
    127 	int magic;
    128 	uv_signal_t signal;
    129 	isc_loop_t *loop;
    130 	isc_signal_cb cb;
    131 	void *cbarg;
    132 	int signum;
    133 };
    134 
    135 /*
    136  * Job to be scheduled in an event loop
    137  */
    138 #define JOB_MAGIC    ISC_MAGIC('J', 'O', 'B', ' ')
    139 #define VALID_JOB(t) ISC_MAGIC_VALID(t, JOB_MAGIC)
    140 
    141 #define DEFAULT_LOOP(loopmgr) (&(loopmgr)->loops[0])
    142 #define CURRENT_LOOP(loopmgr) (&(loopmgr)->loops[isc_tid()])
    143 #define LOOP(loopmgr, tid)    (&(loopmgr)->loops[tid])
    144 #define ON_LOOP(loop)	      ((loop) == CURRENT_LOOP((loop)->loopmgr))
    145 
    146 isc__workthread_t *
    147 isc__loopmgr_workthread(isc_loop_t *loop, isc_worklane_t lane);
    148 
    149 void
    150 isc__loopmgr_starting(isc_loop_t *loop);
    151 void
    152 isc__loopmgr_stopping(isc_loop_t *loop);
    153