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