diff --git a/devices/src/virtio/vhost/user/vmm/block.rs b/devices/src/virtio/vhost/user/vmm/block.rs index 8a41a1e4b3..dc29b11975 100644 --- a/devices/src/virtio/vhost/user/vmm/block.rs +++ b/devices/src/virtio/vhost/user/vmm/block.rs @@ -13,7 +13,7 @@ use virtio_sys::virtio_ring::VIRTIO_RING_F_EVENT_IDX; use vm_memory::GuestMemory; use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; -use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, worker::Worker}; +use crate::virtio::vhost::user::vmm::handler::VhostUserHandler; use crate::virtio::{block::common::virtio_blk_config, DeviceType, Interrupt, Queue, VirtioDevice}; const VIRTIO_BLK_F_SEG_MAX: u32 = 2; @@ -27,7 +27,7 @@ const QUEUE_SIZE: u16 = 256; pub struct Block { kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, queue_sizes: Vec, } @@ -105,45 +105,17 @@ impl VirtioDevice for Block { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self + match self .handler .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) + .activate(mem, interrupt, queues, queue_evts, "block") { - error!("failed to activate queues: {}", e); - return; - } - - let (self_kill_evt, kill_evt) = match Event::new().and_then(|e| Ok((e.try_clone()?, e))) { - Ok(v) => v, - Err(e) => { - error!("failed creating kill Event pair: {}", e); - return; - } - }; - self.kill_evt = Some(self_kill_evt); - - let worker_result = thread::Builder::new() - .name("vhost_user_virtio_blk".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }); - - match worker_result { - Err(e) => { - error!("failed to spawn vhost-user virtio_blk worker: {}", e); - } - Ok(join_handle) => { + Ok((join_handle, kill_evt)) => { self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); } } } diff --git a/devices/src/virtio/vhost/user/vmm/console.rs b/devices/src/virtio/vhost/user/vmm/console.rs index 7192d248b1..a767ce1911 100644 --- a/devices/src/virtio/vhost/user/vmm/console.rs +++ b/devices/src/virtio/vhost/user/vmm/console.rs @@ -12,12 +12,12 @@ use vm_memory::GuestMemory; use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use crate::virtio::console::{virtio_console_config, QUEUE_SIZE}; -use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, worker::Worker, Error, Result}; +use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, Error, Result}; use crate::virtio::{DeviceType, Interrupt, Queue, VirtioDevice}; pub struct Console { kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, queue_sizes: Vec, } @@ -88,44 +88,17 @@ impl VirtioDevice for Console { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self + match self .handler .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) + .activate(mem, interrupt, queues, queue_evts, "console") { - error!("failed to activate queues: {}", e); - return; - } - let (self_kill_evt, kill_evt) = match Event::new().and_then(|e| Ok((e.try_clone()?, e))) { - Ok(v) => v, - Err(e) => { - error!("failed creating kill Event pair: {}", e); - return; - } - }; - self.kill_evt = Some(self_kill_evt); - - let worker_result = thread::Builder::new() - .name("vhost_user_virtio_console".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }); - - match worker_result { - Err(e) => { - error!("failed to spawn vhost-user virtio_console worker: {}", e); - } - Ok(join_handle) => { + Ok((join_handle, kill_evt)) => { self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); } } } diff --git a/devices/src/virtio/vhost/user/vmm/fs.rs b/devices/src/virtio/vhost/user/vmm/fs.rs index b285d4836d..c578af26d7 100644 --- a/devices/src/virtio/vhost/user/vmm/fs.rs +++ b/devices/src/virtio/vhost/user/vmm/fs.rs @@ -14,14 +14,14 @@ use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vmm_vhost::Error as VhostUserError; use crate::virtio::fs::{virtio_fs_config, FS_MAX_TAG_LEN, QUEUE_SIZE}; -use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, worker::Worker, Error, Result}; +use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, Error, Result}; use crate::virtio::{copy_config, DeviceType}; use crate::virtio::{Interrupt, Queue, VirtioDevice}; pub struct Fs { cfg: virtio_fs_config, kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, queue_sizes: Vec, } @@ -120,45 +120,17 @@ impl VirtioDevice for Fs { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self + match self .handler .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) + .activate(mem, interrupt, queues, queue_evts, "fs") { - error!("failed to activate queues: {}", e); - return; - } - - let (self_kill_evt, kill_evt) = match Event::new().and_then(|e| Ok((e.try_clone()?, e))) { - Ok(v) => v, - Err(e) => { - error!("failed creating kill Event pair: {}", e); - return; - } - }; - self.kill_evt = Some(self_kill_evt); - - let worker_result = thread::Builder::new() - .name("vhost_user_virtio_fs".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }); - - match worker_result { - Err(e) => { - error!("failed to spawn vhost-user virtio_fs worker: {}", e); - } - Ok(join_handle) => { + Ok((join_handle, kill_evt)) => { self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); } } } diff --git a/devices/src/virtio/vhost/user/vmm/gpu.rs b/devices/src/virtio/vhost/user/vmm/gpu.rs index 796e4fb06a..d0b4aea2c5 100644 --- a/devices/src/virtio/vhost/user/vmm/gpu.rs +++ b/devices/src/virtio/vhost/user/vmm/gpu.rs @@ -12,7 +12,7 @@ use crate::{ pci::{PciBarConfiguration, PciCapability}, virtio::{ gpu::QUEUE_SIZES, - vhost::user::vmm::{worker::Worker, Result, VhostUserHandler}, + vhost::user::vmm::{Result, VhostUserHandler}, virtio_gpu_config, DeviceType, Interrupt, PciCapabilityType, Queue, VirtioDevice, VirtioPciShmCap, GPU_BAR_NUM, GPU_BAR_OFFSET, VIRTIO_GPU_F_CONTEXT_INIT, VIRTIO_GPU_F_CREATE_GUEST_HANDLE, VIRTIO_GPU_F_RESOURCE_BLOB, VIRTIO_GPU_F_RESOURCE_SYNC, @@ -37,7 +37,7 @@ enum GpuState { pub struct Gpu { kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, state: GpuState, queue_sizes: Vec, @@ -149,45 +149,17 @@ impl VirtioDevice for Gpu { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self + match self .handler .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) + .activate(mem, interrupt, queues, queue_evts, "gpu") { - error!("failed to activate queues: {}", e); - return; - } - - let (self_kill_evt, kill_evt) = match Event::new().and_then(|e| Ok((e.try_clone()?, e))) { - Ok(v) => v, - Err(e) => { - error!("failed creating kill Event pair: {}", e); - return; - } - }; - self.kill_evt = Some(self_kill_evt); - - let worker_result = thread::Builder::new() - .name("vhost_user_gpu".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }); - - match worker_result { - Err(e) => { - error!("failed to spawn vhost_user_gpu worker: {}", e); - } - Ok(join_handle) => { + Ok((join_handle, kill_evt)) => { self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); } } } diff --git a/devices/src/virtio/vhost/user/vmm/handler.rs b/devices/src/virtio/vhost/user/vmm/handler.rs index 710730aa6d..49806bf530 100644 --- a/devices/src/virtio/vhost/user/vmm/handler.rs +++ b/devices/src/virtio/vhost/user/vmm/handler.rs @@ -5,8 +5,9 @@ mod sys; use std::io::Write; +use std::thread; -use base::{AsRawDescriptor, Event, Tube}; +use base::{error, AsRawDescriptor, Event, Tube}; use vm_memory::GuestMemory; use vmm_vhost::message::{ VhostUserConfigFlags, VhostUserProtocolFeatures, VhostUserVirtioFeatures, @@ -14,6 +15,7 @@ use vmm_vhost::message::{ use vmm_vhost::{VhostBackend, VhostUserMaster, VhostUserMemoryRegionInfo, VringConfigData}; use crate::virtio::vhost::user::vmm::handler::sys::SocketMaster; +use crate::virtio::vhost::user::vmm::worker::Worker; use crate::virtio::vhost::user::vmm::{Error, Result}; use crate::virtio::{Interrupt, Queue}; @@ -212,12 +214,13 @@ impl VhostUserHandler { /// Activates vrings. pub fn activate( &mut self, - mem: &GuestMemory, - interrupt: &Interrupt, - queues: &[Queue], - queue_evts: &[Event], - ) -> Result<()> { - self.set_mem_table(mem)?; + mem: GuestMemory, + interrupt: Interrupt, + queues: Vec, + queue_evts: Vec, + label: &str, + ) -> Result<(thread::JoinHandle<()>, Event)> { + self.set_mem_table(&mem)?; let msix_config_opt = interrupt .get_msix_config() @@ -230,10 +233,29 @@ impl VhostUserHandler { let irqfd = msix_config .get_irqfd(queue.vector as usize) .unwrap_or_else(|| interrupt.get_interrupt_evt()); - self.activate_vring(mem, queue_index, queue, queue_evt, irqfd)?; + self.activate_vring(&mem, queue_index, queue, queue_evt, irqfd)?; } - Ok(()) + drop(msix_config); + + let label = format!("vhost_user_virtio_{}", label); + let kill_evt = Event::new().map_err(Error::CreateEvent)?; + let self_kill_evt = kill_evt.try_clone().map_err(Error::CreateEvent)?; + thread::Builder::new() + .name(label.clone()) + .spawn(move || { + let mut worker = Worker { + queues, + mem, + kill_evt, + }; + + if let Err(e) = worker.run(interrupt) { + error!("failed to start {} worker: {}", label, e); + } + }) + .map(|worker_result| (worker_result, self_kill_evt)) + .map_err(Error::SpawnWorker) } /// Deactivates all vrings. diff --git a/devices/src/virtio/vhost/user/vmm/mac80211_hwsim.rs b/devices/src/virtio/vhost/user/vmm/mac80211_hwsim.rs index ba028eacdb..970e3b93bb 100644 --- a/devices/src/virtio/vhost/user/vmm/mac80211_hwsim.rs +++ b/devices/src/virtio/vhost/user/vmm/mac80211_hwsim.rs @@ -8,33 +8,20 @@ use std::path::Path; use std::thread; use base::{error, Event, RawDescriptor}; -use remain::sorted; -use thiserror::Error as ThisError; use vm_memory::GuestMemory; use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; -use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, worker::Worker, Error}; +use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, Error}; use crate::virtio::{DeviceType, Interrupt, Queue, VirtioDevice}; use std::result::Result; -#[sorted] -#[derive(ThisError, Debug)] -enum Mac80211HwsimError { - #[error("failed to activate queues: {0}")] - ActivateQueue(Error), - #[error("failed to kill event pair: {0}")] - CreateKillEventPair(base::Error), - #[error("failed to spawn mac80211_hwsim worker: {0}")] - SpawnWorker(std::io::Error), -} - const QUEUE_SIZE: u16 = 256; const QUEUE_COUNT: usize = 2; pub struct Mac80211Hwsim { kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, queue_sizes: Vec, } @@ -63,44 +50,6 @@ impl Mac80211Hwsim { queue_sizes, }) } - - fn activate_internal( - &mut self, - mem: GuestMemory, - interrupt: Interrupt, - queues: Vec, - queue_evts: Vec, - ) -> Result<(), Mac80211HwsimError> { - self.handler - .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) - .map_err(Mac80211HwsimError::ActivateQueue)?; - - let (self_kill_evt, kill_evt) = Event::new() - .and_then(|e| Ok((e.try_clone()?, e))) - .map_err(Mac80211HwsimError::CreateKillEventPair)?; - - self.kill_evt = Some(self_kill_evt); - - let join_handle = thread::Builder::new() - .name("vhost_user_mac80211_hwsim".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }) - .map_err(Mac80211HwsimError::SpawnWorker)?; - - self.worker_thread = Some(join_handle); - - Ok(()) - } } impl Drop for Mac80211Hwsim { @@ -147,8 +96,20 @@ impl VirtioDevice for Mac80211Hwsim { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self.activate_internal(mem, interrupt, queues, queue_evts) { - error!("Failed to activate mac80211_hwsim: {}", e); + match self.handler.borrow_mut().activate( + mem, + interrupt, + queues, + queue_evts, + "mac80211_hwsim", + ) { + Ok((join_handle, kill_evt)) => { + self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); + } } } diff --git a/devices/src/virtio/vhost/user/vmm/mod.rs b/devices/src/virtio/vhost/user/vmm/mod.rs index a281c969cd..6435e78146 100644 --- a/devices/src/virtio/vhost/user/vmm/mod.rs +++ b/devices/src/virtio/vhost/user/vmm/mod.rs @@ -131,6 +131,9 @@ pub enum Error { /// Failed to create Master from a UDS path. #[error("failed to connect to device socket while creating instance: {0}")] SocketConnectOnMasterCreate(VhostError), + /// Failed to spawn worker thread. + #[error("failed to spawn worker: {0}")] + SpawnWorker(std::io::Error), /// The tag for the Fs device was too long to fit in the config space. #[error("tag is too long: {len} > {max}")] TagTooLong { len: usize, max: usize }, diff --git a/devices/src/virtio/vhost/user/vmm/net.rs b/devices/src/virtio/vhost/user/vmm/net.rs index 6854e0b307..1da95a6931 100644 --- a/devices/src/virtio/vhost/user/vmm/net.rs +++ b/devices/src/virtio/vhost/user/vmm/net.rs @@ -12,7 +12,7 @@ use virtio_sys::virtio_net; use vm_memory::GuestMemory; use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; -use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, worker::Worker, Error}; +use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, Error}; use crate::virtio::{DeviceType, Interrupt, Queue, VirtioDevice, VirtioNetConfig}; type Result = std::result::Result; @@ -21,7 +21,7 @@ const QUEUE_SIZE: u16 = 1024; pub struct Net { kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, queue_sizes: Vec, } @@ -101,44 +101,17 @@ impl VirtioDevice for Net { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self + match self .handler .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) + .activate(mem, interrupt, queues, queue_evts, "net") { - error!("failed to activate queues: {}", e); - return; - } - - let (self_kill_evt, kill_evt) = match Event::new().and_then(|e| Ok((e.try_clone()?, e))) { - Ok(v) => v, - Err(e) => { - error!("failed creating kill Event pair: {}", e); - return; - } - }; - self.kill_evt = Some(self_kill_evt); - - let worker_result = thread::Builder::new() - .name("vhost_user_virtio_net".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }); - - match worker_result { - Err(e) => { - error!("failed to spawn virtio_net worker: {}", e); - } - Ok(join_handle) => { + Ok((join_handle, kill_evt)) => { self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); } } } diff --git a/devices/src/virtio/vhost/user/vmm/snd.rs b/devices/src/virtio/vhost/user/vmm/snd.rs index 24a867e60a..230c6ef719 100644 --- a/devices/src/virtio/vhost/user/vmm/snd.rs +++ b/devices/src/virtio/vhost/user/vmm/snd.rs @@ -12,13 +12,13 @@ use vm_memory::GuestMemory; use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use crate::virtio::snd::layout::virtio_snd_config; -use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, worker::Worker, Error, Result}; +use crate::virtio::vhost::user::vmm::{handler::VhostUserHandler, Error, Result}; use crate::virtio::{DeviceType, Interrupt, Queue, VirtioDevice}; // A vhost-user snd device. pub struct Snd { kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, queue_sizes: Vec, } @@ -97,46 +97,17 @@ impl VirtioDevice for Snd { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self + match self .handler .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) + .activate(mem, interrupt, queues, queue_evts, "snd") { - error!("failed to activate queues: {}", e); - return; - } - - let (self_kill_evt, kill_evt) = - match Event::new().and_then(|evt| Ok((evt.try_clone()?, evt))) { - Ok(v) => v, - Err(e) => { - error!("failed creating kill Event pair: {}", e); - return; - } - }; - self.kill_evt = Some(self_kill_evt); - - let worker_result = thread::Builder::new() - .name("vhost_user_virtio_snd".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }); - - match worker_result { - Err(e) => { - error!("failed to spawn vhost-user virtio_snd worker: {}", e); - } - Ok(join_handle) => { + Ok((join_handle, kill_evt)) => { self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); } } } diff --git a/devices/src/virtio/vhost/user/vmm/vsock.rs b/devices/src/virtio/vhost/user/vmm/vsock.rs index 8c63c85def..6d2e4adc7d 100644 --- a/devices/src/virtio/vhost/user/vmm/vsock.rs +++ b/devices/src/virtio/vhost/user/vmm/vsock.rs @@ -11,7 +11,7 @@ use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use crate::virtio::{ vhost::{ - user::vmm::{handler::VhostUserHandler, worker::Worker, Error, Result}, + user::vmm::{handler::VhostUserHandler, Error, Result}, vsock, }, DeviceType, Interrupt, Queue, VirtioDevice, @@ -19,7 +19,7 @@ use crate::virtio::{ pub struct Vsock { kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, queue_sizes: Vec, } @@ -100,44 +100,17 @@ impl VirtioDevice for Vsock { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self + match self .handler .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) + .activate(mem, interrupt, queues, queue_evts, "vsock") { - error!("failed to activate queues: {}", e); - return; - } - - let (self_kill_evt, kill_evt) = match Event::new().and_then(|e| Ok((e.try_clone()?, e))) { - Ok(v) => v, - Err(e) => { - error!("failed creating kill Event pair: {}", e); - return; - } - }; - self.kill_evt = Some(self_kill_evt); - - let worker_result = thread::Builder::new() - .name("vhost_user_vsock".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }); - - match worker_result { - Err(e) => { - error!("failed to spawn virtio_vsock worker: {}", e); - } - Ok(join_handle) => { + Ok((join_handle, kill_evt)) => { self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); } } } diff --git a/devices/src/virtio/vhost/user/vmm/wl.rs b/devices/src/virtio/vhost/user/vmm/wl.rs index 36ce2399c3..c9112b9ed4 100644 --- a/devices/src/virtio/vhost/user/vmm/wl.rs +++ b/devices/src/virtio/vhost/user/vmm/wl.rs @@ -10,7 +10,7 @@ use base::{error, Event, RawDescriptor}; use vm_memory::GuestMemory; use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; -use crate::virtio::vhost::user::vmm::{worker::Worker, Result, VhostUserHandler}; +use crate::virtio::vhost::user::vmm::{Result, VhostUserHandler}; use crate::virtio::wl::{ QUEUE_SIZE, QUEUE_SIZES, VIRTIO_WL_F_SEND_FENCES, VIRTIO_WL_F_TRANS_FLAGS, }; @@ -18,7 +18,7 @@ use crate::virtio::{DeviceType, Interrupt, Queue, VirtioDevice}; pub struct Wl { kill_evt: Option, - worker_thread: Option>, + worker_thread: Option>, handler: RefCell, queue_sizes: Vec, } @@ -85,45 +85,17 @@ impl VirtioDevice for Wl { queues: Vec, queue_evts: Vec, ) { - if let Err(e) = self + match self .handler .borrow_mut() - .activate(&mem, &interrupt, &queues, &queue_evts) + .activate(mem, interrupt, queues, queue_evts, "wl") { - error!("failed to activate queues: {}", e); - return; - } - - let (self_kill_evt, kill_evt) = match Event::new().and_then(|e| Ok((e.try_clone()?, e))) { - Ok(v) => v, - Err(e) => { - error!("failed creating kill Event pair: {}", e); - return; - } - }; - self.kill_evt = Some(self_kill_evt); - - let worker_result = thread::Builder::new() - .name("vhost_user_wl".to_string()) - .spawn(move || { - let mut worker = Worker { - queues, - mem, - kill_evt, - }; - - if let Err(e) = worker.run(interrupt) { - error!("failed to start a worker: {}", e); - } - worker - }); - - match worker_result { - Err(e) => { - error!("failed to spawn vhost_user_wl worker: {}", e); - } - Ok(join_handle) => { + Ok((join_handle, kill_evt)) => { self.worker_thread = Some(join_handle); + self.kill_evt = Some(kill_evt); + } + Err(e) => { + error!("failed to activate queues: {}", e); } } }