qt main_window: _coroutines_scheduled needs locking
window.run_coroutine_from_thread starts a coroutine on the asyncio loop, which, when finishing, pops from the dict. The for loop in clean_up is running on the Qt thread. fixes https://github.com/spesmilo/electrum/issues/7983
This commit is contained in:
@@ -189,6 +189,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
||||
Logger.__init__(self)
|
||||
|
||||
self._coroutines_scheduled = {} # type: Dict[concurrent.futures.Future, str]
|
||||
self._coroutines_scheduled_lock = threading.Lock()
|
||||
self.thread = TaskThread(self, self.on_error)
|
||||
|
||||
self.tx_notification_queue = queue.Queue()
|
||||
@@ -310,11 +311,13 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
||||
if on_result:
|
||||
on_result(res)
|
||||
finally:
|
||||
self._coroutines_scheduled.pop(fut)
|
||||
with self._coroutines_scheduled_lock:
|
||||
self._coroutines_scheduled.pop(fut)
|
||||
self.need_update.set()
|
||||
|
||||
fut = asyncio.run_coroutine_threadsafe(wrapper(), self.network.asyncio_loop)
|
||||
self._coroutines_scheduled[fut] = name
|
||||
with self._coroutines_scheduled_lock:
|
||||
self._coroutines_scheduled[fut] = name
|
||||
self.need_update.set()
|
||||
|
||||
def on_fx_history(self):
|
||||
@@ -999,7 +1002,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
||||
if num_tasks == 0:
|
||||
name = ''
|
||||
elif num_tasks == 1:
|
||||
name = list(self._coroutines_scheduled.values())[0] + '...'
|
||||
with self._coroutines_scheduled_lock:
|
||||
name = list(self._coroutines_scheduled.values())[0] + '...'
|
||||
else:
|
||||
name = "%d"%num_tasks + _('tasks') + '...'
|
||||
self.tasks_label.setText(name)
|
||||
@@ -2494,7 +2498,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
||||
if self.thread:
|
||||
self.thread.stop()
|
||||
self.thread = None
|
||||
for fut in self._coroutines_scheduled.keys():
|
||||
with self._coroutines_scheduled_lock:
|
||||
coro_keys = list(self._coroutines_scheduled.keys())
|
||||
for fut in coro_keys:
|
||||
fut.cancel()
|
||||
self.unregister_callbacks()
|
||||
self.config.set_key("is_maximized", self.isMaximized())
|
||||
|
||||
Reference in New Issue
Block a user