1
0

run_electrum: have daemon manage Plugins object, and call Plugins.stop

Plugins.stop was never called, so the Plugins thread only stopped
because of the is_running() check in run(), which triggers too late:
the Plugins thread was stopping after the main thread stopped.

E.g. playing around in the qt wizard with wallet creation for a Trezor,
and closing the wizard (only window):
``` 24.85 | E | p/plugin.Plugins |
Traceback (most recent call last):
  File "/home/user/wspace/electrum/electrum/util.py", line 386, in run_jobs
    job.run()
  File "/home/user/wspace/electrum/electrum/plugin.py", line 430, in run
    client.timeout(cutoff)
  File "/home/user/wspace/electrum/electrum/plugin.py", line 363, in wrapper
    return run_in_hwd_thread(partial(func, *args, **kwargs))
  File "/home/user/wspace/electrum/electrum/plugin.py", line 355, in run_in_hwd_thread
    fut = _hwd_comms_executor.submit(func)
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 167, in submit
    raise RuntimeError('cannot schedule new futures after shutdown')
RuntimeError: cannot schedule new futures after shutdown
```
This commit is contained in:
SomberNight
2023-08-24 16:56:23 +00:00
parent c12d9b14da
commit 90f39bce88
3 changed files with 25 additions and 8 deletions

View File

@@ -451,10 +451,9 @@ def handle_cmd(*, cmdname: str, config: 'SimpleConfig', config_options: dict):
configure_logging(config)
fd = daemon.get_file_descriptor(config)
if fd is not None:
plugins = init_plugins(config, config.GUI_NAME)
d = daemon.Daemon(config, fd, start_network=False)
try:
d.run_gui(config, plugins)
d.run_gui()
except BaseException as e:
_logger.exception('daemon.run_gui errored')
sys_exit(1)
@@ -469,7 +468,6 @@ def handle_cmd(*, cmdname: str, config: 'SimpleConfig', config_options: dict):
fd = daemon.get_file_descriptor(config)
if fd is not None:
# run daemon
init_plugins(config, 'cmdline')
d = daemon.Daemon(config, fd)
d.run_daemon()
sys_exit(0)
@@ -515,7 +513,11 @@ def handle_cmd(*, cmdname: str, config: 'SimpleConfig', config_options: dict):
coro = run_offline_command(config, config_options, plugins)
fut = asyncio.run_coroutine_threadsafe(coro, loop)
try:
result = fut.result()
try:
result = fut.result()
finally:
plugins.stop()
plugins.stopped_event.wait(1)
except Exception as e:
print_stderr(str(e) or repr(e))
sys_exit(1)