Kaydet (Commit) ab27a9fc authored tarafından Guido van Rossum's avatar Guido van Rossum

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

üst 669eeaf9
...@@ -641,22 +641,16 @@ class FastChildWatcher(BaseChildWatcher): ...@@ -641,22 +641,16 @@ class FastChildWatcher(BaseChildWatcher):
def add_child_handler(self, pid, callback, *args): def add_child_handler(self, pid, callback, *args):
assert self._forks, "Must use the context manager" assert self._forks, "Must use the context manager"
with self._lock:
try:
returncode = self._zombies.pop(pid)
except KeyError:
# The child is running.
self._callbacks[pid] = callback, args
return
self._callbacks[pid] = callback, args # The child is dead already. We can fire the callback.
callback(pid, returncode, *args)
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:
callback(pid, returncode, *args)
def remove_child_handler(self, pid): def remove_child_handler(self, pid):
try: try:
...@@ -681,16 +675,18 @@ class FastChildWatcher(BaseChildWatcher): ...@@ -681,16 +675,18 @@ class FastChildWatcher(BaseChildWatcher):
returncode = self._compute_returncode(status) returncode = self._compute_returncode(status)
try: with self._lock:
callback, args = self._callbacks.pop(pid) try:
except KeyError: callback, args = self._callbacks.pop(pid)
# unknown child except KeyError:
with self._lock: # unknown child
if self._forks: if self._forks:
# It may not be registered yet. # It may not be registered yet.
self._zombies[pid] = returncode self._zombies[pid] = returncode
continue continue
callback = None
if callback is None:
logger.warning( logger.warning(
"Caught subprocess termination from unknown pid: " "Caught subprocess termination from unknown pid: "
"%d -> %d", pid, returncode) "%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