1 // Copyright 2021 The Chromium OS Authors. All rights reserved. 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 base::{error, Event}; 6 use cros_async::{select2, AsyncError, EventAsync, Executor, SelectResult}; 7 use futures::pin_mut; 8 use thiserror::Error as ThisError; 9 use vm_memory::GuestMemory; 10 11 use crate::virtio::interrupt::SignalableInterrupt; 12 use crate::virtio::{Interrupt, Queue}; 13 14 #[derive(ThisError, Debug)] 15 enum Error { 16 /// Failed to read the resample event. 17 #[error("failed to read the resample event: {0}")] 18 ReadResampleEvent(AsyncError), 19 } 20 21 pub struct Worker { 22 pub queues: Vec<Queue>, 23 pub mem: GuestMemory, 24 pub kill_evt: Event, 25 } 26 27 impl Worker { 28 // Processes any requests to resample the irq value. handle_irq_resample( resample_evt: EventAsync, interrupt: Interrupt, ) -> Result<(), Error>29 async fn handle_irq_resample( 30 resample_evt: EventAsync, 31 interrupt: Interrupt, 32 ) -> Result<(), Error> { 33 loop { 34 let _ = resample_evt 35 .next_val() 36 .await 37 .map_err(Error::ReadResampleEvent)?; 38 interrupt.do_interrupt_resample(); 39 } 40 } 41 42 // Waits until the kill event is triggered. wait_kill(kill_evt: EventAsync)43 async fn wait_kill(kill_evt: EventAsync) { 44 // Once this event is readable, exit. Exiting this future will cause the main loop to 45 // break and the device process to exit. 46 let _ = kill_evt.next_val().await; 47 } 48 49 // Runs asynchronous tasks. run(&mut self, ex: &Executor, interrupt: Interrupt) -> Result<(), String>50 pub fn run(&mut self, ex: &Executor, interrupt: Interrupt) -> Result<(), String> { 51 let resample_evt = interrupt 52 .get_resample_evt() 53 .expect("resample event required") 54 .try_clone() 55 .expect("failed to clone resample event"); 56 let async_resample_evt = 57 EventAsync::new(resample_evt.0, ex).expect("failed to create async resample event"); 58 let resample = Self::handle_irq_resample(async_resample_evt, interrupt); 59 pin_mut!(resample); 60 61 let kill_evt = EventAsync::new( 62 self.kill_evt 63 .try_clone() 64 .expect("failed to clone kill_evt") 65 .0, 66 &ex, 67 ) 68 .expect("failed to create async kill event fd"); 69 let kill = Self::wait_kill(kill_evt); 70 pin_mut!(kill); 71 72 match ex.run_until(select2(resample, kill)) { 73 Ok((resample_res, _)) => { 74 if let SelectResult::Finished(Err(e)) = resample_res { 75 return Err(format!("failed to resample a irq value: {:?}", e)); 76 } 77 Ok(()) 78 } 79 Err(e) => Err(e.to_string()), 80 } 81 } 82 } 83