xref: /netbsd-src/external/mpl/bind/dist/lib/isc/loop_p.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
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