xref: /aosp_15_r20/external/crosvm/metrics/src/sys/windows/controller.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use anyhow::Result;
6 use base::CloseNotifier;
7 use base::ReadNotifier;
8 use base::WaitContext;
9 
10 use crate::controller::MetricsController;
11 use crate::controller::MetricsControllerToken;
12 
13 impl MetricsController {
run_internal(&mut self) -> Result<()>14     pub(crate) fn run_internal(&mut self) -> Result<()> {
15         let wait_ctx: WaitContext<MetricsControllerToken> = WaitContext::new()?;
16         self.closed_tubes = 0;
17 
18         for (agent_index, agent) in self.agents.iter().enumerate() {
19             wait_ctx.add(
20                 agent.get_read_notifier(),
21                 MetricsControllerToken::Agent(agent_index),
22             )?;
23             wait_ctx.add(
24                 agent.get_close_notifier(),
25                 MetricsControllerToken::AgentExited(agent_index),
26             )?;
27         }
28 
29         'listen: loop {
30             let events = wait_ctx.wait()?;
31             for event in events.iter().filter(|e| e.is_readable) {
32                 match event.token {
33                     MetricsControllerToken::Agent(client_index) => {
34                         self.on_tube_readable(&self.agents[client_index]);
35                     }
36                     MetricsControllerToken::AgentExited(client_index) => {
37                         let client = &self.agents[client_index];
38                         wait_ctx.delete(client.get_read_notifier())?;
39                         wait_ctx.delete(client.get_close_notifier())?;
40                         if self.on_connection_closed() {
41                             break 'listen;
42                         }
43                     }
44                 }
45             }
46         }
47         Ok(())
48     }
49 }
50