1use std::sync::atomic::{AtomicUsize, Ordering};
6use std::time::Duration;
7
8use diagnostics_traits::{InspectableValue, Inspector};
9
10use crate::parse::{IncomingResponseToRequestErrorCounters, SelectingIncomingMessageErrorCounters};
11
12#[derive(Default, Debug)]
14pub(crate) struct Counter(AtomicUsize);
15
16impl Counter {
17 pub(crate) fn increment(&self) {
18 let _: usize = self.0.fetch_add(1, Ordering::Relaxed);
19 }
20
21 pub(crate) fn load(&self) -> usize {
22 self.0.load(Ordering::Relaxed)
23 }
24}
25
26impl InspectableValue for Counter {
27 fn record<I: diagnostics_traits::Inspector>(&self, name: &str, inspector: &mut I) {
28 inspector.record_uint(name, u64::try_from(self.load()).unwrap_or(u64::MAX));
29 }
30}
31
32pub(crate) fn record_optional_duration_secs(
33 inspector: &mut impl Inspector,
34 name: &str,
35 value: Option<Duration>,
36) {
37 match value {
38 Some(value) => inspector.record_uint(name, value.as_secs()),
39 None => inspector.record_display(name, "Unset"),
40 }
41}
42
43#[derive(Debug, Default)]
45pub(crate) struct MessagingRelatedCounters {
46 pub(crate) send_message: Counter,
48 pub(crate) recv_message: Counter,
50 pub(crate) recv_message_fatal_socket_error: Counter,
53 pub(crate) recv_message_non_fatal_socket_error: Counter,
56 pub(crate) recv_time_out: Counter,
59 pub(crate) recv_wrong_xid: Counter,
62 pub(crate) recv_wrong_chaddr: Counter,
65 pub(crate) recv_failed_dhcp_parse: Counter,
68}
69
70impl MessagingRelatedCounters {
71 fn record(&self, inspector: &mut impl Inspector) {
72 let Self {
73 send_message,
74 recv_message,
75 recv_message_fatal_socket_error,
76 recv_message_non_fatal_socket_error,
77 recv_time_out,
78 recv_wrong_xid,
79 recv_wrong_chaddr,
80 recv_failed_dhcp_parse,
81 } = self;
82 inspector.record_inspectable_value("SendMessage", send_message);
83 inspector.record_inspectable_value("RecvMessage", recv_message);
84 inspector.record_inspectable_value(
85 "RecvMessageFatalSocketError",
86 recv_message_fatal_socket_error,
87 );
88 inspector.record_inspectable_value(
89 "RecvMessageNonFatalSocketError",
90 recv_message_non_fatal_socket_error,
91 );
92 inspector.record_inspectable_value("RecvTimeOut", recv_time_out);
93 inspector.record_inspectable_value("RecvWrongXid", recv_wrong_xid);
94 inspector.record_inspectable_value("RecvWrongChaddr", recv_wrong_chaddr);
95 inspector.record_inspectable_value("RecvFailedDhcpParse", recv_failed_dhcp_parse);
96 }
97}
98
99#[derive(Debug, Default)]
101pub(crate) struct InitCounters {
102 pub(crate) entered: Counter,
104}
105
106impl InitCounters {
107 fn record(&self, inspector: &mut impl Inspector) {
108 let Self { entered } = self;
109 inspector.record_inspectable_value("Entered", entered);
110 }
111}
112
113#[derive(Debug, Default)]
115pub(crate) struct SelectingCounters {
116 pub(crate) entered: Counter,
118 pub(crate) messaging: MessagingRelatedCounters,
120 pub(crate) recv_error: SelectingIncomingMessageErrorCounters,
123}
124
125impl SelectingCounters {
126 fn record(&self, inspector: &mut impl Inspector) {
127 let Self { entered, messaging, recv_error } = self;
128 inspector.record_inspectable_value("Entered", entered);
129 messaging.record(inspector);
130 recv_error.record(inspector);
131 }
132}
133
134#[derive(Debug, Default)]
136pub(crate) struct RequestingCounters {
137 pub(crate) entered: Counter,
139 pub(crate) messaging: MessagingRelatedCounters,
141 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
144 pub(crate) recv_nak: Counter,
147}
148
149impl RequestingCounters {
150 fn record(&self, inspector: &mut impl Inspector) {
151 let Self { entered, messaging, recv_error, recv_nak } = self;
152 inspector.record_inspectable_value("Entered", entered);
153 messaging.record(inspector);
154 recv_error.record(inspector);
155 inspector.record_inspectable_value("RecvNak", recv_nak);
156 }
157}
158
159#[derive(Debug, Default)]
161pub(crate) struct BoundCounters {
162 pub(crate) entered: Counter,
164 pub(crate) assigned: Counter,
166}
167
168impl BoundCounters {
169 fn record(&self, inspector: &mut impl Inspector) {
170 let Self { entered, assigned } = self;
171 inspector.record_inspectable_value("Entered", entered);
172 inspector.record_inspectable_value("Assigned", assigned);
173 }
174}
175
176#[derive(Debug, Default)]
178pub(crate) struct RenewingCounters {
179 pub(crate) entered: Counter,
181 pub(crate) messaging: MessagingRelatedCounters,
183 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
186 pub(crate) recv_nak: Counter,
189}
190
191impl RenewingCounters {
192 fn record(&self, inspector: &mut impl Inspector) {
193 let Self { entered, messaging, recv_error, recv_nak } = self;
194 inspector.record_inspectable_value("Entered", entered);
195 messaging.record(inspector);
196 recv_error.record(inspector);
197 inspector.record_inspectable_value("RecvNak", recv_nak);
198 }
199}
200
201#[derive(Debug, Default)]
203pub(crate) struct RebindingCounters {
204 pub(crate) entered: Counter,
206 pub(crate) messaging: MessagingRelatedCounters,
208 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
211 pub(crate) recv_nak: Counter,
214}
215
216impl RebindingCounters {
217 fn record(&self, inspector: &mut impl Inspector) {
218 let Self { entered, messaging, recv_error, recv_nak } = self;
219 inspector.record_inspectable_value("Entered", entered);
220 messaging.record(inspector);
221 recv_error.record(inspector);
222 inspector.record_inspectable_value("RecvNak", recv_nak);
223 }
224}
225
226#[derive(Debug, Default)]
228pub(crate) struct WaitingToRestartCounters {
229 pub(crate) entered: Counter,
231}
232
233impl WaitingToRestartCounters {
234 fn record(&self, inspector: &mut impl Inspector) {
235 let Self { entered } = self;
236 inspector.record_inspectable_value("Entered", entered);
237 }
238}
239
240#[derive(Default, Debug)]
242pub struct Counters {
243 pub(crate) init: InitCounters,
244 pub(crate) selecting: SelectingCounters,
245 pub(crate) requesting: RequestingCounters,
246 pub(crate) bound: BoundCounters,
247 pub(crate) renewing: RenewingCounters,
248 pub(crate) rebinding: RebindingCounters,
249 pub(crate) waiting_to_restart: WaitingToRestartCounters,
250}
251
252impl Counters {
253 pub fn record(&self, inspector: &mut impl Inspector) {
255 let Self { init, selecting, requesting, bound, renewing, rebinding, waiting_to_restart } =
256 self;
257 inspector.record_child("Init", |inspector| {
258 init.record(inspector);
259 });
260 inspector.record_child("Selecting", |inspector| {
261 selecting.record(inspector);
262 });
263 inspector.record_child("Requesting", |inspector| {
264 requesting.record(inspector);
265 });
266 inspector.record_child("Bound", |inspector| {
267 bound.record(inspector);
268 });
269 inspector.record_child("Renewing", |inspector| {
270 renewing.record(inspector);
271 });
272 inspector.record_child("Rebinding", |inspector| {
273 rebinding.record(inspector);
274 });
275 inspector.record_child("WaitingToRestart", |inspector| {
276 waiting_to_restart.record(inspector);
277 });
278 }
279}