99#include < type_traits>
1010#include < utils/Logger.h>
1111
12- #define ENABLE_MEMORY_TRACKING 1
12+ #define ENABLE_MEMORY_TRACKING 0
1313
1414#define USE_TRACKED_SHARED_PTR ENABLE_MEMORY_TRACKING
15- #define USE_TRACKED_DELETE_LATER ENABLE_MEMORY_TRACKING
15+ #define USE_TRACKED_CUSTOM_DELETE ENABLE_MEMORY_TRACKING
1616
1717#if USE_TRACKED_SHARED_PTR
1818 #define MAKE_TRACKED_SHARED (T, ...) makeTrackedShared<T>(__VA_ARGS__)
1919#else
20- #define MAKE_TRACKED_SHARED (T, ...) QSharedPointer<T>(new T(__VA_ARGS__), &DELETE_LATER_FN (T) )
20+ #define MAKE_TRACKED_SHARED (T, ...) QSharedPointer<T>(new T(__VA_ARGS__), &customDelete<T> )
2121#endif
2222
23- #if USE_TRACKED_DELETE_LATER
24- #define DELETE_LATER_FN (T ) trackedDeleteLater<T>
25- #else
26- #define DELETE_LATER_FN (T ) untrackedDeleteLater<T>
27-
28- #endif
29-
30- // Deleter function templates
23+ // Custom Delete function templates
3124
3225template <typename T>
33- void untrackedDeleteLater (T* ptr)
26+ void customDelete (T* ptr)
3427{
3528 if (!ptr)
3629 return ;
3730
38- if constexpr (std::is_base_of<QObject, T>::value)
39- {
40- QThread* thread = ptr->thread ();
41- if (thread && thread->isRunning ())
42- {
43- QMetaObject::invokeMethod (ptr, " deleteLater" , Qt::QueuedConnection);
44- }
45- else
46- {
47- delete ptr;
48- }
49- }
50- else
51- {
52- delete ptr;
53- }
54- }
55-
56- template <typename T>
57- void trackedDeleteLater (T* ptr)
58- {
59- if (!ptr)
60- return ;
31+ #if USE_TRACKED_CUSTOM_DELETE
6132
6233 QString subComponent = " __" ;
6334 QString typeName;
@@ -77,28 +48,44 @@ void trackedDeleteLater(T* ptr)
7748 }
7849
7950 Logger* log = Logger::getInstance (" MEMORY" , subComponent);
80-
8151 Debug (log, " Deleting object of type '%s' at %p" , QSTRING_CSTR (typeName), static_cast <void *>(ptr));
52+ #endif
8253
8354 if constexpr (std::is_base_of<QObject, T>::value)
8455 {
8556 QThread* thread = ptr->thread ();
86- if (thread && thread->isRunning ())
87- {
88- // Schedule deleteLater from the object's thread
89- Debug (log, " QObject<%s>::deleteLater() scheduled via invokeMethod on thread '%s'" ,
90- QSTRING_CSTR (typeName), QSTRING_CSTR (thread->objectName ()));
91- QMetaObject::invokeMethod (ptr, " deleteLater" , Qt::QueuedConnection);
57+ if (thread && thread == QThread::currentThread ()) {
58+ #if USE_TRACKED_CUSTOM_DELETE
59+ Debug (log, " QObject<%s> deleted immediately (current thread)." , QSTRING_CSTR (typeName));
60+ #endif
61+ ptr->deleteLater ();
9262 }
9363 else
9464 {
95- Debug (log, " QObject<%s> deleted immediately (thread not running)." , QSTRING_CSTR (typeName));
96- delete ptr;
65+ if (thread && thread->isRunning ())
66+ {
67+ // Schedule deleteLater from the object's thread
68+ #if USE_TRACKED_CUSTOM_DELETE
69+ Debug (log, " QObject<%s>::deleteLater() scheduled via invokeMethod on thread '%s'" ,
70+ QSTRING_CSTR (typeName), QSTRING_CSTR (thread->objectName ()));
71+ #endif
72+ QMetaObject::invokeMethod (ptr, " deleteLater" , Qt::QueuedConnection);
73+ }
74+ else
75+ {
76+ // This should be an *extremely rare* fallback and indicates a bug in the thread shutdown sequence.
77+ #if USE_TRACKED_CUSTOM_DELETE
78+ Debug (log, " <%s> object's owning thread is not running. Deleted immediately (thread not running)." , QSTRING_CSTR (typeName));
79+ #endif
80+ delete ptr;
81+ }
9782 }
9883 }
9984 else
10085 {
86+ #if USE_TRACKED_CUSTOM_DELETE
10187 Debug (log, " Non-QObject<%s> deleted immediately." , QSTRING_CSTR (typeName));
88+ #endif
10289 delete ptr;
10390
10491 }
@@ -132,7 +119,7 @@ QSharedPointer<T> makeTrackedShared(Args&&... args)
132119 Logger* log = Logger::getInstance (" MEMORY" , subComponent);
133120 Debug (log, " Creating object of type '%s' at %p" , QSTRING_CSTR (typeName), static_cast <void *>(rawPtr));
134121
135- return QSharedPointer<T>(rawPtr, DELETE_LATER_FN (T) );
122+ return QSharedPointer<T>(rawPtr, &customDelete<T> );
136123}
137124
138125#endif // TRACKEDMEMORY_H
0 commit comments