Skip to content

Commit

Permalink
More robust thread quittting
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasgriffin committed Oct 16, 2024
1 parent 12a6a7c commit f683a9b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
7 changes: 4 additions & 3 deletions bitcoin_safe/gui/qt/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1343,22 +1343,23 @@ def sync(self) -> None:
qt_wallet.sync()

def closeEvent(self, event: Optional[QCloseEvent]) -> None:
self.threading_manager.end_threading_manager()

self.config.last_wallet_files[str(self.config.network)] = [
qt_wallet.file_path for qt_wallet in self.qt_wallets.values()
]

self.write_current_open_txs_to_config()
self.config.save()
self.save_all_wallets()

self.threading_manager.end_threading_manager()

self.remove_all_qt_wallet()

if self.new_startup_network:
self.config.network = self.new_startup_network
self.config.save()

logger.info(f"Finished close handling")
logger.info(f"Finished close handling of {self}")
super().closeEvent(event)

def restart(self, new_startup_network: bdk.Network | None = None) -> None:
Expand Down
34 changes: 22 additions & 12 deletions bitcoin_safe/threading_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import sys
import threading
from collections import deque
from types import TracebackType
from typing import Any, Callable, NamedTuple, Optional, Tuple

from PyQt6.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
Expand All @@ -55,7 +56,7 @@ class Worker(QObject):
"""Worker object to perform tasks in a separate thread."""

finished: pyqtSignal = pyqtSignal(object, object, object) # Result, cb_done, cb_success/error
error: pyqtSignal = pyqtSignal(object)
error: pyqtSignal = pyqtSignal(object, object)

def __init__(self, task: Task) -> None:
super().__init__()
Expand Down Expand Up @@ -107,6 +108,8 @@ def add_and_start(
NoThread().add_and_start(do, on_success, on_done, on_error)
return self

self.cancelled = False

logger.debug(f"Starting new thread {do}.")
task: Task = Task(do, on_success, on_done, on_error, cancel)
self.worker = Worker(task)
Expand All @@ -126,36 +129,41 @@ def thread_name(self):
if self.worker.thread_name:
return self.worker.thread_name

def on_error(self, error_info):
def on_error(
self,
error_info: tuple[type[BaseException], BaseException, TracebackType],
cb_error: Callable[[Any], None],
):
if self.worker:
self.worker.task.cb_error(error_info)
cb_error(error_info)
self.my_quit()

@pyqtSlot(object, object, object)
def on_done(self, result: Any, cb_done: Callable[[Any], None], cb_result: Callable[[Any], None]) -> None:
"""Handle task completion."""
logger.debug(f"Thread done: {self.thread_name}.")
cb_done(result)
cb_result(result)
if not self.cancelled:
logger.debug(f"Thread done: {self.thread_name}.")
cb_done(result)
cb_result(result)
self.my_quit()

def stop(self) -> None:
"""Stops the thread and any associated task cancellation if defined."""
logger.info("Stopping TaskThread and associated worker.")
logger.debug(f"Stopping {self.thread_name}.")
if self.worker and self.worker.task.cancel:
logger.debug(f"Stopping {self.thread_name}.")
self.cancelled = True
self.worker.task.cancel()
self.my_quit()
logger.debug(f"Stopped {self.thread_name}.")

def my_quit(self):
name = self.thread_name
try:
self.cancelled = True
self.quit()
self.wait()
# cannot put it in finally, since QThread might be already destroyed
# and then self is not recognized as a QThread decendent any more in pyqtSignal
self.deleteLater()
except:
pass
logger.error(f"An error during the shutdown of {name}")


class NoThread:
Expand Down Expand Up @@ -230,9 +238,11 @@ def stop_and_wait_all(self):
# Wait for all threads to finish
while self.taskthreads:
taskthread = self.taskthreads.pop()
logger.debug(f"stop taskthreads {taskthread}")
taskthread.stop()

def end_threading_manager(self):
logger.debug(f"end_threading_manager of {self}")
self.stop_and_wait_all()

if self.threading_parent and self in self.threading_parent.threading_manager_children:
Expand Down

0 comments on commit f683a9b

Please sign in to comment.