diff options
-rw-r--r-- | devices/src/usb/xhci/ring_buffer_controller.rs | 2 | ||||
-rw-r--r-- | devices/src/usb/xhci/xhci.rs | 3 | ||||
-rw-r--r-- | devices/src/utils/error.rs | 2 | ||||
-rw-r--r-- | devices/src/utils/event_loop.rs | 100 |
4 files changed, 57 insertions, 50 deletions
diff --git a/devices/src/usb/xhci/ring_buffer_controller.rs b/devices/src/usb/xhci/ring_buffer_controller.rs index 5084fab..201441a 100644 --- a/devices/src/usb/xhci/ring_buffer_controller.rs +++ b/devices/src/usb/xhci/ring_buffer_controller.rs @@ -320,7 +320,7 @@ mod tests { fn test_ring_buffer_controller() { let (tx, rx) = channel(); let mem = setup_mem(); - let (l, j) = EventLoop::start(None).unwrap(); + let (l, j) = EventLoop::start("test".to_string(), None).unwrap(); let l = Arc::new(l); let controller = RingBufferController::new_with_handler( "".to_string(), diff --git a/devices/src/usb/xhci/xhci.rs b/devices/src/usb/xhci/xhci.rs index df57e68..55dd50e 100644 --- a/devices/src/usb/xhci/xhci.rs +++ b/devices/src/usb/xhci/xhci.rs @@ -83,7 +83,8 @@ impl Xhci { regs: XhciRegs, ) -> Result<Arc<Self>> { let (event_loop, _join_handle) = - EventLoop::start(Some(fail_handle.clone())).map_err(Error::StartEventLoop)?; + 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, ®s))); let event_loop = Arc::new(event_loop); let intr_resample_handler = diff --git a/devices/src/utils/error.rs b/devices/src/utils/error.rs index 3d5fcc7..024d3f7 100644 --- a/devices/src/utils/error.rs +++ b/devices/src/utils/error.rs @@ -14,6 +14,7 @@ pub enum Error { CreatePollContext(SysError), PollContextAddFd(SysError), PollContextDeleteFd(SysError), + StartThread(std::io::Error), } impl Display for Error { @@ -28,6 +29,7 @@ impl Display for Error { CreatePollContext(e) => write!(f, "failed to create poll context: {}", e), PollContextAddFd(e) => write!(f, "failed to add fd to poll context: {}", e), PollContextDeleteFd(e) => write!(f, "failed to delete fd from poll context: {}", e), + StartThread(e) => write!(f, "failed to start thread: {}", e), } } } diff --git a/devices/src/utils/event_loop.rs b/devices/src/utils/event_loop.rs index b420dcf..405c543 100644 --- a/devices/src/utils/event_loop.rs +++ b/devices/src/utils/event_loop.rs @@ -71,6 +71,7 @@ pub trait EventHandler: Send + Sync { impl EventLoop { /// Start an event loop. An optional fail handle could be passed to the event loop. pub fn start( + name: String, fail_handle: Option<Arc<dyn FailHandle>>, ) -> Result<(EventLoop, thread::JoinHandle<()>)> { let (self_stop_evt, stop_evt) = EventFd::new() @@ -91,59 +92,62 @@ impl EventLoop { stop_evt: self_stop_evt, }; - let handle = thread::spawn(move || { - let event_loop = EpollEvents::new(); - loop { - if fail_handle.failed() { - error!("xhci controller already failed, stopping event ring"); - return; - } - let events = match poll_ctx.wait(&event_loop) { - Ok(events) => events, - Err(e) => { - error!("cannot poll {:?}", e); - fail_handle.fail(); + let handle = thread::Builder::new() + .name(name) + .spawn(move || { + let event_loop = EpollEvents::new(); + loop { + if fail_handle.failed() { + error!("xhci controller already failed, stopping event ring"); return; } - }; - for event in &events { - if event.token().as_raw_fd() == stop_evt.as_raw_fd() { - return; - } else { - let fd = event.token().as_raw_fd(); - let mut locked = fd_callbacks.lock(); - let weak_handler = match locked.get(&fd) { - Some(cb) => cb.clone(), - None => { - warn!("callback for fd {} already removed", fd); - continue; - } - }; - match weak_handler.upgrade() { - Some(handler) => { - // Drop lock before triggering the event. - drop(locked); - match handler.on_event() { - Ok(()) => {} - Err(_) => { - error!("event loop stopping due to handle event error"); - fail_handle.fail(); - return; + let events = match poll_ctx.wait(&event_loop) { + Ok(events) => events, + Err(e) => { + error!("cannot poll {:?}", e); + fail_handle.fail(); + return; + } + }; + for event in &events { + if event.token().as_raw_fd() == stop_evt.as_raw_fd() { + return; + } else { + let fd = event.token().as_raw_fd(); + let mut locked = fd_callbacks.lock(); + let weak_handler = match locked.get(&fd) { + Some(cb) => cb.clone(), + None => { + warn!("callback for fd {} already removed", fd); + continue; + } + }; + match weak_handler.upgrade() { + Some(handler) => { + // Drop lock before triggering the event. + drop(locked); + match handler.on_event() { + Ok(()) => {} + Err(_) => { + error!("event loop stopping due to handle event error"); + fail_handle.fail(); + return; + } + }; + } + // If the handler is already gone, we remove the fd. + None => { + let _ = poll_ctx.delete(&Fd(fd)); + if locked.remove(&fd).is_none() { + error!("fail to remove handler for file descriptor {}", fd); } - }; - } - // If the handler is already gone, we remove the fd. - None => { - let _ = poll_ctx.delete(&Fd(fd)); - if locked.remove(&fd).is_none() { - error!("fail to remove handler for file descriptor {}", fd); } - } - }; + }; + } } } - } - }); + }) + .map_err(Error::StartThread)?; Ok((event_loop, handle)) } @@ -219,7 +223,7 @@ mod tests { #[test] fn event_loop_test() { - let (l, j) = EventLoop::start(None).unwrap(); + let (l, j) = EventLoop::start("test".to_string(), None).unwrap(); let (self_evt, evt) = match EventFd::new().and_then(|e| Ok((e.try_clone()?, e))) { Ok(v) => v, Err(e) => { |