8000 switch to pidfd · python/cpython@67b155c · GitHub
[go: up one dir, main page]

Skip to content

Commit 67b155c

Browse files
switch to pidfd
1 parent e500cc0 commit 67b155c

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

Lib/asyncio/unix_events.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,17 @@ def _do_waitpid(self, loop, expected_pid, callback, args):
14231423

14241424
self._threads.pop(expected_pid)
14251425

1426+
def can_use_pidfd():
1427+
if not hasattr(os, 'pidfd_open'):
1428+
return False
1429+
try:
1430+
pid = os.getpid()
1431+
os.close(os.pidfd_open(pid, 0))
1432+
except OSError:
1433+
# blocked by security policy like SECCOMP
1434+
return False
1435+
return True
1436+
14261437

14271438
class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
14281439
"""UNIX event loop policy with a watcher for child processes."""
@@ -1435,7 +1446,10 @@ def __init__(self):
14351446
def _init_watcher(self):
14361447
with events._lock:
14371448
if self._watcher is None: # pragma: no branch
1438-
self._watcher = ThreadedChildWatcher()
1449+
if can_use_pidfd():
1450+
self._watcher = PidfdChildWatcher()
1451+
else:
1452+
self._watcher = ThreadedChildWatcher()
14391453
if threading.current_thread() is threading.main_thread():
14401454
self._watcher.attach_loop(self._local._loop)
14411455

Lib/test/test_asyncio/test_unix_events.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1702,14 +1702,26 @@ def create_policy(self):
17021702
def test_get_default_child_watcher(self):
17031703
policy = self.create_policy()
17041704
self.assertIsNone(policy._watcher)
1705-
1705+
unix_events.can_use_pidfd = mock.Mock()
1706+
unix_events.can_use_pidfd.return_value = False
17061707
watcher = policy.get_child_watcher()
17071708
self.assertIsInstance(watcher, asyncio.ThreadedChildWatcher)
17081709

17091710
self.assertIs(policy._watcher, watcher)
17101711

17111712
self.assertIs(watcher, policy.get_child_watcher())
17121713

1714+
policy = self.create_policy()
1715+
self.assertIsNone(policy._watcher)
1716+
unix_events.can_use_pidfd = mock.Mock()
1717+
unix_events.can_use_pidfd.return_value = True
1718+
watcher = policy.get_child_watcher()
1719+
self.assertIsInstance(watcher, asyncio.PidfdChildWatcher)
1720+
1721+
self.assertIs(policy._watcher, watcher)
1722+
1723+
self.assertIs(watcher, policy.get_child_watcher())
1724+
17131725
def test_get_child_watcher_after_set(self):
17141726
policy = self.create_policy()
17151727
watcher = asyncio.FastChildWatcher()

0 commit comments

Comments
 (0)
0