1- use core:: {
2- fmt:: Debug ,
3- sync:: atomic:: { AtomicBool , Ordering } ,
4- } ;
5-
61use crate :: {
72 filesystem:: vfs:: {
83 file:: { File , FileFlags } ,
@@ -11,14 +6,18 @@ use crate::{
116 libs:: {
127 rbtree:: RBTree ,
138 spinlock:: { SpinLock , SpinLockGuard } ,
14- wait_queue:: { WaitQueue , Waiter } ,
9+ wait_queue:: { WaitQueue , Waiter , Waker } ,
1510 } ,
1611 process:: ProcessManager ,
1712 time:: {
18- timer:: { next_n_us_timer_jiffies, Timer , WakeUpHelper } ,
13+ timer:: { next_n_us_timer_jiffies, Timer , TimerFunction } ,
1914 PosixTimeSpec ,
2015 } ,
2116} ;
17+ use core:: {
18+ fmt:: Debug ,
19+ sync:: atomic:: { AtomicBool , Ordering } ,
20+ } ;
2221
2322use alloc:: {
2423 collections:: LinkedList ,
@@ -29,6 +28,22 @@ use system_error::SystemError;
2928
3029use super :: { fs:: EPollInode , EPollCtlOption , EPollEvent , EPollEventType , EPollItem } ;
3130
31+ use alloc:: boxed:: Box ;
32+
33+ #[ derive( Debug ) ]
34+ struct EpollTimeoutWaker {
35+ waker : Arc < Waker > ,
36+ }
37+
38+ impl TimerFunction for EpollTimeoutWaker {
39+ fn run ( & mut self ) -> Result < ( ) , SystemError > {
40+ // Wake the waiter (and thus the process) in a way Waiter::wait can observe.
41+ // NOTE: Timer-based wakeup must go through Waker::wake(); waking PCB alone is insufficient.
42+ self . waker . wake ( ) ;
43+ Ok ( ( ) )
44+ }
45+ }
46+
3247/// 内核的Epoll对象结构体,当用户创建一个Epoll时,内核就会创建一个该类型对象
3348/// 它对应一个epfd
3449#[ derive( Debug ) ]
@@ -329,6 +344,7 @@ impl EventPoll {
329344 }
330345 if let Some ( epoll_data) = epolldata {
331346 let epoll = epoll_data. epoll . clone ( ) ;
347+
332348 let epoll_guard = epoll. 0 . lock_irqsave ( ) ;
333349
334350 let mut timeout = false ;
@@ -391,19 +407,22 @@ impl EventPoll {
391407 }
392408
393409 // 还未等待到事件发生,则睡眠
394- // 注册定时器
410+ // 构造一次等待(先构造 Waiter/Waker,超时需要通过 Waker::wake 触发)
411+ let ( waiter, waker) = Waiter :: new_pair ( ) ;
412+
413+ // 注册定时器:用 waker.wake() 来触发 waiter 退出等待(而不是仅唤醒 PCB)
395414 let mut timer = None ;
396415 if let Some ( timespec) = timespec {
397- let handle = WakeUpHelper :: new ( current_pcb. clone ( ) ) ;
398- let jiffies = next_n_us_timer_jiffies (
399- ( timespec. tv_sec * 1000000 + timespec. tv_nsec / 1000 ) as u64 ,
416+ let us = ( timespec. tv_sec * 1_000_000 + timespec. tv_nsec / 1_000 ) as u64 ;
417+ let jiffies = next_n_us_timer_jiffies ( us) ;
418+ let inner: Arc < Timer > = Timer :: new (
419+ Box :: new ( EpollTimeoutWaker {
420+ waker : waker. clone ( ) ,
421+ } ) ,
422+ jiffies,
400423 ) ;
401- let inner: Arc < Timer > = Timer :: new ( handle, jiffies) ;
402- inner. activate ( ) ;
403424 timer = Some ( inner) ;
404425 }
405- // 构造一次等待
406- let ( waiter, waker) = Waiter :: new_pair ( ) ;
407426 {
408427 let guard = epoll. 0 . lock_irqsave ( ) ;
409428 // 注册前再次检查,避免错过事件
0 commit comments