From ebc3e67bf427f4210264c2259ea2887bca745fee Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Wed, 13 Mar 2024 19:50:28 +0300 Subject: [PATCH] Workaround crashes caused by some slots deleting the sender Signed-off-by: Alexander Golubev --- src/kernel/ntqobject.h | 2 +- src/kernel/ntqobjectdefs.h | 2 +- src/kernel/qobject.cpp | 32 ++++++++++++++++++++++++++------ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/kernel/ntqobject.h b/src/kernel/ntqobject.h index fc16c50b..cc5d5c89 100644 --- a/src/kernel/ntqobject.h +++ b/src/kernel/ntqobject.h @@ -210,7 +210,7 @@ private: const char *objname; TQObject *parentObj; TQObjectList *childObjects; - TQSignalVec *connections; + TQObjectSignalVec *connections; TQSenderObjectList *senderObjects; TQObjectList *eventFilters; TQPostEventList *postedEvents; diff --git a/src/kernel/ntqobjectdefs.h b/src/kernel/ntqobjectdefs.h index ba5e12b8..53f7e806 100644 --- a/src/kernel/ntqobjectdefs.h +++ b/src/kernel/ntqobjectdefs.h @@ -155,7 +155,7 @@ class TQMutex; struct TQMetaData; class TQConnectionList; class TQConnectionListIt; -class TQSignalVec; +class TQObjectSignalVec; class TQObjectList; class TQObjectListIt; class TQMemberDict; diff --git a/src/kernel/qobject.cpp b/src/kernel/qobject.cpp index 44971cfe..6b28b15f 100644 --- a/src/kernel/qobject.cpp +++ b/src/kernel/qobject.cpp @@ -88,6 +88,14 @@ class TQStyleControlElementDataPrivate { bool isTQWidget; }; +// A thin wrapper around TQSignalVec, which is technicly public, but shouldn't be +class TQObjectSignalVec: public TQSignalVec, public TQShared +{ +public: + TQObjectSignalVec(int size=17 ): TQSignalVec(size) + { setAutoDelete(TRUE); } +}; + #ifndef TQT_NO_USERDATA class TQObjectPrivate : public TQPtrVector #else @@ -773,8 +781,10 @@ TQObject::~TQObject() } } } - delete connections; - connections = 0; + if ( connections->deref() ) { + delete connections; + connections = 0; + } } if ( eventFilters ) { delete eventFilters; @@ -1606,8 +1616,7 @@ TQConnectionList *TQObject::receivers( int signal ) const if ( tqt_preliminary_signal_spy && signal >= 0 ) { if ( !connections ) { TQObject* that = (TQObject*) this; - that->connections = new TQSignalVec( signal+1 ); - that->connections->setAutoDelete( TRUE ); + that->connections = new TQObjectSignalVec( signal+1 ); } if ( !connections->at( signal ) ) { TQConnectionList* clist = new TQConnectionList; @@ -2242,9 +2251,8 @@ void TQObject::connectInternal( const TQObject *sender, int signal_index, const TQObject *r = (TQObject*)receiver; if ( !s->connections ) { // create connections lookup table - s->connections = new TQSignalVec( signal_index+1 ); + s->connections = new TQObjectSignalVec( signal_index+1 ); TQ_CHECK_PTR( s->connections ); - s->connections->setAutoDelete( TRUE ); } TQConnectionList *clist = s->connections->at( signal_index ); @@ -2785,6 +2793,13 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) const TQThread *currentThread = TQThread::currentThreadObject(); #endif // TQT_THREAD_SUPPORT + // Some slots are deleting the sender. It's not that great, but it's widespread enough, + // so we can't track all such issues. So, we have to workaround this somehow. + // For that we are postponing the deletion of clist (which is part of connections). + Q_ASSERT(connections); + TQObjectSignalVec *conn = connections; + conn->ref(); + const TQConnection *cd = 0; for(const TQConnection *c: *clist) { Q_ASSERT( c ); @@ -2862,6 +2877,11 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) if (sol) sol->listMutex->unlock(); #endif // TQT_THREAD_SUPPORT } + + // use a copy of the pointer here as at this point this might be already deleted; no pun intended ;) + if( conn->deref() ) { + delete conn; + } } /*!