[Python-checkins] GH-98023: Change default child watcher to PidfdChildWatcher on supported systems (#98024)
gvanrossum
webhook-mailer at python.org
Fri Oct 7 20:29:17 EDT 2022
https://github.com/python/cpython/commit/8ba9378b168ad330c158a001afca03d6c028d39b
commit: 8ba9378b168ad330c158a001afca03d6c028d39b
branch: main
author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com>
committer: gvanrossum <gvanrossum at gmail.com>
date: 2022-10-07T17:29:09-07:00
summary:
GH-98023: Change default child watcher to PidfdChildWatcher on supported systems (#98024)
files:
A Misc/NEWS.d/next/Library/2022-10-07-09-52-37.gh-issue-98023.aliEcl.rst
M Lib/asyncio/unix_events.py
M Lib/test/test_asyncio/test_unix_events.py
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 0f67b4d469f2..7fc75cd17ef7 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -1403,6 +1403,17 @@ def _do_waitpid(self, loop, expected_pid, callback, args):
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 @@ def __init__(self):
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)
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index 5bad21ecbae4..03fb5e649d8e 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -1702,7 +1702,8 @@ def create_policy(self):
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 @@ def test_get_default_child_watcher(self):
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()
diff --git a/Misc/NEWS.d/next/Library/2022-10-07-09-52-37.gh-issue-98023.aliEcl.rst b/Misc/NEWS.d/next/Library/2022-10-07-09-52-37.gh-issue-98023.aliEcl.rst
new file mode 100644
index 000000000000..1bfd68d4ac7c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-10-07-09-52-37.gh-issue-98023.aliEcl.rst
@@ -0,0 +1 @@
+Change default child watcher to :class:`~asyncio.PidfdChildWatcher` on Linux systems which supports it. Patch by Kumar Aditya.
More information about the Python-checkins
mailing list