@@ -4091,8 +4091,8 @@ def test_broken_pipe_cleanup(self):
40914091
40924092
40934093class FastWaitTestCase (BaseTestCase ):
4094- """Tests for efficient (pidfd_open / kqueue) process waiting in
4095- subprocess.Popen.wait().
4094+ """Tests for efficient (pidfd_open() + poll() / kqueue()) process
4095+ waiting in subprocess.Popen.wait().
40964096 """
40974097 CAN_USE_PIDFD_OPEN = hasattr (os , "pidfd_open" )
40984098 CAN_USE_KQUEUE = subprocess ._CAN_USE_KQUEUE
@@ -4164,6 +4164,36 @@ def test_pidfd_open_race(self):
41644164 def test_kqueue_race (self ):
41654165 self .assert_wait_race_condition ("select.kqueue" , select .kqueue )
41664166
4167+ def assert_notification_without_immediate_reap (self , patch_target ):
4168+ # Verify fallback to busy polling when poll() / kqueue()
4169+ # succeeds, but waitpid(pid, WNOHANG) returns (0, 0).
4170+ def waitpid_wrapper (pid , flags ):
4171+ nonlocal ncalls
4172+ ncalls += 1
4173+ if ncalls == 1 :
4174+ return (0 , 0 )
4175+ return real_waitpid (pid , flags )
4176+
4177+ ncalls = 0
4178+ real_waitpid = os .waitpid
4179+ with mock .patch .object (subprocess .Popen , patch_target , return_value = True ) as m1 :
4180+ with mock .patch ("os.waitpid" , side_effect = waitpid_wrapper ) as m2 :
4181+ p = subprocess .Popen ([sys .executable ,
4182+ "-c" , "import time; time.sleep(0.3)" ])
4183+ with self .assertRaises (subprocess .TimeoutExpired ):
4184+ p .wait (timeout = 0.0001 )
4185+ self .assertEqual (p .wait (timeout = support .SHORT_TIMEOUT ), 0 )
4186+ assert m1 .called
4187+ assert m2 .called
4188+
4189+ @unittest .skipIf (not CAN_USE_PIDFD_OPEN , reason = "LINUX only" )
4190+ def test_poll_notification_without_immediate_reap (self ):
4191+ self .assert_notification_without_immediate_reap ("_wait_pidfd" )
4192+
4193+ @unittest .skipIf (not CAN_USE_KQUEUE , reason = "macOS / BSD only" )
4194+ def test_kqueue_notification_without_immediate_reap (self ):
4195+ self .assert_notification_without_immediate_reap ("_wait_kqueue" )
4196+
41674197
41684198if __name__ == "__main__" :
41694199 unittest .main ()
0 commit comments