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