Skip to content

Commit af6ce8e

Browse files
authored
Merge pull request Electron-Cash#3173 from EchterAgo/fix_jobs_deadlock
Fix deadlock in DaemonThread when jobs block while holding job_lock Take a copy of the jobs list, then execute the jobs without the lock held, so as to not hold the lock for too long.
2 parents d3ad66c + 3b9f9ec commit af6ce8e

1 file changed

Lines changed: 16 additions & 8 deletions

File tree

electroncash/util.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,15 +220,23 @@ def remove_jobs(self, jobs):
220220
self._jobs2rm.update(jobs)
221221

222222
def run_jobs(self):
223+
# Make a copy of the jobs list while holding the lock
224+
with self.job_lock:
225+
jobs_copy = list(self.jobs)
226+
227+
# Execute jobs without holding the lock to avoid deadlock when jobs
228+
# block (e.g. showing modal dialogs)
229+
for job in jobs_copy:
230+
try:
231+
job.run()
232+
except Exception as e:
233+
# Don't let a throwing job disrupt the thread, future runs of
234+
# itself, or other jobs. This is useful protection against
235+
# malformed or malicious server responses
236+
traceback.print_exc(file=sys.stderr)
237+
238+
# Now handle job additions/removals while holding the lock
223239
with self.job_lock:
224-
for job in self.jobs:
225-
try:
226-
job.run()
227-
except Exception as e:
228-
# Don't let a throwing job disrupt the thread, future runs of
229-
# itself, or other jobs. This is useful protection against
230-
# malformed or malicious server responses
231-
traceback.print_exc(file=sys.stderr)
232240
# below is support for jobs adding/removing themselves
233241
# during their run implementation.
234242
for addjob in self._jobs2add:

0 commit comments

Comments
 (0)