diff options
Diffstat (limited to 'src/kernel/qapplication.cpp')
-rw-r--r-- | src/kernel/qapplication.cpp | 142 |
1 files changed, 110 insertions, 32 deletions
diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp index 64f4dfa4b..10e25adb6 100644 --- a/src/kernel/qapplication.cpp +++ b/src/kernel/qapplication.cpp @@ -377,8 +377,13 @@ int TQApplication::composedUnicode = 0; #ifdef QT_THREAD_SUPPORT TQMutex *TQApplication::tqt_mutex = 0; -static TQMutex *postevent_mutex = 0; -static TQt::HANDLE tqt_application_thread_id = 0; +TQMutex *tqt_sharedStringMutex = 0; +Q_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; Q_EXPORT TQt::HANDLE tqt_get_application_thread_id() { return tqt_application_thread_id; @@ -600,6 +605,10 @@ static TQPostEventList *globalPostedEvents = 0; // list of posted events uint qGlobalPostedEventsCount() { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( postevent_mutex ); +#endif // QT_THREAD_SUPPORT + if (!globalPostedEvents) { return 0; } @@ -1015,6 +1024,11 @@ void TQApplication::initialize( int argc, char **argv ) { #ifdef QT_THREAD_SUPPORT tqt_mutex = new TQMutex( TRUE ); + tqt_sharedStringMutex = new TQMutex( TRUE ); + tqt_sharedMetaObjectMutex = new TQMutex( TRUE ); +#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 // QT_THREAD_SUPPORT @@ -1184,6 +1198,17 @@ TQApplication::~TQApplication() session_key = 0; #endif //QT_NO_SESSIONMANAGER +#ifdef QT_THREAD_SUPPORT + delete tqt_sharedMetaObjectMutex; + tqt_sharedMetaObjectMutex = 0; + delete tqt_sharedStringMutex; + tqt_sharedStringMutex = 0; +#ifdef QT_USE_GLIBMAINLOOP + delete tqt_timerListMutex; + tqt_timerListMutex = 0; +#endif // QT_USE_GLIBMAINLOOP +#endif // QT_THREAD_SUPPORT + tqt_explicit_app_style = FALSE; tqt_app_has_font = FALSE; app_tracking = 0; @@ -2425,35 +2450,40 @@ bool TQApplication::notify( TQObject *receiver, TQEvent *e ) return FALSE; } - if ( e->type() == TQEvent::ChildRemoved && receiver->postedEvents && globalPostedEvents) { + if ( receiver && (e->type() == TQEvent::Destroy) ) { + return TRUE; + } + if ( e->type() == TQEvent::ChildRemoved && receiver->postedEvents) { #ifdef QT_THREAD_SUPPORT TQMutexLocker locker( postevent_mutex ); #endif // QT_THREAD_SUPPORT - // 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; + 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(); + } } - l->next(); - } } } @@ -3545,8 +3575,9 @@ void TQApplication::removePostedEvents( TQObject *receiver ) void TQApplication::removePostedEvents( TQObject *receiver, int event_type ) { - if ( !receiver ) + if ( !receiver ) { return; + } #ifdef QT_THREAD_SUPPORT TQMutexLocker locker( postevent_mutex ); @@ -3556,8 +3587,9 @@ void TQApplication::removePostedEvents( TQObject *receiver, int event_type ) // 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 ( !receiver->postedEvents ) { return; + } // iterate over the object-specifc list and delete the events. // leave the TQPostEvent objects; they'll be deleted by @@ -3596,8 +3628,13 @@ void TQApplication::removePostedEvents( TQObject *receiver, int event_type ) void TQApplication::removePostedEvent( TQEvent * event ) { - if ( !event || !event->posted ) + if ( !event || !event->posted ) { return; + } + +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( postevent_mutex ); +#endif // QT_THREAD_SUPPORT if ( !globalPostedEvents ) { #if defined(QT_DEBUG) @@ -3607,10 +3644,6 @@ void TQApplication::removePostedEvent( TQEvent * event ) #endif } -#ifdef QT_THREAD_SUPPORT - TQMutexLocker locker( postevent_mutex ); -#endif // QT_THREAD_SUPPORT - TQPostEventListIt it( *globalPostedEvents ); TQPostEvent * pe; while( (pe = it.current()) != 0 ) { @@ -3696,6 +3729,51 @@ void TQApplication::removePostedEvent( TQEvent * event ) } } +void tqThreadTerminationHandlerRecursive( TQObject* object, TQThread* originThread, TQThread* destinationThread ) { +#ifdef QT_THREAD_SUPPORT + TQThread* objectThread = object->contextThreadObject(); + if (objectThread != destinationThread) { + TQThread::CleanupType cleanupType = objectThread->cleanupType(); + if (cleanupType == TQThread::CleanupMergeObjects) { + object->moveToThread(destinationThread); + } + else if (cleanupType == TQThread::CleanupNone) { + // Do nothing +#if defined(QT_DEBUG) + tqDebug( "TQApplication::threadTerminationHandler: object %p still owned by thread %p at thread termination!", object, objectThread); +#endif // QT_DEBUG + } + else { + // Do nothing +#if defined(QT_DEBUG) + tqDebug( "TQApplication::threadTerminationHandler: invalid thread termination cleanup type %d specified", cleanupType); +#endif // QT_DEBUG + } + } + TQObjectList children = object->childrenListObject(); + TQObject *childObject; + for ( childObject = children.first(); childObject; childObject = children.next() ) { + tqThreadTerminationHandlerRecursive(childObject, originThread, destinationThread); + } +#endif // QT_THREAD_SUPPORT +} + +/*!\internal + + Migrates all objects from the specified thread in preparation + for thread destruction. + */ +void TQApplication::threadTerminationHandler( TQThread *originThread ) { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( tqt_mutex ); + TQThread* destinationThread = guiThread(); + const TQObjectList* objects = TQObject::objectTrees(); + for ( TQObjectListIt objectit( *objects ) ; *objectit; ++objectit ) { + tqThreadTerminationHandlerRecursive((*objectit), originThread, destinationThread); + } +#endif // QT_THREAD_SUPPORT +} + /*!\internal Sets the active window in reaction to a system event. Call this |