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