@@ -188,10 +188,42 @@ async def connect_stdout():
188188
189189 @override
190190 def _connect_child (self , argv : List [str ]) -> None :
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 import PidfdChildWatcher
210+ return PidfdChildWatcher ()
211+ except ImportError :
212+ pass
213+
214+ try :
215+ from asyncio import ThreadedChildWatcher
216+ return ThreadedChildWatcher ()
217+ except ImportError :
218+ pass
219+
220+ # FIXME Python 3.7, return None if we drop support
221+ return asyncio .get_child_watcher ()
222+
191223 if os .name != 'nt' :
192- # see #238, #241
193- self . _child_watcher = asyncio . get_child_watcher ( )
194- self ._child_watcher . attach_loop ( self . _loop )
224+ watcher = get_child_watcher ()
225+ watcher . attach_loop ( self . _loop )
226+ self ._child_watcher = watcher
195227
196228 async def create_subprocess ():
197229 transport : asyncio .SubprocessTransport # type: ignore
@@ -250,7 +282,8 @@ def _close_transport(transport):
250282 # Windows: for ProactorBasePipeTransport, close() doesn't take in
251283 # effect immediately (closing happens asynchronously inside the
252284 # event loop), need to wait a bit for completing graceful shutdown.
253- if os .name == 'nt' and hasattr (transport , '_sock' ):
285+ if (sys .version_info < (3 , 13 ) and
286+ os .name == 'nt' and hasattr (transport , '_sock' )):
254287 async def wait_until_closed ():
255288 # pylint: disable-next=protected-access
256289 while transport ._sock is not None :
0 commit comments