Make pause_timeout return EINTR

This commit is contained in:
Ruihan Li
2024-11-05 17:17:40 +08:00
committed by Tate, Hongliang Tian
parent b563fb639f
commit 6421fd0b36

View File

@ -86,10 +86,9 @@ pub trait Pause: WaitTimeout {
/// ///
/// # Errors /// # Errors
/// ///
/// This method will return an error with [`ETIME`] if the timeout is reached. /// This method will return an error with
/// /// - [`EINTR`] if a signal is received;
/// Unlike other methods in the trait, this method will _not_ return an error with [`EINTR`] if /// - [`ETIME`] if the timeout is reached.
/// a signal is received (FIXME).
/// ///
/// [`ETIME`]: crate::error::Errno::ETIME /// [`ETIME`]: crate::error::Errno::ETIME
/// [`EINTR`]: crate::error::Errno::EINTR /// [`EINTR`]: crate::error::Errno::EINTR
@ -108,10 +107,10 @@ impl Pause for Waiter {
// No fast paths for `Waiter`. If the caller wants a fast path, it should do so _before_ // No fast paths for `Waiter`. If the caller wants a fast path, it should do so _before_
// the waiter is created. // the waiter is created.
let current_thread = self.task().data().downcast_ref::<Arc<Thread>>(); let Some(posix_thread) = self
.task()
let Some(posix_thread) = current_thread .data()
.as_ref() .downcast_ref::<Arc<Thread>>()
.and_then(|thread| thread.as_posix_thread()) .and_then(|thread| thread.as_posix_thread())
else { else {
return self.wait_until_or_timeout_cancelled(cond, || Ok(()), timeout); return self.wait_until_or_timeout_cancelled(cond, || Ok(()), timeout);
@ -142,12 +141,13 @@ impl Pause for Waiter {
}) })
}); });
let current_thread = self.task().data().downcast_ref::<Arc<Thread>>(); let posix_thread_opt = self
.task()
.data()
.downcast_ref::<Arc<Thread>>()
.and_then(|thread| thread.as_posix_thread());
if let Some(posix_thread) = current_thread if let Some(posix_thread) = posix_thread_opt {
.as_ref()
.and_then(|thread| thread.as_posix_thread())
{
posix_thread.set_signalled_waker(self.waker()); posix_thread.set_signalled_waker(self.waker());
self.wait(); self.wait();
posix_thread.clear_signalled_waker(); posix_thread.clear_signalled_waker();
@ -157,12 +157,22 @@ impl Pause for Waiter {
if let Some(timer) = timer { if let Some(timer) = timer {
if timer.remain().is_zero() { if timer.remain().is_zero() {
return_errno_with_message!(Errno::ETIME, "the timeout is reached"); return_errno_with_message!(Errno::ETIME, "the time limit is reached");
} }
// If the timeout is not expired, cancel the timer manually. // If the timeout is not expired, cancel the timer manually.
timer.cancel(); timer.cancel();
} }
if posix_thread_opt
.as_ref()
.is_some_and(|posix_thread| posix_thread.has_pending())
{
return_errno_with_message!(
Errno::EINTR,
"the current thread is interrupted by a signal"
);
}
Ok(()) Ok(())
} }
} }