@@ -188,10 +188,36 @@ 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+ # Unix system without pidfd_open?
193+ if not hasattr (os , 'pidfd_open' ):
194+ return False
195+
196+ # Check that we are not blocked by security policy like SECCOMP
197+ try :
198+ pid = os .getpid ()
199+ fd = os .pidfd_open (pid , 0 )
200+ os .close (fd )
201+ except OSError :
202+ return False
203+
204+ return True
205+
206+ def get_child_watcher ():
207+ if can_use_pidfd ():
208+ try :
209+ from asyncio .unix_events import PidfdChildWatcher
210+ return PidfdChildWatcher ()
211+ except ImportError :
212+ pass
213+
214+ try :
215+ from asyncio .unix_events import ThreadedChildWatcher
216+ return ThreadedChildWatcher ()
217+ except ImportError :
218+ pass
219+
220+ return asyncio .get_child_watcher ()
195221
196222 async def create_subprocess ():
197223 transport : asyncio .SubprocessTransport # type: ignore
@@ -200,6 +226,12 @@ async def create_subprocess():
200226 pid = transport .get_pid ()
201227 debug ("child subprocess_exec successful, PID = %s" , pid )
202228
229+ if os .name != 'nt' :
230+ watcher = get_child_watcher ()
231+
232+ watcher .attach_loop (self ._loop )
233+ self ._child_watcher = watcher
234+
203235 self ._transport = cast (asyncio .WriteTransport ,
204236 transport .get_pipe_transport (0 )) # stdin
205237 self ._protocol = protocol
0 commit comments