diff options
author | Yury Selivanov <yury@magic.io> | 2016-10-05 20:57:12 (GMT) |
---|---|---|
committer | Yury Selivanov <yury@magic.io> | 2016-10-05 20:57:12 (GMT) |
commit | 9eb6c677763c1eaf0646170ccff110c89828a06e (patch) | |
tree | 546b340fc4aad4f9b24e0bb646242ebc744c6155 /Lib/asyncio/unix_events.py | |
parent | b5bb404ccaa9a3dd81e220fb4ca40253be778831 (diff) | |
download | cpython-9eb6c677763c1eaf0646170ccff110c89828a06e.zip cpython-9eb6c677763c1eaf0646170ccff110c89828a06e.tar.gz cpython-9eb6c677763c1eaf0646170ccff110c89828a06e.tar.bz2 |
Issue #28368: Refuse monitoring processes if the child watcher has no loop attached.
Patch by Vincent Michel.
Diffstat (limited to 'Lib/asyncio/unix_events.py')
-rw-r--r-- | Lib/asyncio/unix_events.py | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index a0113f6..ac44218 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -746,6 +746,7 @@ class BaseChildWatcher(AbstractChildWatcher): def __init__(self): self._loop = None + self._callbacks = {} def close(self): self.attach_loop(None) @@ -759,6 +760,12 @@ class BaseChildWatcher(AbstractChildWatcher): def attach_loop(self, loop): assert loop is None or isinstance(loop, events.AbstractEventLoop) + if self._loop is not None and loop is None and self._callbacks: + warnings.warn( + 'A loop is being detached ' + 'from a child watcher with pending handlers', + RuntimeWarning) + if self._loop is not None: self._loop.remove_signal_handler(signal.SIGCHLD) @@ -807,10 +814,6 @@ class SafeChildWatcher(BaseChildWatcher): big number of children (O(n) each time SIGCHLD is raised) """ - def __init__(self): - super().__init__() - self._callbacks = {} - def close(self): self._callbacks.clear() super().close() @@ -822,6 +825,11 @@ class SafeChildWatcher(BaseChildWatcher): pass def add_child_handler(self, pid, callback, *args): + if self._loop is None: + raise RuntimeError( + "Cannot add child handler, " + "the child watcher does not have a loop attached") + self._callbacks[pid] = (callback, args) # Prevent a race condition in case the child is already terminated. @@ -886,7 +894,6 @@ class FastChildWatcher(BaseChildWatcher): """ def __init__(self): super().__init__() - self._callbacks = {} self._lock = threading.Lock() self._zombies = {} self._forks = 0 @@ -918,6 +925,12 @@ class FastChildWatcher(BaseChildWatcher): def add_child_handler(self, pid, callback, *args): assert self._forks, "Must use the context manager" + + if self._loop is None: + raise RuntimeError( + "Cannot add child handler, " + "the child watcher does not have a loop attached") + with self._lock: try: returncode = self._zombies.pop(pid) |