Commit ab27a9fc authored by Guido van Rossum's avatar Guido van Rossum

asyncio: Fix race in FastChildWatcher (by its original author, Anthony Baire).

parent 669eeaf9
......@@ -641,21 +641,15 @@ class FastChildWatcher(BaseChildWatcher):
def add_child_handler(self, pid, callback, *args):
assert self._forks, "Must use the context manager"
self._callbacks[pid] = callback, args
with self._lock:
try:
# Ensure that the child is not already terminated.
# (raise KeyError if still alive)
returncode = self._zombies.pop(pid)
# Child is dead, therefore we can fire the callback immediately.
# First we remove it from the dict.
# (raise KeyError if .remove_child_handler() was called in-between)
del self._callbacks[pid]
except KeyError:
pass
else:
# The child is running.
self._callbacks[pid] = callback, args
return
# The child is dead already. We can fire the callback.
callback(pid, returncode, *args)
def remove_child_handler(self, pid):
......@@ -681,16 +675,18 @@ class FastChildWatcher(BaseChildWatcher):
returncode = self._compute_returncode(status)
with self._lock:
try:
callback, args = self._callbacks.pop(pid)
except KeyError:
# unknown child
with self._lock:
if self._forks:
# It may not be registered yet.
self._zombies[pid] = returncode
continue
callback = None
if callback is None:
logger.warning(
"Caught subprocess termination from unknown pid: "
"%d -> %d", pid, returncode)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment