diff --git a/tools/chatgui/src/main.cpp b/tools/chatgui/src/main.cpp index 71c9825b..e1550463 100644 --- a/tools/chatgui/src/main.cpp +++ b/tools/chatgui/src/main.cpp @@ -5,6 +5,7 @@ #include #ifdef _WIN32 #include +#include #endif #include "mainwindow.h" #include "../db/db_manager.h" @@ -15,6 +16,19 @@ #ifdef _WIN32 static UtunNode* g_ctrl_node = nullptr; +static DWORD count_threads(void) { + DWORD pid = GetCurrentProcessId(), count = 0; + HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (snap == INVALID_HANDLE_VALUE) return 0; + THREADENTRY32 te = { sizeof(te) }; + if (Thread32First(snap, &te)) { + do { if (te.th32OwnerProcessID == pid) count++; } + while (Thread32Next(snap, &te)); + } + CloseHandle(snap); + return count; +} + static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType) { if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) { if (g_ctrl_node) g_ctrl_node->requestStop(); @@ -27,6 +41,14 @@ static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType) { static struct ShutdownSentinel { ~ShutdownSentinel() { DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "main: static destructors done"); +#ifdef _WIN32 + DWORD threads = count_threads(); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "main: threads at exit=%lu", (unsigned long)threads); + if (threads > 4) { + DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "main: %lu hanging threads, ExitProcess", (unsigned long)threads); + ExitProcess(0); + } +#endif } } g_shutdown_sentinel; diff --git a/tools/chatgui/src/mainwindow.cpp b/tools/chatgui/src/mainwindow.cpp index 1982d2f0..c5f33b5c 100644 --- a/tools/chatgui/src/mainwindow.cpp +++ b/tools/chatgui/src/mainwindow.cpp @@ -90,6 +90,8 @@ MainWindow::~MainWindow() { DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "MainWindow: ~MainWindow — stopping utun node"); if (m_node) { m_node->stop(); delete m_node; m_node = nullptr; } DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "MainWindow: ~MainWindow — node stop+delete done"); + MessageList::cleanupAnimations(); + DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "MainWindow: ~MainWindow — animations cleaned"); DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "MainWindow: ~MainWindow done"); } diff --git a/tools/chatgui/src/messagelist.cpp b/tools/chatgui/src/messagelist.cpp index 90f7b407..478b4034 100644 --- a/tools/chatgui/src/messagelist.cpp +++ b/tools/chatgui/src/messagelist.cpp @@ -7,6 +7,7 @@ #include "animtimer.h" #include "lottieicon.h" #include "../db/db_manager.h" +#include "../../lib/debug_config.h" #include #include #include @@ -18,6 +19,8 @@ #include #include +static std::vector> s_icons; + extern "C" { #include "../transport/gui_bridge.h" #include "../transport/chat_core.h" @@ -95,7 +98,6 @@ MessageList::MessageList(DbManager* db, QWidget *parent) m_view->setBackgroundImage("../resources/bg.jpg"); layout->addWidget(m_view, 1); - static std::vector> s_icons; if (s_icons.empty()) { for (const auto &cat : builtinEmojiSet()) { for (const auto &e : cat.items) { @@ -412,3 +414,10 @@ void MessageList::updateReadPosition() { chat_core_save_ui_state(posKey.constData(), posVal.constData()); } } + +void MessageList::cleanupAnimations() { + size_t n = s_icons.size(); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "MessageList: cleanupAnimations clearing %zu icons", n); + s_icons.clear(); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "MessageList: cleanupAnimations done"); +} diff --git a/tools/chatgui/src/messagelist.h b/tools/chatgui/src/messagelist.h index 2091061a..2880b89b 100644 --- a/tools/chatgui/src/messagelist.h +++ b/tools/chatgui/src/messagelist.h @@ -19,6 +19,7 @@ public: void loadChannel(const QString& channelId); void refresh(); void saveChannelState(); + static void cleanupAnimations(); void addMessage(const QString& channelId, quint64 authorNodeId, const QByteArray& content, qint64 timestamp);