• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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