mirror of
https://github.com/python/cpython.git
synced 2025-12-15 21:44:50 +00:00
GH-98023: Change default child watcher to PidfdChildWatcher on supported systems (#98024)
This commit is contained in:
parent
3d8b224547
commit
8ba9378b16
3 changed files with 29 additions and 2 deletions
|
|
@ -1403,6 +1403,17 @@ class ThreadedChildWatcher(AbstractChildWatcher):
|
|||
|
||||
self._threads.pop(expected_pid)
|
||||
|
||||
def can_use_pidfd():
|
||||
if not hasattr(os, 'pidfd_open'):
|
||||
return False
|
||||
try:
|
||||
pid = os.getpid()
|
||||
os.close(os.pidfd_open(pid, 0))
|
||||
except OSError:
|
||||
# blocked by security policy like SECCOMP
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
|
||||
"""UNIX event loop policy with a watcher for child processes."""
|
||||
|
|
@ -1415,7 +1426,10 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
|
|||
def _init_watcher(self):
|
||||
with events._lock:
|
||||
if self._watcher is None: # pragma: no branch
|
||||
self._watcher = ThreadedChildWatcher()
|
||||
if can_use_pidfd():
|
||||
self._watcher = PidfdChildWatcher()
|
||||
else:
|
||||
self._watcher = ThreadedChildWatcher()
|
||||
if threading.current_thread() is threading.main_thread():
|
||||
self._watcher.attach_loop(self._local._loop)
|
||||
|
||||
|
|
|
|||
|
|
@ -1702,7 +1702,8 @@ class PolicyTests(unittest.TestCase):
|
|||
def test_get_default_child_watcher(self):
|
||||
policy = self.create_policy()
|
||||
self.assertIsNone(policy._watcher)
|
||||
|
||||
unix_events.can_use_pidfd = mock.Mock()
|
||||
unix_events.can_use_pidfd.return_value = False
|
||||
watcher = policy.get_child_watcher()
|
||||
self.assertIsInstance(watcher, asyncio.ThreadedChildWatcher)
|
||||
|
||||
|
|
@ -1710,6 +1711,17 @@ class PolicyTests(unittest.TestCase):
|
|||
|
||||
self.assertIs(watcher, policy.get_child_watcher())
|
||||
|
||||
policy = self.create_policy()
|
||||
self.assertIsNone(policy._watcher)
|
||||
unix_events.can_use_pidfd = mock.Mock()
|
||||
unix_events.can_use_pidfd.return_value = True
|
||||
watcher = policy.get_child_watcher()
|
||||
self.assertIsInstance(watcher, asyncio.PidfdChildWatcher)
|
||||
|
||||
self.assertIs(policy._watcher, watcher)
|
||||
|
||||
self.assertIs(watcher, policy.get_child_watcher())
|
||||
|
||||
def test_get_child_watcher_after_set(self):
|
||||
policy = self.create_policy()
|
||||
watcher = asyncio.FastChildWatcher()
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Change default child watcher to :class:`~asyncio.PidfdChildWatcher` on Linux systems which supports it. Patch by Kumar Aditya.
|
||||
Loading…
Add table
Add a link
Reference in a new issue