diff --git a/src/platform/redox/epoll.rs b/src/platform/redox/epoll.rs index 8c0b2d17b7..b9dd7597ea 100644 --- a/src/platform/redox/epoll.rs +++ b/src/platform/redox/epoll.rs @@ -57,16 +57,43 @@ impl PalEpoll for Sys { ) -> Result<(), Errno> { match op { EPOLL_CTL_ADD | EPOLL_CTL_MOD => { - Sys::write( - epfd, - &Event { - id: fd as usize, - flags: unsafe { epoll_to_event_flags((*event).events) }, - // NOTE: Danger when using something smaller than 64-bit - // systems. If this is needed, use a box or something - data: unsafe { (*event).data.u64 as usize }, - }, - )?; + let ev = Event { + id: fd as usize, + flags: unsafe { epoll_to_event_flags((*event).events) }, + // NOTE: Danger when using something smaller than 64-bit + // systems. If this is needed, use a box or something + data: unsafe { (*event).data.u64 as usize }, + }; + // Registering an fd with /scheme/event can transiently fail + // with EINVAL/EBADF while the scheme backing `fd` is still + // starting up or the fd-table is churning during early boot + // (e.g. a tokio/mio reactor built by a daemon that races ahead + // of ipcd's uds_stream scheme). Without recovery, tokio's + // Runtime::build aborts the whole runtime, killing every + // zbus-based daemon and any tokio program (including the login + // shell). Retry with a short backoff so the registration + // succeeds once the scheme settles; a genuinely permanent + // failure still surfaces after the bounded window. This mirrors + // the park-path recovery in the P0-epoll-redox-recovery tokio + // patch, but at the registration site the patch cannot reach. + let mut attempts: u32 = 0; + loop { + match Sys::write(epfd, &ev) { + Ok(_) => break, + Err(Errno(err)) + if (err == EINVAL || err == EBADF) && attempts < 400 => + { + attempts += 1; + let req = syscall::data::TimeSpec { + tv_sec: 0, + tv_nsec: 5_000_000, // 5ms; up to ~2s total + }; + let mut rem = syscall::data::TimeSpec::default(); + let _ = syscall::nanosleep(&req, &mut rem); + } + Err(err) => return Err(err), + } + } } EPOLL_CTL_DEL => { Sys::write(