From 8a5127b3259774ba878fedff9a4f173b83ea6e09 Mon Sep 17 00:00:00 2001 From: "Jorge E. Moreira" Date: Mon, 19 Apr 2021 12:43:17 -0700 Subject: Delay the start of VioS recv thread until after sandbox The recv thread was started immediately after the client object was created, which caused minijail to abort refusing to fork a multithreaded process. BUG=b/185811304 Change-Id: I5608e3b89eb4dfd944542d163e60b78937d37ba1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2837306 Tested-by: Jorge Moreira Broche Commit-Queue: Jorge Moreira Broche Reviewed-by: Dylan Reid --- devices/src/virtio/snd/vios_backend/shm_streams.rs | 1 + devices/src/virtio/snd/vios_backend/shm_vios.rs | 46 ++++++++++++++-------- 2 files changed, 30 insertions(+), 17 deletions(-) (limited to 'devices') diff --git a/devices/src/virtio/snd/vios_backend/shm_streams.rs b/devices/src/virtio/snd/vios_backend/shm_streams.rs index d05aa252a..5b5e0f641 100644 --- a/devices/src/virtio/snd/vios_backend/shm_streams.rs +++ b/devices/src/virtio/snd/vios_backend/shm_streams.rs @@ -89,6 +89,7 @@ impl ShmStreamSource for VioSShmStreamSource { client_shm: &SysSharedMemory, _buffer_offsets: [u64; 2], ) -> GenericResult> { + self.vios_client.ensure_bg_thread_started()?; let virtio_dir = match direction { StreamDirection::Playback => VIRTIO_SND_D_OUTPUT, StreamDirection::Capture => VIRTIO_SND_D_INPUT, diff --git a/devices/src/virtio/snd/vios_backend/shm_vios.rs b/devices/src/virtio/snd/vios_backend/shm_vios.rs index 824af5789..425a96871 100644 --- a/devices/src/virtio/snd/vios_backend/shm_vios.rs +++ b/devices/src/virtio/snd/vios_backend/shm_vios.rs @@ -110,7 +110,7 @@ pub struct VioSClient { rx_subscribers: Arc>>>, recv_running: Arc>, recv_event: Mutex, - recv_thread: Option>>, + recv_thread: Mutex>>>, } impl VioSClient { @@ -186,17 +186,6 @@ impl VioSClient { let recv_running = Arc::new(Mutex::new(true)); let recv_event = Event::new().map_err(|e| Error::EventCreateError(e))?; - let recv_thread = Some(spawn_recv_thread( - rx_subscribers.clone(), - recv_event - .try_clone() - .map_err(|e| Error::EventDupError(e))?, - recv_running.clone(), - rx_socket - .try_clone() - .map_err(|e| Error::UnixSeqpacketDupError(e))?, - )); - let mut client = VioSClient { config, streams: Mutex::new(Vec::new()), @@ -207,12 +196,36 @@ impl VioSClient { rx_subscribers, recv_running, recv_event: Mutex::new(recv_event), - recv_thread, + recv_thread: Mutex::new(None), }; client.request_and_cache_streams_info()?; Ok(client) } + pub fn ensure_bg_thread_started(&self) -> Result<()> { + let event_socket = self + .recv_event + .lock() + .try_clone() + .map_err(|e| Error::EventDupError(e))?; + let rx_socket = self + .rx + .lock() + .socket + .try_clone() + .map_err(|e| Error::UnixSeqpacketDupError(e))?; + let mut opt = self.recv_thread.lock(); + if opt.is_none() { + opt.get_or_insert(spawn_recv_thread( + self.rx_subscribers.clone(), + event_socket, + self.recv_running.clone(), + rx_socket, + )); + } + Ok(()) + } + /// Gets an unused stream id of the specified direction. `direction` must be one of /// VIRTIO_SND_D_INPUT OR VIRTIO_SND_D_OUTPUT. pub fn get_unused_stream_id(&self, direction: u8) -> Option { @@ -437,16 +450,15 @@ impl Drop for VioSClient { if let Err(e) = self.recv_event.lock().write(1u64) { error!("Failed to notify recv thread: {:?}", e); } - match self.recv_thread.take() { - None => error!("No Recv thread handle!! That's a bug."), - Some(handle) => match handle.join() { + if let Some(handle) = self.recv_thread.lock().take() { + match handle.join() { Ok(r) => { if let Err(e) = r { error!("Error detected on Recv Thread: {}", e); } } Err(e) => error!("Recv thread panicked: {:?}", e), - }, + }; } } } -- cgit v1.2.3