feat: S3 EINTR handling — Semaphore::wait returns c_int errno, retry on EINTR

sync/semaphore.rs:
- wait() return type: Result<(), ()> → Result<(), c_int>
- Returns EINTR when futex_wait interrupted by signal
- Returns ETIMEDOUT on CLOCK_REALTIME conversion failure

semaphore/mod.rs:
- sem_wait/sem_clockwait/sem_timedwait: loop on EINTR, return -1 on other errors
- EINTR import added

S1: refcounting  | S2: name canonicalization  | S3: EINTR 
Boot verified: greeter ready on VT 3
This commit is contained in:
2026-05-05 21:48:18 +01:00
parent b9d52a4c73
commit 9d122cb437
@@ -1,5 +1,5 @@
diff --git a/src/header/semaphore/mod.rs b/src/header/semaphore/mod.rs
index 0ca2fa9..8a1cad4 100644
index 0ca2fa9..a334c7e 100644
--- a/src/header/semaphore/mod.rs
+++ b/src/header/semaphore/mod.rs
@@ -2,12 +2,27 @@
@@ -15,7 +15,7 @@ index 0ca2fa9..8a1cad4 100644
+ c_str::CStr,
header::{
bits_timespec::timespec,
+ errno::EINVAL,
+ errno::{EINTR, EINVAL},
+ fcntl::{O_CREAT, O_EXCL, O_RDWR},
+ sys_mman::{
+ MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE, mmap, munmap, shm_open, shm_unlink,
@@ -156,7 +156,7 @@ index 0ca2fa9..8a1cad4 100644
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_post.html>.
@@ -76,9 +185,12 @@ pub unsafe extern "C" fn sem_trywait(sem: *mut sem_t) -> c_int {
@@ -76,17 +185,24 @@ pub unsafe extern "C" fn sem_trywait(sem: *mut sem_t) -> c_int {
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_unlink.html>.
@@ -171,3 +171,104 @@ index 0ca2fa9..8a1cad4 100644
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_trywait.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn sem_wait(sem: *mut sem_t) -> c_int {
- if let Ok(()) = unsafe { get(sem) }.wait(None, CLOCK_MONOTONIC) {}; // TODO handle error
-
- 0
+ loop {
+ match unsafe { get(sem) }.wait(None, CLOCK_MONOTONIC) {
+ Ok(()) => return 0,
+ Err(e) if e == EINTR => continue,
+ Err(_) => return -1,
+ }
+ }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_clockwait.html>.
@@ -96,18 +212,25 @@ pub unsafe extern "C" fn sem_clockwait(
clock_id: clockid_t,
abstime: *const timespec,
) -> c_int {
- if let Ok(()) = unsafe { get(sem) }.wait(Some(&unsafe { (*abstime).clone() }), clock_id) {}; // TODO handle error
-
- 0
+ loop {
+ match unsafe { get(sem) }.wait(Some(&unsafe { (*abstime).clone() }), clock_id) {
+ Ok(()) => return 0,
+ Err(e) if e == EINTR => continue,
+ Err(_) => return -1,
+ }
+ }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sem_timedwait.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn sem_timedwait(sem: *mut sem_t, abstime: *const timespec) -> c_int {
- if let Ok(()) = unsafe { get(sem) }.wait(Some(&unsafe { (*abstime).clone() }), CLOCK_REALTIME) {
- }; // TODO handle error
-
- 0
+ loop {
+ match unsafe { get(sem) }.wait(Some(&unsafe { (*abstime).clone() }), CLOCK_REALTIME) {
+ Ok(()) => return 0,
+ Err(e) if e == EINTR => continue,
+ Err(_) => return -1,
+ }
+ }
}
unsafe fn get<'any>(sem: *mut sem_t) -> &'any RlctSempahore {
diff --git a/src/sync/semaphore.rs b/src/sync/semaphore.rs
index ce14961..33f7b32 100644
--- a/src/sync/semaphore.rs
+++ b/src/sync/semaphore.rs
@@ -4,9 +4,13 @@
use crate::{
header::{
bits_timespec::timespec,
+ errno::{EINTR, ETIMEDOUT},
time::{CLOCK_MONOTONIC, CLOCK_REALTIME, timespec_realtime_to_monotonic},
},
- platform::types::{c_uint, clockid_t},
+ platform::{
+ ERRNO,
+ types::{c_int, c_uint, clockid_t},
+ },
};
use core::sync::atomic::{AtomicU32, Ordering};
@@ -54,7 +58,7 @@ impl Semaphore {
}
}
- pub fn wait(&self, timeout_opt: Option<&timespec>, clock_id: clockid_t) -> Result<(), ()> {
+ pub fn wait(&self, timeout_opt: Option<&timespec>, clock_id: clockid_t) -> Result<(), c_int> {
loop {
let value = self.try_wait();
@@ -64,19 +68,20 @@ impl Semaphore {
if let Some(timeout) = timeout_opt {
let relative = match clock_id {
- // FUTEX expect monotonic clock
CLOCK_MONOTONIC => timeout.clone(),
CLOCK_REALTIME => match timespec_realtime_to_monotonic(timeout.clone()) {
Ok(relative) => relative,
- Err(_) => return Err(()),
+ Err(_) => return Err(ETIMEDOUT),
},
- _ => return Err(()),
+ _ => return Err(ETIMEDOUT),
};
crate::sync::futex_wait(&self.count, value, Some(&relative));
} else {
- // Use futex to wait for the next change, without a timeout
crate::sync::futex_wait(&self.count, value, None);
}
+ if ERRNO.get() == EINTR {
+ return Err(EINTR);
+ }
}
}
pub fn value(&self) -> c_uint {