devices: virtio: async_utils: do not borrow interrupt across await

Update handle_irq_resample() to resemble the previously-removed async
block version, which clones the resample event in a separate block so
that the Rc<RefCell<...>> is not borrowed across await. Otherwise, other
users of the Rc<RefCell<Interrupt>> cannot borrow it mutably.

BUG=b:208264646
TEST=tools/presubmit
TEST=Boot Crostini on hatch

Change-Id: I2505d580ae7813b20fff60e7ced0e4f706339a81
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3311457
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
Daniel Verkamp 2021-12-01 10:10:46 -08:00 committed by Commit Bot
parent 51e0cab41d
commit d2172d435f

View file

@ -24,12 +24,18 @@ pub async fn await_and_exit(ex: &Executor, event: Event) -> Result<()> {
/// Async task that resamples the status of the interrupt when the guest sends a request by
/// signalling the resample event associated with the interrupt.
pub async fn handle_irq_resample(ex: &Executor, interrupt: Rc<RefCell<Interrupt>>) -> Result<()> {
if let Some(resample_evt) = interrupt.borrow().get_resample_evt() {
// Clone resample_evt if interrupt has one.
// This is a separate block so that we do not hold a RefCell borrow across await.
let resample_evt = if let Some(resample_evt) = interrupt.borrow().get_resample_evt() {
let resample_evt = resample_evt
.try_clone()
.context("resample_evt.try_clone() failed")?;
let resample_evt =
EventAsync::new(resample_evt.0, ex).context("failed to create async resample event")?;
Some(EventAsync::new(resample_evt.0, ex).context("failed to create async resample event")?)
} else {
None
};
if let Some(resample_evt) = resample_evt {
loop {
let _ = resample_evt
.next_val()