@@ -188,10 +188,33 @@ async def connect_stdout():
188188
189189 @override
190190 def _connect_child (self , argv : List [str ]) -> None :
191- if os .name != 'nt' :
192- # see #238, #241
193- self ._child_watcher = asyncio .get_child_watcher ()
194- self ._child_watcher .attach_loop (self ._loop )
191+ def can_use_pidfd ():
192+ try :
193+ pid = os .getpid ()
194+ fd = os .pidfd_open (pid , 0 )
195+ os .close (fd )
196+ except OSError :
197+ # blocked by security policy like SECCOMP
198+ return False
199+ return True
200+
201+ def get_child_watcher ():
202+ # Unix system without pidfd_open
203+ if hasattr (os , "pidfd_open" ):
204+ try :
205+ from asyncio .unix_events import PidfdChildWatcher
206+ if can_use_pidfd ():
207+ return PidfdChildWatcher ()
208+ except ImportError :
209+ pass
210+
211+ try :
212+ from asyncio .unix_events import ThreadedChildWatcher
213+ return ThreadedChildWatcher ()
214+ except ImportError :
215+ pass
216+
217+ return asyncio .get_child_watcher ()
195218
196219 async def create_subprocess ():
197220 transport : asyncio .SubprocessTransport # type: ignore
@@ -200,6 +223,12 @@ async def create_subprocess():
200223 pid = transport .get_pid ()
201224 debug ("child subprocess_exec successful, PID = %s" , pid )
202225
226+ if os .name != 'nt' :
227+ watcher = get_child_watcher ()
228+
229+ watcher .attach_loop (self ._loop )
230+ self ._child_watcher = watcher
231+
203232 self ._transport = cast (asyncio .WriteTransport ,
204233 transport .get_pipe_transport (0 )) # stdin
205234 self ._protocol = protocol
0 commit comments