Skip to content

Commit bf1e269

Browse files
committed
fixes a possible race condition in AutoRestartTrick
Just a long shot for a failure observed on gorakhargosh#998. My hypothesis is that when we stop ProcessWatcher before we restart the process manually, we don't yield to it and immediately kill the process. Next, when the ProcessWatcher thread is woken up, we have to conditions ready - the popen_obj and stopped_event, see the corresponding code, ``` while True: if self.popen_obj.poll() is not None: break if self.stopped_event.wait(timeout=0.1): return ``` And desipte that `stopped_event` is set, we first check for `popen_obj` and trigger the process restart. We can also make the ProcessWatcher logic more robust, by checking if we are stopped before calling the termination callback, e.g., ``` try: if not self.stopped_event.is_set(): self.process_termination_callback() except Exception: logger.exception("Error calling process termination callback") ``` I am not 100% sure about that, as I don't really know what semantics is expected from ProcessWatcher by other users. But at least the AutoRestarter expects this semantics - i.e., a watcher shall not call any events after it was stopped.
1 parent 75a3289 commit bf1e269

File tree

1 file changed

+1
-0
lines changed

1 file changed

+1
-0
lines changed

src/watchdog/tricks/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ def _stop_process(self):
253253
try:
254254
if self.process_watcher is not None:
255255
self.process_watcher.stop()
256+
self.process_watcher.join()
256257
self.process_watcher = None
257258

258259
if self.process is not None:

0 commit comments

Comments
 (0)