diff options
| author | Victor Stinner <vstinner@python.org> | 2019-12-06 16:32:41 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-06 16:32:41 +0100 |
| commit | e76ee1a72b9e3f5da287663ea3daec4bb3f67612 (patch) | |
| tree | f49a44ca51473f69ec847ba87178a7060b50ed6d | |
| parent | b64334cb93d0ddbb551c8cd712942bab2fc72772 (diff) | |
| download | cpython-git-e76ee1a72b9e3f5da287663ea3daec4bb3f67612.tar.gz | |
bpo-38982: Fix asyncio PidfdChildWatcher on waitpid() error (GH-17477)
If waitpid() is called elsewhere, waitpid() call fails with
ChildProcessError: use return code 255 in this case, and log a
warning. It ensure that the pidfd file descriptor is closed if this
error occurs.
| -rw-r--r-- | Lib/asyncio/unix_events.py | 15 | ||||
| -rw-r--r-- | Misc/NEWS.d/next/Library/2019-12-05-18-21-26.bpo-38982.W3u-03.rst | 5 |
2 files changed, 18 insertions, 2 deletions
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 97198ea2f4..28fb491864 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -930,9 +930,20 @@ class PidfdChildWatcher(AbstractChildWatcher): def _do_wait(self, pid): pidfd, callback, args = self._callbacks.pop(pid) self._loop._remove_reader(pidfd) - _, status = os.waitpid(pid, 0) + try: + _, status = os.waitpid(pid, 0) + except ChildProcessError: + # The child process is already reaped + # (may happen if waitpid() is called elsewhere). + returncode = 255 + logger.warning( + "child process pid %d exit status already read: " + " will report returncode 255", + pid) + else: + returncode = _compute_returncode(status) + os.close(pidfd) - returncode = _compute_returncode(status) callback(pid, returncode, *args) def remove_child_handler(self, pid): diff --git a/Misc/NEWS.d/next/Library/2019-12-05-18-21-26.bpo-38982.W3u-03.rst b/Misc/NEWS.d/next/Library/2019-12-05-18-21-26.bpo-38982.W3u-03.rst new file mode 100644 index 0000000000..b591209ea0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-12-05-18-21-26.bpo-38982.W3u-03.rst @@ -0,0 +1,5 @@ +Fix asyncio ``PidfdChildWatcher``: handle ``waitpid()`` error. If +``waitpid()`` is called elsewhere, ``waitpid()`` call fails with +:exc:`ChildProcessError`: use return code 255 in this case, and log a +warning. It ensures that the pidfd file descriptor is closed if this error +occurs. |
