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