fix(time): 处理信号中断导致的定时器唤醒 (#1204)

在sleep和schedule_timeout模块中增加信号中断检查,当定时器被信号中断时取消定时器并返回ERESTARTSYS错误。

Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
LoGin 2025-06-12 14:22:53 +08:00 committed by GitHub
parent 523d2a97d9
commit 774f9eb7ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 0 deletions

View File

@ -4,6 +4,7 @@ use alloc::{boxed::Box, sync::Arc};
use system_error::SystemError;
use crate::{
arch::ipc::signal::Signal,
arch::{CurrentIrqArch, CurrentTimeArch},
exception::InterruptArch,
process::ProcessManager,
@ -56,9 +57,25 @@ pub fn nanosleep(sleep_time: PosixTimeSpec) -> Result<PosixTimeSpec, SystemError
schedule(SchedMode::SM_NONE);
let end_time = getnstimeofday();
// 检查是否被信号中断,如果是则取消定时器
let current_pcb = ProcessManager::current_pcb();
let was_interrupted = current_pcb.has_pending_signal_fast()
|| Signal::signal_pending_state(true, false, &current_pcb);
// 如果定时器没有超时(被信号中断或其他原因唤醒),则取消定时器
if !timer.timeout() {
timer.cancel();
}
// 返回正确的剩余时间
let real_sleep_time = end_time - start_time;
let rm_time: PosixTimeSpec = (sleep_time - real_sleep_time.into()).into();
// 如果被信号中断,返回 ERESTARTSYS 错误
if was_interrupted {
return Err(SystemError::ERESTARTSYS);
}
return Ok(rm_time);
}

View File

@ -325,6 +325,12 @@ pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
drop(irq_guard);
schedule(SchedMode::SM_NONE);
// 如果定时器没有超时(被信号中断或其他原因唤醒),则取消定时器
if !timer.timeout() {
timer.cancel();
}
let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
if time_remaining >= 0 {
// 被提前唤醒,返回剩余时间