summary refs log tree commit diff
path: root/devices/src/usb
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2019-09-12 13:34:50 -0700
committerCommit Bot <commit-bot@chromium.org>2019-09-17 22:32:22 +0000
commit9dd75d0d3e1a7fa8226bef55a40a608beff5baf7 (patch)
treef5b368968319b8563f237f78b1a0f707bc976714 /devices/src/usb
parent94c352752e1109fc6cf7c0cf9c6ce121ad1d46b9 (diff)
downloadcrosvm-9dd75d0d3e1a7fa8226bef55a40a608beff5baf7.tar
crosvm-9dd75d0d3e1a7fa8226bef55a40a608beff5baf7.tar.gz
crosvm-9dd75d0d3e1a7fa8226bef55a40a608beff5baf7.tar.bz2
crosvm-9dd75d0d3e1a7fa8226bef55a40a608beff5baf7.tar.lz
crosvm-9dd75d0d3e1a7fa8226bef55a40a608beff5baf7.tar.xz
crosvm-9dd75d0d3e1a7fa8226bef55a40a608beff5baf7.tar.zst
crosvm-9dd75d0d3e1a7fa8226bef55a40a608beff5baf7.zip
devices: join worker threads in drop()
Make sure all devices join any threads they spawn before returning from
the drop() handler after signaling the exit event.

BUG=chromium:992494
TEST=crosvm exits without errors

Change-Id: I6bc91c32a08f568b041765044caa9aff6f7cf4a9
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1802156
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'devices/src/usb')
-rw-r--r--devices/src/usb/xhci/xhci.rs16
1 files changed, 15 insertions, 1 deletions
diff --git a/devices/src/usb/xhci/xhci.rs b/devices/src/usb/xhci/xhci.rs
index 47ebe85..bd8e217 100644
--- a/devices/src/usb/xhci/xhci.rs
+++ b/devices/src/usb/xhci/xhci.rs
@@ -14,6 +14,7 @@ use crate::usb::host_backend::host_backend_device_provider::HostBackendDevicePro
 use crate::utils::{Error as UtilsError, EventLoop, FailHandle};
 use std::fmt::{self, Display};
 use std::sync::Arc;
+use std::thread;
 use sync::Mutex;
 use sys_util::{error, EventFd, GuestAddress, GuestMemory};
 
@@ -65,6 +66,8 @@ pub struct Xhci {
     interrupter: Arc<Mutex<Interrupter>>,
     command_ring_controller: Arc<CommandRingController>,
     device_slots: DeviceSlots,
+    event_loop: Arc<EventLoop>,
+    event_loop_join_handle: Option<thread::JoinHandle<()>>,
     // resample handler and device provider only lives on EventLoop to handle corresponding events.
     // By design, event loop only hold weak reference. We need to keep a strong reference here to
     // keep it alive.
@@ -84,7 +87,7 @@ impl Xhci {
         irq_resample_evt: EventFd,
         regs: XhciRegs,
     ) -> Result<Arc<Self>> {
-        let (event_loop, _join_handle) =
+        let (event_loop, join_handle) =
             EventLoop::start("xhci".to_string(), Some(fail_handle.clone()))
                 .map_err(Error::StartEventLoop)?;
         let interrupter = Arc::new(Mutex::new(Interrupter::new(mem.clone(), irq_evt, &regs)));
@@ -122,6 +125,8 @@ impl Xhci {
             command_ring_controller,
             device_slots,
             device_provider,
+            event_loop,
+            event_loop_join_handle: Some(join_handle),
         });
         Self::init_reg_callbacks(&xhci);
         Ok(xhci)
@@ -390,3 +395,12 @@ impl Xhci {
         Ok(())
     }
 }
+
+impl Drop for Xhci {
+    fn drop(&mut self) {
+        self.event_loop.stop();
+        if let Some(join_handle) = self.event_loop_join_handle.take() {
+            let _ = join_handle.join();
+        }
+    }
+}