• 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 //! Virtio device async helper functions.
6 
7 use std::cell::RefCell;
8 use std::rc::Rc;
9 
10 use anyhow::{Context, Result};
11 use base::Event;
12 use cros_async::{EventAsync, Executor};
13 
14 use super::{Interrupt, SignalableInterrupt};
15 
16 /// Async task that waits for a signal from `event`.  Once this event is readable, exit. Exiting
17 /// this future will cause the main loop to break and the worker thread to exit.
await_and_exit(ex: &Executor, event: Event) -> Result<()>18 pub async fn await_and_exit(ex: &Executor, event: Event) -> Result<()> {
19     let event_async = EventAsync::new(event.0, ex).context("failed to create EventAsync")?;
20     let _ = event_async.next_val().await;
21     Ok(())
22 }
23 
24 /// Async task that resamples the status of the interrupt when the guest sends a request by
25 /// signalling the resample event associated with the interrupt.
handle_irq_resample(ex: &Executor, interrupt: Rc<RefCell<Interrupt>>) -> Result<()>26 pub async fn handle_irq_resample(ex: &Executor, interrupt: Rc<RefCell<Interrupt>>) -> Result<()> {
27     // Clone resample_evt if interrupt has one.
28     // This is a separate block so that we do not hold a RefCell borrow across await.
29     let resample_evt = if let Some(resample_evt) = interrupt.borrow().get_resample_evt() {
30         let resample_evt = resample_evt
31             .try_clone()
32             .context("resample_evt.try_clone() failed")?;
33         Some(EventAsync::new(resample_evt.0, ex).context("failed to create async resample event")?)
34     } else {
35         None
36     };
37 
38     if let Some(resample_evt) = resample_evt {
39         loop {
40             let _ = resample_evt
41                 .next_val()
42                 .await
43                 .context("failed to read resample event")?;
44             interrupt.borrow().do_interrupt_resample();
45         }
46     } else {
47         // No resample event; park the future.
48         let () = futures::future::pending().await;
49     }
50     Ok(())
51 }
52