diff options
author | Alexander Golubev <fatzer2@gmail.com> | 2024-03-16 08:31:50 +0300 |
---|---|---|
committer | TDE Gitea <gitea@mirror.git.trinitydesktop.org> | 2024-03-18 09:36:47 +0000 |
commit | b1e6f384640525c5a0caceef017848f8ebee46b8 (patch) | |
tree | 0503258437e109f568af20702e446fc092dc2555 /src/kernel | |
parent | bcda4011918a88064d35908b089a3300e187245a (diff) | |
download | tqt3-b1e6f384640525c5a0caceef017848f8ebee46b8.tar.gz tqt3-b1e6f384640525c5a0caceef017848f8ebee46b8.zip |
Fix TQThreadStorage destruction in the main thread
Before that the allocations of TQThreadStorage objects from the main
thread were never destroyed and memory associated with them were never
freed. The second one isn't a huge problem as at that point program is
terminating anyway (but it still makes valgrind complain). The first one
is the bigger issue as destructors might contain some essential external
cleanups like removing temporary files.
Also make `TQApplication::guiThread()` return `0` when the thread is
destroyed (may happen on the program exiting during destruction of
statics).
Signed-off-by: Alexander Golubev <fatzer2@gmail.com>
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/ntqthread.h | 1 | ||||
-rw-r--r-- | src/kernel/qapplication.cpp | 24 | ||||
-rw-r--r-- | src/kernel/qthread_unix.cpp | 5 |
3 files changed, 28 insertions, 2 deletions
diff --git a/src/kernel/ntqthread.h b/src/kernel/ntqthread.h index 695a61fb7..0b38e5a33 100644 --- a/src/kernel/ntqthread.h +++ b/src/kernel/ntqthread.h @@ -120,6 +120,7 @@ protected: private: TQThreadInstance * d; friend class TQThreadInstance; + friend class TQThreadStorageData; friend class TQCoreApplicationThread; friend class TQApplication; friend class TQEventLoop; diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp index fbdb9330c..e8658cdab 100644 --- a/src/kernel/qapplication.cpp +++ b/src/kernel/qapplication.cpp @@ -542,12 +542,19 @@ TQClipboard *tqt_clipboard = 0; // global clipboard object TQWidgetList * tqt_modal_stack=0; // stack of modal widgets #ifdef TQT_THREAD_SUPPORT + // thread wrapper for the main() thread class TQCoreApplicationThread : public TQThread { public: inline TQCoreApplicationThread() { +#ifdef QT_CHECK_STATE + if ( tqt_gui_thread_self ) + tqWarning( "TQCoreApplicationThread: there should be exactly one main thread object" ); +#endif + tqt_gui_thread_self = this; + TQThreadInstance::setCurrentThread(this); // thread should be running and not finished for the lifetime @@ -556,11 +563,19 @@ public: d->finished = false; d->eventLoop = NULL; } + inline ~TQCoreApplicationThread() { + tqt_gui_thread_self = nullptr; + // avoid warning from TQThread d->running = false; + // do some cleanup, namely clean up the thread-local storage associated with the GUI thread + TQThreadInstance::finishGuiThread(d); } + + static TQCoreApplicationThread* self() { return tqt_gui_thread_self; } + private: inline void run() { @@ -568,10 +583,15 @@ private: // only so that we can instantiate the object tqFatal("TQCoreApplicationThread: internal error"); } + + static TQCoreApplicationThread* tqt_gui_thread_self; }; +TQCoreApplicationThread* TQCoreApplicationThread::tqt_gui_thread_self = nullptr; + +// construct exactly one instance of the core thread with static storage duration. Do it static +// rather than in the heap as we need it to be properly destroyed on the exit from the program. static TQCoreApplicationThread tqt_main_thread; -static TQThread *mainThread() { return &tqt_main_thread; } #endif // Definitions for posted events @@ -1035,7 +1055,7 @@ TQApplication::TQApplication(Display *dpy, int argc, char **argv, #ifdef TQT_THREAD_SUPPORT TQThread* TQApplication::guiThread() { - return mainThread(); + return TQCoreApplicationThread::self(); } bool TQApplication::isGuiThread() { diff --git a/src/kernel/qthread_unix.cpp b/src/kernel/qthread_unix.cpp index 7a6bc3393..6a6f81b7f 100644 --- a/src/kernel/qthread_unix.cpp +++ b/src/kernel/qthread_unix.cpp @@ -180,6 +180,11 @@ void TQThreadInstance::finish( void * ) } } +void TQThreadInstance::finishGuiThread(TQThreadInstance *d) { + TQThreadStorageData::finish( d->thread_storage ); + d->thread_storage = 0; +} + TQMutex *TQThreadInstance::mutex() const { return qt_thread_mutexpool ? qt_thread_mutexpool->get( (void *) this ) : 0; |