File tree Expand file tree Collapse file tree 1 file changed +18
-0
lines changed
Expand file tree Collapse file tree 1 file changed +18
-0
lines changed Original file line number Diff line number Diff line change @@ -78,6 +78,24 @@ impl Monitor {
7878 set. remove ( Signal :: SIGURG ) ;
7979 set. thread_set_mask ( )
8080 . expect ( "Failed to remove SIGURG signal mask!" ) ;
81+ //不抢占处于Syscall状态的协程。
82+ //MonitorListener的设计理念是不对Syscall状态的协程发送信号。
83+ //但由于NOTIFY_NODE移除和monitor线程遍历之间存在竞态条件,
84+ //SIGURG可能在协程刚进入Syscall状态时到达。
85+ //如果此时抢占,协程会被放入syscall_map但无人唤醒(因为没有io_uring/epoll注册),
86+ //导致死锁。
87+ // Skip preemption for coroutines in Syscall state.
88+ // MonitorListener's design is to NOT send signals to Syscall-state
89+ // coroutines. However, a race between NOTIFY_NODE removal and the
90+ // monitor's queue iteration can cause SIGURG to arrive just after
91+ // the coroutine entered Syscall state. If preempted here, the
92+ // coroutine lands in the syscall map with no io_uring/epoll/timer
93+ // registration to wake it, causing a deadlock.
94+ if let Some ( co) = SchedulableCoroutine :: current ( ) {
95+ if matches ! ( co. state( ) , CoroutineState :: Syscall ( ( ) , _, _) ) {
96+ return ;
97+ }
98+ }
8199 if let Some ( suspender) = SchedulableSuspender :: current ( ) {
82100 suspender. suspend ( ) ;
83101 }
You can’t perform that action at this time.
0 commit comments