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:
@@ -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<×pec>, clock_id: clockid_t) -> Result<(), ()> {
|
||||
+ pub fn wait(&self, timeout_opt: Option<×pec>, 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 {
|
||||
|
||||
Reference in New Issue
Block a user