diff options
author | Benjamin Schubert <bschubert15@bloomberg.net> | 2019-12-06 11:43:22 +0000 |
---|---|---|
committer | Valentin David <valentin.david@codethink.co.uk> | 2020-03-10 13:19:26 +0100 |
commit | 17acbd3dfda90017e2ffcbec73600f61a19f4492 (patch) | |
tree | 8e38f56bd724bd06d0d33d42477455672b588a5c | |
parent | 0721ffde2255dfa292626d1779877e72cff78ab4 (diff) | |
download | buildstream-17acbd3dfda90017e2ffcbec73600f61a19f4492.tar.gz |
scheduler.py: Only run thread-safe code in callbacks from watchers
Per
https://docs.python.org/3/library/asyncio-policy.html#asyncio.AbstractChildWatcher.add_child_handler,
the callback from a child handler must be thread safe. Not all our
callbacks were. This changes all our callbacks to schedule a call for
the next loop iteration instead of executing it directly.
-rw-r--r-- | buildstream/_scheduler/jobs/job.py | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/buildstream/_scheduler/jobs/job.py b/buildstream/_scheduler/jobs/job.py index cbe41bcd1..67ec75db5 100644 --- a/buildstream/_scheduler/jobs/job.py +++ b/buildstream/_scheduler/jobs/job.py @@ -138,7 +138,13 @@ class Job(): with asyncio.get_child_watcher() as watcher: self._process.start() # Register the process to call `_parent_child_completed` once it is done - watcher.add_child_handler(self._process.pid, self._parent_child_completed) + + # Here we delay the call to the next loop tick. This is in order to be running + # in the main thread, as the callback itself must be thread safe. + def on_completion(pid, returncode): + asyncio.get_event_loop().call_soon(self._parent_child_completed, pid, returncode) + + watcher.add_child_handler(self._process.pid, on_completion) # terminate() # |