diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp index 45016b04..fafb0fc0 100644 --- a/src/kernel/qapplication.cpp +++ b/src/kernel/qapplication.cpp @@ -379,10 +379,11 @@ int TQApplication::composedUnicode = 0; TQMutex *TQApplication::tqt_mutex = 0; TQMutex *tqt_sharedStringMutex = 0; TQ_EXPORT TQMutex * tqt_sharedMetaObjectMutex = 0; + #ifdef QT_USE_GLIBMAINLOOP TQMutex *tqt_timerListMutex = 0; #endif // QT_USE_GLIBMAINLOOP -static TQMutex *postevent_mutex = 0; + static TQt::HANDLE tqt_application_thread_id = 0; TQ_EXPORT TQt::HANDLE tqt_get_application_thread_id() { @@ -597,7 +598,7 @@ static TQCoreApplicationThread tqt_main_thread; // Definitions for posted events struct TQPostEvent { TQPostEvent( TQObject *r, TQEvent *e ): receiver( r ), event( e ) {} - ~TQPostEvent() { delete event; } + ~TQPostEvent() { delete event; } TQObject *receiver; TQEvent *event; }; @@ -605,36 +606,68 @@ struct TQPostEvent { class TQ_EXPORT TQPostEventList : public TQPtrList { public: - TQPostEventList() : TQPtrList() {} - TQPostEventList( const TQPostEventList &list ) : TQPtrList(list) {} - ~TQPostEventList() { clear(); } - TQPostEventList &operator=(const TQPostEventList &list) - { return (TQPostEventList&)TQPtrList::operator=(list); } + TQPostEventList(bool with_mutex = false) : TQPtrList(), m_mutex(nullptr) + { +#ifdef TQT_THREAD_SUPPORT + if (with_mutex) + { + m_mutex = new TQMutex(TRUE); + } +#endif + } + + ~TQPostEventList() + { + if (m_mutex) + { + delete m_mutex; + m_mutex = nullptr; + } + clear(); + } + + TQMutex* mutex() const { return m_mutex; } + +private: + TQMutex *m_mutex; + + TQPostEventList(const TQPostEventList &) = delete; + TQPostEventList &operator=(const TQPostEventList &) = delete; }; + class TQ_EXPORT TQPostEventListIt : public TQPtrListIterator { public: TQPostEventListIt( const TQPostEventList &l ) : TQPtrListIterator(l) {} TQPostEventListIt &operator=(const TQPostEventListIt &i) -{ return (TQPostEventListIt&)TQPtrListIterator::operator=(i); } +{ + return (TQPostEventListIt&)TQPtrListIterator::operator=(i); } }; -static TQPostEventList *globalPostedEvents = 0; // list of posted events +// The global list and its pointer are initialized in different functions +// to optimize access to the list pointer in normal usage +static TQPostEventList* InitGlobalPostedEventsList() +{ + static TQPostEventList _globalEventList(true); + _globalEventList.setAutoDelete(TRUE); + return &_globalEventList; +} + +static TQPostEventList* GlobalPostedEvents() +{ + static TQPostEventList *_globalPostedEvents = InitGlobalPostedEventsList(); + return _globalPostedEvents; +} uint qGlobalPostedEventsCount() { #ifdef TQT_THREAD_SUPPORT - TQMutexLocker locker( postevent_mutex ); + TQMutexLocker locker( GlobalPostedEvents()->mutex() ); #endif // TQT_THREAD_SUPPORT - if (!globalPostedEvents) { - return 0; - } - return globalPostedEvents->count(); + return GlobalPostedEvents()->count(); } -static TQSingleCleanupHandler qapp_cleanup_events; - #ifndef TQT_NO_PALETTE TQPalette *tqt_std_pal = 0; @@ -1094,7 +1127,6 @@ void TQApplication::initialize( int argc, char **argv, bool enable_sm ) #ifdef QT_USE_GLIBMAINLOOP tqt_timerListMutex = new TQMutex( TRUE ); #endif // QT_USE_GLIBMAINLOOP - postevent_mutex = new TQMutex( TRUE ); tqt_application_thread_id = TQThread::currentThread(); #endif // TQT_THREAD_SUPPORT @@ -1253,8 +1285,6 @@ TQApplication::~TQApplication() #ifdef TQT_THREAD_SUPPORT delete tqt_mutex; tqt_mutex = 0; - delete postevent_mutex; - postevent_mutex = 0; #endif // TQT_THREAD_SUPPORT if( tqApp == this ) { @@ -2546,33 +2576,31 @@ bool TQApplication::notify( TQObject *receiver, TQEvent *e ) if ( e->type() == TQEvent::ChildRemoved && receiver->postedEvents) { #ifdef TQT_THREAD_SUPPORT - TQMutexLocker locker( postevent_mutex ); + TQMutexLocker locker( GlobalPostedEvents()->mutex() ); #endif // TQT_THREAD_SUPPORT - if (globalPostedEvents) { - // the TQObject destructor calls TQObject::removeChild, which calls - // TQApplication::sendEvent() directly. this can happen while the event - // loop is in the middle of posting events, and when we get here, we may - // not have any more posted events for this object. - if ( receiver->postedEvents ) { - // if this is a child remove event and the child insert - // hasn't been dispatched yet, kill that insert - TQPostEventList * l = receiver->postedEvents; - TQObject * c = ((TQChildEvent*)e)->child(); - TQPostEvent * pe; - l->first(); - while( ( pe = l->current()) != 0 ) { - if ( pe->event && pe->receiver == receiver && - pe->event->type() == TQEvent::ChildInserted && - ((TQChildEvent*)pe->event)->child() == c ) { - pe->event->posted = FALSE; - delete pe->event; - pe->event = 0; - l->remove(); - continue; - } - l->next(); + // the TQObject destructor calls TQObject::removeChild, which calls + // TQApplication::sendEvent() directly. this can happen while the event + // loop is in the middle of posting events, and when we get here, we may + // not have any more posted events for this object. + if ( receiver->postedEvents ) { + // if this is a child remove event and the child insert + // hasn't been dispatched yet, kill that insert + TQPostEventList * l = receiver->postedEvents; + TQObject * c = ((TQChildEvent*)e)->child(); + TQPostEvent * pe; + l->first(); + while( ( pe = l->current()) != 0 ) { + if ( pe->event && pe->receiver == receiver && + pe->event->type() == TQEvent::ChildInserted && + ((TQChildEvent*)pe->event)->child() == c ) { + pe->event->posted = FALSE; + delete pe->event; + pe->event = 0; + l->remove(); + continue; } + l->next(); } } } @@ -3394,16 +3422,9 @@ void TQApplication::postEvent( TQObject *receiver, TQEvent *event ) } #ifdef TQT_THREAD_SUPPORT - TQMutexLocker locker( postevent_mutex ); + TQMutexLocker locker( GlobalPostedEvents()->mutex() ); #endif // TQT_THREAD_SUPPORT - if ( !globalPostedEvents ) { // create list - globalPostedEvents = new TQPostEventList; - TQ_CHECK_PTR( globalPostedEvents ); - globalPostedEvents->setAutoDelete( TRUE ); - qapp_cleanup_events.set( &globalPostedEvents ); - } - if ( !receiver->postedEvents ) { receiver->postedEvents = new TQPostEventList; } @@ -3487,7 +3508,7 @@ void TQApplication::postEvent( TQObject *receiver, TQEvent *event ) event->posted = TRUE; TQPostEvent * pe = new TQPostEvent( receiver, event ); l->append( pe ); - globalPostedEvents->append( pe ); + GlobalPostedEvents()->append( pe ); #ifdef TQT_THREAD_SUPPORT // Wake up the receiver thread event loop @@ -3543,24 +3564,20 @@ void TQApplication::sendPostedEvents( TQObject *receiver, int event_type ) } #ifdef TQT_THREAD_SUPPORT - TQMutexLocker locker( postevent_mutex ); + TQMutexLocker locker( GlobalPostedEvents()->mutex() ); #endif - if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) { - return; - } - bool sent = TRUE; while ( sent ) { sent = FALSE; - if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) { + if (receiver && !receiver->postedEvents) { return; } // if we have a receiver, use the local list. Otherwise, use the // global list - TQPostEventList * l = receiver ? receiver->postedEvents : globalPostedEvents; + TQPostEventList * l = receiver ? receiver->postedEvents : GlobalPostedEvents(); // okay. here is the tricky loop. be careful about optimizing // this, it looks the way it does for good reasons. @@ -3632,14 +3649,14 @@ void TQApplication::sendPostedEvents( TQObject *receiver, int event_type ) // clear the global list, i.e. remove everything that was // delivered. - if ( l == globalPostedEvents ) { - globalPostedEvents->first(); - while( (pe=globalPostedEvents->current()) != 0 ) { + if ( l == GlobalPostedEvents() ) { + GlobalPostedEvents()->first(); + while( (pe=GlobalPostedEvents()->current()) != 0 ) { if ( pe->event ) { - globalPostedEvents->next(); + GlobalPostedEvents()->next(); } else { - globalPostedEvents->remove(); + GlobalPostedEvents()->remove(); } } } @@ -3681,7 +3698,7 @@ void TQApplication::removePostedEvents( TQObject *receiver, int event_type ) } #ifdef TQT_THREAD_SUPPORT - TQMutexLocker locker( postevent_mutex ); + TQMutexLocker locker( GlobalPostedEvents()->mutex() ); #endif // TQT_THREAD_SUPPORT // the TQObject destructor calls this function directly. this can @@ -3734,18 +3751,10 @@ void TQApplication::removePostedEvent( TQEvent * event ) } #ifdef TQT_THREAD_SUPPORT - TQMutexLocker locker( postevent_mutex ); + TQMutexLocker locker( GlobalPostedEvents()->mutex() ); #endif // TQT_THREAD_SUPPORT - if ( !globalPostedEvents ) { -#if defined(QT_DEBUG) - tqDebug( "TQApplication::removePostedEvent: %p %d is posted: impossible", - (void*)event, event->type() ); - return; -#endif - } - - TQPostEventListIt it( *globalPostedEvents ); + TQPostEventListIt it( *GlobalPostedEvents() ); TQPostEvent * pe; while( (pe = it.current()) != 0 ) { ++it; diff --git a/src/kernel/qobject.cpp b/src/kernel/qobject.cpp index bb4c848b..7692e9c2 100644 --- a/src/kernel/qobject.cpp +++ b/src/kernel/qobject.cpp @@ -747,7 +747,10 @@ TQObject::~TQObject() if ( pendTimer ) { // might be pending timers qKillTimer( this ); } - TQApplication::removePostedEvents( this ); + if ( tqApp ) + { + TQApplication::removePostedEvents( this ); + } if ( isTree ) { remove_tree( this ); // remove from global root list isTree = FALSE; diff --git a/src/kernel/qwidget.cpp b/src/kernel/qwidget.cpp index 0c76bd3b..c865fbe9 100644 --- a/src/kernel/qwidget.cpp +++ b/src/kernel/qwidget.cpp @@ -1008,7 +1008,10 @@ TQWidget::~TQWidget() childObjects = 0; } - TQApplication::removePostedEvents( this ); + if ( tqApp ) + { + TQApplication::removePostedEvents( this ); + } destroy(); // platform-dependent cleanup if ( extra )