summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--devices/src/usb/xhci/ring_buffer_controller.rs2
-rw-r--r--devices/src/usb/xhci/xhci.rs3
-rw-r--r--devices/src/utils/error.rs2
-rw-r--r--devices/src/utils/event_loop.rs100
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, &regs)));
         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) => {