diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-04-22 21:25:32 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-04-22 21:25:32 -0500 |
commit | 83d39cad274f592a43a3262926d215493caea0bc (patch) | |
tree | 05fefa97bd40200c6b7a1a184cd4df2610cc1091 | |
parent | 7abfc2a181531c769d50bcb1c0bff1fc08c66de2 (diff) | |
download | qt3-83d39cad274f592a43a3262926d215493caea0bc.tar.gz qt3-83d39cad274f592a43a3262926d215493caea0bc.zip |
Fix a number of threading problems and crashes
This partially resolves Bug 1467
-rw-r--r-- | src/kernel/qapplication.cpp | 45 | ||||
-rw-r--r-- | src/kernel/qeventloop_glib_p.h | 27 | ||||
-rw-r--r-- | src/kernel/qeventloop_unix_glib.cpp | 597 | ||||
-rw-r--r-- | src/kernel/qeventloop_x11_glib.cpp | 15 | ||||
-rw-r--r-- | src/kernel/qobject.cpp | 15 | ||||
-rw-r--r-- | src/tools/qglist.cpp | 355 | ||||
-rw-r--r-- | src/tools/qglist.h | 8 |
7 files changed, 757 insertions, 305 deletions
diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp index 620f5df..fb531cb 100644 --- a/src/kernel/qapplication.cpp +++ b/src/kernel/qapplication.cpp @@ -600,8 +600,9 @@ static QPostEventList *globalPostedEvents = 0; // list of posted events uint qGlobalPostedEventsCount() { - if (!globalPostedEvents) + if (!globalPostedEvents) { return 0; + } return globalPostedEvents->count(); } @@ -2413,8 +2414,9 @@ void QApplication::aboutQt() bool QApplication::notify( QObject *receiver, QEvent *e ) { // no events are delivered after ~QApplication() has started - if ( is_app_closing ) + if ( is_app_closing ) { return FALSE; + } if ( receiver == 0 ) { // serious error #if defined(QT_CHECK_NULL) @@ -2456,8 +2458,9 @@ bool QApplication::notify( QObject *receiver, QEvent *e ) } bool res = FALSE; - if ( !receiver->isWidgetType() ) + if ( !receiver->isWidgetType() ) { res = internalNotify( receiver, e ); + } else switch ( e->type() ) { #ifndef QT_NO_ACCEL case QEvent::Accel: @@ -2465,13 +2468,15 @@ bool QApplication::notify( QObject *receiver, QEvent *e ) QKeyEvent* key = (QKeyEvent*) e; res = internalNotify( receiver, e ); - if ( !res && !key->isAccepted() ) + if ( !res && !key->isAccepted() ) { res = qt_dispatchAccelEvent( (QWidget*)receiver, key ); + } // next lines are for compatibility with Qt <= 3.0.x: old // QAccel was listening on toplevel widgets - if ( !res && !key->isAccepted() && !((QWidget*)receiver)->isTopLevel() ) + if ( !res && !key->isAccepted() && !((QWidget*)receiver)->isTopLevel() ) { res = internalNotify( ((QWidget*)receiver)->topLevelWidget(), e ); + } } break; #endif //QT_NO_ACCEL @@ -3275,8 +3280,9 @@ void QApplication::postEvent( QObject *receiver, QEvent *event ) qapp_cleanup_events.set( &globalPostedEvents ); } - if ( !receiver->postedEvents ) + if ( !receiver->postedEvents ) { receiver->postedEvents = new QPostEventList; + } QPostEventList * l = receiver->postedEvents; // if this is one of the compressible events, do compression @@ -3374,8 +3380,9 @@ void QApplication::postEvent( QObject *receiver, QEvent *event ) } #endif - if (currentEventLoop()) + if (currentEventLoop()) { currentEventLoop()->wakeUp(); + } } @@ -3406,22 +3413,25 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type ) { // Make sure the object hierarchy is stable before processing events // to avoid endless loops - if ( receiver == 0 && event_type == 0 ) + if ( receiver == 0 && event_type == 0 ) { sendPostedEvents( 0, QEvent::ChildInserted ); - - if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) - return; + } #ifdef QT_THREAD_SUPPORT QMutexLocker locker( postevent_mutex ); #endif + if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) { + return; + } + bool sent = TRUE; while ( sent ) { sent = FALSE; - if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) + if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) { return; + } // if we have a receiver, use the local list. Otherwise, use the // global list @@ -3438,7 +3448,7 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type ) || receiver == pe->receiver ) // we send to THAT receiver && ( event_type == 0 // we send all types || event_type == pe->event->type() ) // we send THAT type - && ( (!pe->receiver) || (pe->receiver->contextThreadObject() == QThread::currentThreadObject()) ) ) { // only send if active thread is receiver object owning thread + && ( (!pe->receiver) || ((pe->receiver) && (!pe->receiver->wasDeleted) && (pe->receiver->contextThreadObject() == QThread::currentThreadObject())) ) ) { // only send if active thread is receiver object owning thread // first, we diddle the event so that we can deliver // it, and that noone will try to touch it later. pe->event->posted = FALSE; @@ -3471,8 +3481,9 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type ) if ( e->type() == QEvent::Paint && r->isWidgetType() ) { QWidget * w = (QWidget*)r; QPaintEvent * p = (QPaintEvent*)e; - if ( w->isVisible() ) + if ( w->isVisible() ) { w->repaint( p->reg, p->erase ); + } } else { sent = TRUE; QApplication::sendEvent( r, e ); @@ -3493,10 +3504,12 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type ) if ( l == globalPostedEvents ) { globalPostedEvents->first(); while( (pe=globalPostedEvents->current()) != 0 ) { - if ( pe->event ) + if ( pe->event ) { globalPostedEvents->next(); - else + } + else { globalPostedEvents->remove(); + } } } } diff --git a/src/kernel/qeventloop_glib_p.h b/src/kernel/qeventloop_glib_p.h index 4dfc02c..d8fa15d 100644 --- a/src/kernel/qeventloop_glib_p.h +++ b/src/kernel/qeventloop_glib_p.h @@ -75,8 +75,8 @@ class QSocketNotifier; struct QSockNotGPollFD { - QSocketNotifier *obj; - GPollFD gPollFD; + QSocketNotifier *obj; + GPollFD gPollFD; gushort events; // save events bool pending; }; @@ -84,25 +84,10 @@ struct QSockNotGPollFD class QEventLoopPrivate { public: - QEventLoopPrivate() - { -#if defined(Q_WS_X11) - xfd = -1; - x_gPollFD.fd = -1; -#endif // Q_WS_X11 - singletoolkit = TRUE; - ctx = 0; - ctx_is_default = false; - reset(); - } - - void reset() { - looplevel = 0; - quitcode = 0; - quitnow = FALSE; - exitloop = FALSE; - shortcut = FALSE; - } + QEventLoopPrivate(); + ~QEventLoopPrivate(); + + void reset(); int looplevel; int quitcode; diff --git a/src/kernel/qeventloop_unix_glib.cpp b/src/kernel/qeventloop_unix_glib.cpp index 6a890ce..1c491cf 100644 --- a/src/kernel/qeventloop_unix_glib.cpp +++ b/src/kernel/qeventloop_unix_glib.cpp @@ -45,6 +45,11 @@ #include "qapplication.h" #include "qbitarray.h" #include "qmutex.h" + +#if defined(QT_THREAD_SUPPORT) + #include "qthread.h" +#endif + #include <stdlib.h> #include <sys/types.h> @@ -87,22 +92,25 @@ // struct TimerInfo { // internal timer info - int id; // - timer identifier - timeval interval; // - timer interval - timeval timeout; // - when to sent event - QObject *obj; // - object to receive event + int id; // - timer identifier + timeval interval; // - timer interval + timeval timeout; // - when to sent event + QObject *obj; // - object to receive event }; -typedef QPtrList<TimerInfo> TimerList; // list of TimerInfo structs +typedef QPtrList<TimerInfo> TimerList; // list of TimerInfo structs static QBitArray *timerBitVec; // timer bit vector -static TimerList *timerList = 0; // timer list +static TimerList *timerList = 0; // timer list +#if defined(QT_THREAD_SUPPORT) +static QMutex *timerListMutex = 0; // timer list mutex +#endif -static void initTimers(); +static void initTimers(); void cleanupTimers(); -static timeval watchtime; // watch if time is turned back -timeval *qt_wait_timer(); -timeval *qt_wait_timer_max = 0; +static timeval watchtime; // watch if time is turned back +timeval *qt_wait_timer(); +timeval *qt_wait_timer_max = 0; // // Internal operator functions for timevals @@ -110,45 +118,44 @@ timeval *qt_wait_timer_max = 0; static inline bool operator<( const timeval &t1, const timeval &t2 ) { - return t1.tv_sec < t2.tv_sec || - (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); + return (t1.tv_sec < t2.tv_sec) || ((t1.tv_sec == t2.tv_sec) && (t1.tv_usec < t2.tv_usec)); } static inline bool operator==( const timeval &t1, const timeval &t2 ) { - return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; + return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; } static inline timeval &operator+=( timeval &t1, const timeval &t2 ) { - t1.tv_sec += t2.tv_sec; - if ( (t1.tv_usec += t2.tv_usec) >= 1000000 ) { - t1.tv_sec++; - t1.tv_usec -= 1000000; - } - return t1; + t1.tv_sec += t2.tv_sec; + if ( (t1.tv_usec += t2.tv_usec) >= 1000000 ) { + t1.tv_sec++; + t1.tv_usec -= 1000000; + } + return t1; } static inline timeval operator+( const timeval &t1, const timeval &t2 ) { - timeval tmp; - tmp.tv_sec = t1.tv_sec + t2.tv_sec; - if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 ) { - tmp.tv_sec++; - tmp.tv_usec -= 1000000; - } - return tmp; + timeval tmp; + tmp.tv_sec = t1.tv_sec + t2.tv_sec; + if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 ) { + tmp.tv_sec++; + tmp.tv_usec -= 1000000; + } + return tmp; } static inline timeval operator-( const timeval &t1, const timeval &t2 ) { - timeval tmp; - tmp.tv_sec = t1.tv_sec - t2.tv_sec; - if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 ) { - tmp.tv_sec--; - tmp.tv_usec += 1000000; - } - return tmp; + timeval tmp; + tmp.tv_sec = t1.tv_sec - t2.tv_sec; + if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 ) { + tmp.tv_sec--; + tmp.tv_usec += 1000000; + } + return tmp; } @@ -159,68 +166,84 @@ static inline timeval operator-( const timeval &t1, const timeval &t2 ) static int allocTimerId() // find avail timer identifier { - int i = timerBitVec->size()-1; - while ( i >= 0 && (*timerBitVec)[i] ) - i--; - if ( i < 0 ) { - i = timerBitVec->size(); - timerBitVec->resize( 4 * i ); - for( int j=timerBitVec->size()-1; j > i; j-- ) - timerBitVec->clearBit( j ); - } - timerBitVec->setBit( i ); - return i+1; + int i = timerBitVec->size()-1; + while ( i >= 0 && (*timerBitVec)[i] ) { + i--; + } + if ( i < 0 ) { + i = timerBitVec->size(); + timerBitVec->resize( 4 * i ); + for( int j=timerBitVec->size()-1; j > i; j-- ) { + timerBitVec->clearBit( j ); + } + } + timerBitVec->setBit( i ); + return i+1; } -static void insertTimer( const TimerInfo *ti ) // insert timer info into list +static void insertTimer( const TimerInfo *ti ) // insert timer info into list { - TimerInfo *t = timerList->first(); - int index = 0; +#if defined(QT_THREAD_SUPPORT) + timerListMutex->lock(); +#endif + TimerInfo *t = timerList->first(); + int index = 0; #if defined(QT_DEBUG) - int dangerCount = 0; + int dangerCount = 0; #endif - while ( t && t->timeout < ti->timeout ) { // list is sorted by timeout + while ( t && t->timeout < ti->timeout ) { // list is sorted by timeout #if defined(QT_DEBUG) - if ( t->obj == ti->obj ) - dangerCount++; + if ( t->obj == ti->obj ) { + dangerCount++; + } #endif - t = timerList->next(); - index++; - } - timerList->insert( index, ti ); // inserts sorted + t = timerList->next(); + index++; + } + timerList->insert( index, ti ); // inserts sorted #if defined(QT_DEBUG) - if ( dangerCount > 16 ) - qDebug( "QObject: %d timers now exist for object %s::%s", - dangerCount, ti->obj->className(), ti->obj->name() ); + if ( dangerCount > 16 ) { + qDebug( "QObject: %d timers now exist for object %s::%s", dangerCount, ti->obj->className(), ti->obj->name() ); + } +#endif +#if defined(QT_THREAD_SUPPORT) + timerListMutex->unlock(); #endif } -static inline void getTime( timeval &t ) // get time of day +static inline void getTime( timeval &t ) // get time of day { - gettimeofday( &t, 0 ); - while ( t.tv_usec >= 1000000 ) { // NTP-related fix - t.tv_usec -= 1000000; - t.tv_sec++; - } - while ( t.tv_usec < 0 ) { - if ( t.tv_sec > 0 ) { - t.tv_usec += 1000000; - t.tv_sec--; - } else { - t.tv_usec = 0; - break; + gettimeofday( &t, 0 ); + while ( t.tv_usec >= 1000000 ) { // NTP-related fix + t.tv_usec -= 1000000; + t.tv_sec++; + } + while ( t.tv_usec < 0 ) { + if ( t.tv_sec > 0 ) { + t.tv_usec += 1000000; + t.tv_sec--; + } + else { + t.tv_usec = 0; + break; + } } - } } -static void repairTimer( const timeval &time ) // repair broken timer +static void repairTimer( const timeval &time ) // repair broken timer { - timeval diff = watchtime - time; - register TimerInfo *t = timerList->first(); - while ( t ) { // repair all timers - t->timeout = t->timeout - diff; - t = timerList->next(); - } +#if defined(QT_THREAD_SUPPORT) + timerListMutex->lock(); +#endif + timeval diff = watchtime - time; + register TimerInfo *t = timerList->first(); + while ( t ) { // repair all timers + t->timeout = t->timeout - diff; + t = timerList->next(); + } +#if defined(QT_THREAD_SUPPORT) + timerListMutex->unlock(); +#endif } // @@ -236,117 +259,186 @@ static void repairTimer( const timeval &time ) // repair broken timer timeval *qt_wait_timer() { - static timeval tm; - bool first = TRUE; - timeval currentTime; - if ( timerList && timerList->count() ) { // there are waiting timers - getTime( currentTime ); - if ( first ) { - if ( currentTime < watchtime ) // clock was turned back - repairTimer( currentTime ); - first = FALSE; - watchtime = currentTime; +#if defined(QT_THREAD_SUPPORT) + if (timerListMutex) timerListMutex->lock(); +#endif + static timeval tm; + bool first = TRUE; + timeval currentTime; + if ( timerList && timerList->count() ) { // there are waiting timers + getTime( currentTime ); + if ( first ) { + if ( currentTime < watchtime ) { // clock was turned back + repairTimer( currentTime ); + } + first = FALSE; + watchtime = currentTime; + } + TimerInfo *t = timerList->first(); // first waiting timer + if ( currentTime < t->timeout ) { // time to wait + tm = t->timeout - currentTime; + } + else { + tm.tv_sec = 0; // no time to wait + tm.tv_usec = 0; + } + if ( qt_wait_timer_max && *qt_wait_timer_max < tm ) { + tm = *qt_wait_timer_max; + } +#if defined(QT_THREAD_SUPPORT) + if (timerListMutex) timerListMutex->unlock(); +#endif + return &tm; } - TimerInfo *t = timerList->first(); // first waiting timer - if ( currentTime < t->timeout ) { // time to wait - tm = t->timeout - currentTime; - } else { - tm.tv_sec = 0; // no time to wait - tm.tv_usec = 0; + if ( qt_wait_timer_max ) { + tm = *qt_wait_timer_max; +#if defined(QT_THREAD_SUPPORT) + if (timerListMutex) timerListMutex->unlock(); +#endif + return &tm; } - if ( qt_wait_timer_max && *qt_wait_timer_max < tm ) - tm = *qt_wait_timer_max; - return &tm; - } - if ( qt_wait_timer_max ) { - tm = *qt_wait_timer_max; - return &tm; - } - return 0; // no timers +#if defined(QT_THREAD_SUPPORT) + if (timerListMutex) timerListMutex->unlock(); +#endif + return 0; // no timers } // Timer initialization -static void initTimers() // initialize timers +static void initTimers() // initialize timers { - timerBitVec = new QBitArray( 128 ); - Q_CHECK_PTR( timerBitVec ); - int i = timerBitVec->size(); - while( i-- > 0 ) - timerBitVec->clearBit( i ); - timerList = new TimerList; - Q_CHECK_PTR( timerList ); - timerList->setAutoDelete( TRUE ); - gettimeofday( &watchtime, 0 ); + timerBitVec = new QBitArray( 128 ); + Q_CHECK_PTR( timerBitVec ); + int i = timerBitVec->size(); + while( i-- > 0 ) { + timerBitVec->clearBit( i ); + } + timerList = new TimerList; +#if defined(QT_THREAD_SUPPORT) + timerListMutex = new QMutex(true); +#endif + Q_CHECK_PTR( timerList ); + timerList->setAutoDelete( TRUE ); + gettimeofday( &watchtime, 0 ); } // Timer cleanup void cleanupTimers() { - delete timerList; - timerList = 0; - delete timerBitVec; - timerBitVec = 0; + delete timerList; + timerList = 0; + delete timerBitVec; + timerBitVec = 0; +#if defined(QT_THREAD_SUPPORT) + delete timerListMutex; + timerListMutex = 0; +#endif } // Main timer functions for starting and killing timers int qStartTimer( int interval, QObject *obj ) { - if ( !timerList ) // initialize timer data - initTimers(); - int id = allocTimerId(); // get free timer id - if ( id <= 0 || - id > (int)timerBitVec->size() || !obj )// cannot create timer - return 0; - timerBitVec->setBit( id-1 ); // set timer active - TimerInfo *t = new TimerInfo; // create timer - Q_CHECK_PTR( t ); - t->id = id; - t->interval.tv_sec = interval/1000; - t->interval.tv_usec = (interval%1000)*1000; - timeval currentTime; - getTime( currentTime ); - t->timeout = currentTime + t->interval; - t->obj = obj; - insertTimer( t ); // put timer in list - return id; + if ( !timerList ) { // initialize timer data + initTimers(); + } + int id = allocTimerId(); // get free timer id + if ( (id <= 0) || (id > (int)timerBitVec->size()) || (!obj) ) { // cannot create timer + return 0; + } + timerBitVec->setBit( id-1 ); // set timer active + TimerInfo *t = new TimerInfo; // create timer + Q_CHECK_PTR( t ); + t->id = id; + t->interval.tv_sec = interval/1000; + t->interval.tv_usec = (interval%1000)*1000; + timeval currentTime; + getTime( currentTime ); + t->timeout = currentTime + t->interval; + t->obj = obj; + insertTimer( t ); // put timer in list + return id; } bool qKillTimer( int id ) { - register TimerInfo *t; - if ( !timerList || id <= 0 || - id > (int)timerBitVec->size() || !timerBitVec->testBit( id-1 ) ) - return FALSE; // not init'd or invalid timer - t = timerList->first(); - while ( t && t->id != id ) // find timer info in list - t = timerList->next(); - if ( t ) { // id found - timerBitVec->clearBit( id-1 ); // set timer inactive - return timerList->remove(); - } - else // id not found - return FALSE; + register TimerInfo *t; + if ( (!timerList) || (id <= 0) || (id > (int)timerBitVec->size()) || (!timerBitVec->testBit( id-1 )) ) { + return FALSE; // not init'd or invalid timer + } +#if defined(QT_THREAD_SUPPORT) + timerListMutex->lock(); +#endif + t = timerList->first(); + while ( t && t->id != id ) { // find timer info in list + t = timerList->next(); + } + if ( t ) { // id found + bool ret; + timerBitVec->clearBit( id-1 ); // set timer inactive + ret = timerList->remove(); +#if defined(QT_THREAD_SUPPORT) + timerListMutex->unlock(); +#endif + return ret; + } + else { // id not found +#if defined(QT_THREAD_SUPPORT) + timerListMutex->unlock(); +#endif + return FALSE; + } } bool qKillTimer( QObject *obj ) { - register TimerInfo *t; - if ( !timerList ) // not initialized - return FALSE; - t = timerList->first(); - while ( t ) { // check all timers - if ( t->obj == obj ) { // object found - timerBitVec->clearBit( t->id-1 ); - timerList->remove(); - t = timerList->current(); - } else { - t = timerList->next(); + register TimerInfo *t; + if ( !timerList ) { // not initialized + return FALSE; } - } - return TRUE; +#if defined(QT_THREAD_SUPPORT) + timerListMutex->lock(); +#endif + t = timerList->first(); + while ( t ) { // check all timers + if ( t->obj == obj ) { // object found + timerBitVec->clearBit( t->id-1 ); + timerList->remove(); + t = timerList->current(); + } + else { + t = timerList->next(); + } + } +#if defined(QT_THREAD_SUPPORT) + timerListMutex->unlock(); +#endif + return TRUE; } +QEventLoopPrivate::QEventLoopPrivate() { +#if defined(Q_WS_X11) + xfd = -1; + x_gPollFD.fd = -1; + x_gPollFD.events = 0; + x_gPollFD.revents = 0; +#endif // Q_WS_X11 + singletoolkit = TRUE; + ctx = 0; + ctx_is_default = false; + reset(); +} + +QEventLoopPrivate::~QEventLoopPrivate() { + // +} + +void QEventLoopPrivate::reset() { + looplevel = 0; + quitcode = 0; + quitnow = FALSE; + exitloop = FALSE; + shortcut = FALSE; +} /***************************************************************************** @@ -358,9 +450,6 @@ bool qKillTimer( QObject *obj ) void QEventLoop::registerSocketNotifier( QSocketNotifier *notifier ) { - - - int sockfd = notifier->socket(); int type = notifier->type(); if ( sockfd < 0 || type < 0 || type > 2 || notifier == 0 ) { @@ -378,13 +467,13 @@ void QEventLoop::registerSocketNotifier( QSocketNotifier *notifier ) QSockNotGPollFD *sn; /* - if ( ! list ) { - // create new list, the QSockNotType destructor will delete it for us + if ( ! list ) { + // create new list, the QSockNotType destructor will delete it for us list = new QPtrList<QSockNot>; Q_CHECK_PTR( list ); list->setAutoDelete( TRUE ); d->sn_list = list; - } + } */ gushort events=0; @@ -400,10 +489,10 @@ void QEventLoop::registerSocketNotifier( QSocketNotifier *notifier ) break; } - sn = new QSockNotGPollFD; - Q_CHECK_PTR( sn ); - sn->obj = notifier; - sn->gPollFD.fd = sockfd; + sn = new QSockNotGPollFD; + Q_CHECK_PTR( sn ); + sn->obj = notifier; + sn->gPollFD.fd = sockfd; sn->gPollFD.events = events; sn->events = events; // save events! sn->pending = FALSE; @@ -429,21 +518,24 @@ void QEventLoop::unregisterSocketNotifier( QSocketNotifier *notifier ) printf("unregister socket notifier %d\n", sockfd); #endif - QPtrList<QSockNotGPollFD> *list = &d->sn_list; - QSockNotGPollFD *sn; - if ( ! list ) - return; - sn = list->first(); - while ( sn && !(sn->obj == notifier) ) - sn = list->next(); - if ( !sn ) // not found - return; - + QPtrList<QSockNotGPollFD> *list = &d->sn_list; + QSockNotGPollFD *sn; + if ( ! list ) { + return; + } + sn = list->first(); + while ( sn && !(sn->obj == notifier) ) { + sn = list->next(); + } + if ( !sn ) { // not found + return; + } + d->sn_pending_list.removeRef( sn ); - list->remove(); // remove notifier found above + list->remove(); // remove notifier found above g_source_remove_poll(d->gSource, &sn->gPollFD); - delete sn; // we don't autodelete - lets do it manually + delete sn; // we don't autodelete - lets do it manually } @@ -514,62 +606,95 @@ void QEventLoop::wakeUp() int QEventLoop::timeToWait() const { - timeval *tm = qt_wait_timer(); - if ( ! tm ) // no active timers - return -1; - return (tm->tv_sec*1000) + (tm->tv_usec/1000); + timeval *tm = qt_wait_timer(); + if ( !tm ) { // no active timers + return -1; + } + return (tm->tv_sec*1000) + (tm->tv_usec/1000); } int QEventLoop::activateTimers() { - if ( !timerList || !timerList->count() ) // no timers - return 0; - bool first = TRUE; - timeval currentTime; - int n_act = 0, maxCount = timerList->count(); - TimerInfo *begin = 0; - register TimerInfo *t; - - for ( ;; ) { - if ( ! maxCount-- ) - break; - getTime( currentTime ); // get current time - if ( first ) { - if ( currentTime < watchtime ) // clock was turned back - repairTimer( currentTime ); - first = FALSE; - watchtime = currentTime; + if ( !timerList || !timerList->count() ) { // no timers + return 0; } - t = timerList->first(); - if ( !t || currentTime < t->timeout ) // no timer has expired - break; - if ( ! begin ) { - begin = t; - } else if ( begin == t ) { - // avoid sending the same timer multiple times - break; - } else if ( t->interval < begin->interval || t->interval == begin->interval ) { - begin = t; +#if defined(QT_THREAD_SUPPORT) + timerListMutex->lock(); +#endif + bool first = TRUE; + timeval currentTime; + int n_act = 0, maxCount = timerList->count(); + TimerInfo *begin = 0; + register TimerInfo *t; + + for ( ;; ) { + if ( ! maxCount-- ) { + break; + } + getTime( currentTime ); // get current time + if ( first ) { + if ( currentTime < watchtime ) { // clock was turned back + repairTimer( currentTime ); + } + first = FALSE; + watchtime = currentTime; + } + t = timerList->first(); + if ( !t || currentTime < t->timeout ) { // no timer has expired + break; + } + if ( ! begin ) { + begin = t; + } + else if ( begin == t ) { + // avoid sending the same timer multiple times + break; + } + else if ( t->interval < begin->interval || t->interval == begin->interval ) { + begin = t; + } + timerList->take(); // unlink from list + t->timeout += t->interval; + if ( t->timeout < currentTime ) { + t->timeout = currentTime + t->interval; + } + insertTimer( t ); // relink timer + if ( t->interval.tv_usec > 0 || t->interval.tv_sec > 0 ) { + n_act++; + } +#if defined(QT_THREAD_SUPPORT) + timerListMutex->unlock(); +#endif + QTimerEvent e( t->id ); +#if defined(QT_THREAD_SUPPORT) + // Be careful...the current thread may not be the target object's thread! + if ((!t->obj) || (t->obj && (t->obj->contextThreadObject() == QThread::currentThreadObject()))) { + QApplication::sendEvent( t->obj, &e ); // send event + } + else { + QApplication::postEvent( t->obj, new QTimerEvent(e) ); // post event to correct thread + } +#else // defined(QT_THREAD_SUPPORT) + QApplication::sendEvent( t->obj, &e ); // send event +#endif // defined(QT_THREAD_SUPPORT) +#if defined(QT_THREAD_SUPPORT) + timerListMutex->lock(); +#endif + if ( timerList->findRef( begin ) == -1 ) { + begin = 0; + } } - timerList->take(); // unlink from list - t->timeout += t->interval; - if ( t->timeout < currentTime ) - t->timeout = currentTime + t->interval; - insertTimer( t ); // relink timer - if ( t->interval.tv_usec > 0 || t->interval.tv_sec > 0 ) - n_act++; - QTimerEvent e( t->id ); - QApplication::sendEvent( t->obj, &e ); // send event - if ( timerList->findRef( begin ) == -1 ) - begin = 0; - } - return n_act; +#if defined(QT_THREAD_SUPPORT) + timerListMutex->unlock(); +#endif + return n_act; } int QEventLoop::activateSocketNotifiers() { - if ( d->sn_pending_list.isEmpty() ) - return 0; + if ( d->sn_pending_list.isEmpty() ) { + return 0; + } // activate entries int n_act = 0; @@ -584,7 +709,17 @@ int QEventLoop::activateSocketNotifiers() printf("activate sn : send event fd=%d\n", sn->gPollFD.fd ); #endif sn->pending = FALSE; - QApplication::sendEvent( sn->obj, &event ); +#if defined(QT_THREAD_SUPPORT) + // Be careful...the current thread may not be the target object's thread! + if ((!sn->obj) || (sn->obj && (sn->obj->contextThreadObject() == QThread::currentThreadObject()))) { + QApplication::sendEvent( sn->obj, &event ); // send event + } + else { + QApplication::postEvent( sn->obj, new QEvent(event) ); // post event to correct thread + } +#else // defined(QT_THREAD_SUPPORT) + QApplication::sendEvent( sn->obj, &event ); // send event +#endif // defined(QT_THREAD_SUPPORT) n_act++; } } diff --git a/src/kernel/qeventloop_x11_glib.cpp b/src/kernel/qeventloop_x11_glib.cpp index d37fbee..5226aa9 100644 --- a/src/kernel/qeventloop_x11_glib.cpp +++ b/src/kernel/qeventloop_x11_glib.cpp @@ -484,8 +484,9 @@ bool QEventLoop::gsourceCheck(GSource *gs) { //if ( list ) { QSockNotGPollFD *sn = list->first(); while ( sn ) { - if ( sn->gPollFD.revents ) + if ( sn->gPollFD.revents ) { return TRUE; + } sn = list->next(); } //} @@ -513,7 +514,7 @@ bool QEventLoop::gsourceCheck(GSource *gs) { } // check if we have timers to activate? - timeval * tm =qt_wait_timer(); + timeval * tm = qt_wait_timer(); if (tm && (tm->tv_sec == 0 && tm->tv_usec == 0 )) { #ifdef DEBUG_QT_GLIBMAINLOOP printf("inside gsourceCheck(2) qtwaittimer!\n"); @@ -582,14 +583,18 @@ bool QEventLoop::gsourceDispatch(GSource *gs) { sn = list->next(); } // } - - nevents += activateSocketNotifiers(); + + if (QApplication::isGuiThread()) { + nevents += activateSocketNotifiers(); + } } // activate timers if ( ! ( flags & 0x08 ) ) { // 0x08 == ExcludeTimers for X11 only - nevents += activateTimers(); + if (QApplication::isGuiThread()) { + nevents += activateTimers(); + } } // return true if we handled events, false otherwise diff --git a/src/kernel/qobject.cpp b/src/kernel/qobject.cpp index 13486f4..20973c5 100644 --- a/src/kernel/qobject.cpp +++ b/src/kernel/qobject.cpp @@ -610,11 +610,13 @@ QObject::~QObject() blockSig = 0; // unblock signals to keep QGuardedPtr happy emit destroyed( this ); emit destroyed(); - if ( objname ) + if ( objname ) { delete [] (char*)objname; + } objname = 0; - if ( pendTimer ) // might be pending timers + if ( pendTimer ) { // might be pending timers qKillTimer( this ); + } QApplication::removePostedEvents( this ); if ( isTree ) { remove_tree( this ); // remove from global root list @@ -924,12 +926,17 @@ void destroyDeepCopiedQUObjectArray(QUObject* uArray) bool QObject::event( QEvent *e ) { #if defined(QT_CHECK_NULL) - if ( e == 0 ) + if ( e == 0 ) { qWarning( "QObject::event: Null events are not permitted" ); + } #endif + if ( wasDeleted ) { + return TRUE; + } if ( eventFilters ) { // try filters - if ( activate_filters(e) ) // stopped by a filter + if ( activate_filters(e) ) { // stopped by a filter return TRUE; + } } switch ( e->type() ) { diff --git a/src/tools/qglist.cpp b/src/tools/qglist.cpp index b04ac75..fb94427 100644 --- a/src/tools/qglist.cpp +++ b/src/tools/qglist.cpp @@ -43,6 +43,10 @@ #include "qdatastream.h" #include "qvaluelist.h" +#if defined(QT_THREAD_SUPPORT) + #include "qmutex.h" +#endif // defined(QT_THREAD_SUPPORT) + /*! \class QLNode qglist.h \reentrant @@ -221,6 +225,9 @@ QDataStream &QGList::write( QDataStream &s, QPtrCollection::Item ) const QGList::QGList() { +#if defined(QT_THREAD_SUPPORT) + //mutex = new QMutex(true); +#endif firstNode = lastNode = curNode = 0; // initialize list numNodes = 0; curIndex = -1; @@ -234,6 +241,9 @@ QGList::QGList() QGList::QGList( const QGList & list ) : QPtrCollection( list ) { +#if defined(QT_THREAD_SUPPORT) + //mutex = new QMutex(true); +#endif firstNode = lastNode = curNode = 0; // initialize list numNodes = 0; curIndex = -1; @@ -258,6 +268,9 @@ QGList::~QGList() // twice on the same address! This is insane but let's try not to crash // here. iterators = 0; +#if defined(QT_THREAD_SUPPORT) + //delete mutex; +#endif } @@ -290,11 +303,13 @@ QGList& QGList::operator=( const QGList &list ) bool QGList::operator==( const QGList &list ) const { - if ( count() != list.count() ) + if ( count() != list.count() ) { return FALSE; + } - if ( count() == 0 ) + if ( count() == 0 ) { return TRUE; + } QLNode *n1 = firstNode; QLNode *n2 = list.firstNode; @@ -322,8 +337,15 @@ bool QGList::operator==( const QGList &list ) const QLNode *QGList::locate( uint index ) { - if ( index == (uint)curIndex ) // current node ? +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif + if ( index == (uint)curIndex ) { // current node ? +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return curNode; + } if ( !curNode && firstNode ) { // set current node curNode = firstNode; curIndex = 0; @@ -332,13 +354,18 @@ QLNode *QGList::locate( uint index ) int distance = index - curIndex; // node distance to cur node bool forward; // direction to traverse - if ( index >= numNodes ) + if ( index >= numNodes ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return 0; + } - if ( distance < 0 ) + if ( distance < 0 ) { distance = -distance; + } if ( (uint)distance < index && (uint)distance < numNodes - index ) { - node = curNode; // start from current node + node = curNode; // start from current node forward = index > (uint)curIndex; } else if ( index < numNodes - index ) { // start from first node node = firstNode; @@ -352,13 +379,18 @@ QLNode *QGList::locate( uint index ) forward = FALSE; } if ( forward ) { // now run through nodes - while ( distance-- ) + while ( distance-- ) { node = node->next; + } } else { - while ( distance-- ) + while ( distance-- ) { node = node->prev; + } } curIndex = index; // must update index +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return curNode = node; } @@ -369,6 +401,9 @@ QLNode *QGList::locate( uint index ) void QGList::inSort( QPtrCollection::Item d ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif int index = 0; register QLNode *n = firstNode; while ( n && compareItems(n->data,d) < 0 ){ // find position in list @@ -376,6 +411,9 @@ void QGList::inSort( QPtrCollection::Item d ) index++; } insertAt( index, d ); +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif } @@ -385,6 +423,9 @@ void QGList::inSort( QPtrCollection::Item d ) void QGList::prepend( QPtrCollection::Item d ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif register QLNode *n = new QLNode( newItem(d) ); Q_CHECK_PTR( n ); n->prev = 0; @@ -395,6 +436,9 @@ void QGList::prepend( QPtrCollection::Item d ) firstNode = curNode = n; // curNode affected numNodes++; curIndex = 0; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif } @@ -404,16 +448,24 @@ void QGList::prepend( QPtrCollection::Item d ) void QGList::append( QPtrCollection::Item d ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif register QLNode *n = new QLNode( newItem(d) ); Q_CHECK_PTR( n ); n->next = 0; - if ( (n->prev = lastNode) ) // list is not empty + if ( (n->prev = lastNode) ) { // list is not empty lastNode->next = n; - else // initialize list + } + else { // initialize list firstNode = n; + } lastNode = curNode = n; // curNode affected curIndex = numNodes; numNodes++; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif } @@ -423,25 +475,43 @@ void QGList::append( QPtrCollection::Item d ) bool QGList::insertAt( uint index, QPtrCollection::Item d ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif if ( index == 0 ) { prepend( d ); +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return TRUE; - } else if ( index == numNodes ) { + } + else if ( index == numNodes ) { append( d ); +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return TRUE; } QLNode *nextNode = locate( index ); - if ( !nextNode ) + if ( !nextNode ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return FALSE; + } QLNode *prevNode = nextNode->prev; register QLNode *n = new QLNode( newItem(d) ); Q_CHECK_PTR( n ); nextNode->prev = n; + Q_ASSERT( (!((curIndex > 0) && (!prevNode))) ); prevNode->next = n; n->prev = prevNode; // link new node into list n->next = nextNode; curNode = n; // curIndex set by locate() numNodes++; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return TRUE; } @@ -452,18 +522,30 @@ bool QGList::insertAt( uint index, QPtrCollection::Item d ) void QGList::relinkNode( QLNode *n ) { - if ( n == firstNode ) // already first +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif + if ( n == firstNode ) { // already first +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return; + } curNode = n; unlink(); n->prev = 0; - if ( (n->next = firstNode) ) // list is not empty + if ( (n->next = firstNode) ) { // list is not empty firstNode->prev = n; - else // initialize list + } + else { // initialize list lastNode = n; + } firstNode = curNode = n; // curNode affected numNodes++; curIndex = 0; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif } @@ -473,8 +555,15 @@ void QGList::relinkNode( QLNode *n ) QLNode *QGList::unlink() { - if ( curNode == 0 ) // null current node +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif + if ( curNode == 0 ) { // null current node +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return 0; + } register QLNode *n = curNode; // unlink this node if ( n == firstNode ) { // removing first node ? if ( (firstNode = n->next) ) { @@ -500,9 +589,13 @@ QLNode *QGList::unlink() curIndex--; } - if ( iterators ) + if ( iterators ) { iterators->notifyRemove( n, curNode ); + } numNodes--; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return n; } @@ -513,6 +606,9 @@ QLNode *QGList::unlink() bool QGList::removeNode( QLNode *n ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif #if defined(QT_CHECK_NULL) if ( n == 0 || (n->prev && n->prev->next != n) || (n->next && n->next->prev != n) ) { @@ -526,6 +622,9 @@ bool QGList::removeNode( QLNode *n ) delete n; curNode = firstNode; curIndex = curNode ? 0 : -1; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return TRUE; } @@ -537,13 +636,27 @@ bool QGList::removeNode( QLNode *n ) bool QGList::remove( QPtrCollection::Item d ) { - if ( d && find(d) == -1 ) +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif + if ( d && find(d) == -1 ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return FALSE; + } QLNode *n = unlink(); - if ( !n ) + if ( !n ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return FALSE; + } deleteItem( n->data ); delete n; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return TRUE; } @@ -553,13 +666,27 @@ bool QGList::remove( QPtrCollection::Item d ) bool QGList::removeRef( QPtrCollection::Item d ) { - if ( findRef(d) == -1 ) +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif + if ( findRef(d) == -1 ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return FALSE; + } QLNode *n = unlink(); - if ( !n ) + if ( !n ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return FALSE; + } deleteItem( n->data ); delete n; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return TRUE; } @@ -581,13 +708,27 @@ bool QGList::removeRef( QPtrCollection::Item d ) bool QGList::removeAt( uint index ) { - if ( !locate(index) ) +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif + if ( !locate(index) ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return FALSE; + } QLNode *n = unlink(); - if ( !n ) + if ( !n ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return FALSE; + } deleteItem( n->data ); delete n; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return TRUE; } @@ -597,13 +738,23 @@ bool QGList::removeAt( uint index ) */ bool QGList::replaceAt( uint index, QPtrCollection::Item d ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif QLNode *n = locate( index ); - if ( !n ) + if ( !n ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return FALSE; + } if ( n->data != d ) { deleteItem( n->data ); n->data = newItem( d ); } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return TRUE; } @@ -615,10 +766,16 @@ bool QGList::replaceAt( uint index, QPtrCollection::Item d ) QPtrCollection::Item QGList::takeNode( QLNode *n ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif #if defined(QT_CHECK_NULL) if ( n == 0 || (n->prev && n->prev->next != n) || (n->next && n->next->prev != n) ) { qWarning( "QGList::takeNode: Corrupted node" ); +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return 0; } #endif @@ -628,6 +785,9 @@ QPtrCollection::Item QGList::takeNode( QLNode *n ) delete n; // delete the node, not data curNode = firstNode; curIndex = curNode ? 0 : -1; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return d; } @@ -637,9 +797,15 @@ QPtrCollection::Item QGList::takeNode( QLNode *n ) QPtrCollection::Item QGList::take() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif QLNode *n = unlink(); // unlink node Item d = n ? n->data : 0; delete n; // delete node, keep contents +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return d; } @@ -649,11 +815,21 @@ QPtrCollection::Item QGList::take() QPtrCollection::Item QGList::takeAt( uint index ) { - if ( !locate(index) ) +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif + if ( !locate(index) ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return 0; + } QLNode *n = unlink(); // unlink node Item d = n ? n->data : 0; delete n; // delete node, keep contents +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return d; } @@ -663,10 +839,16 @@ QPtrCollection::Item QGList::takeAt( uint index ) QPtrCollection::Item QGList::takeFirst() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif first(); QLNode *n = unlink(); // unlink node Item d = n ? n->data : 0; delete n; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return d; } @@ -676,10 +858,16 @@ QPtrCollection::Item QGList::takeFirst() QPtrCollection::Item QGList::takeLast() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif last(); QLNode *n = unlink(); // unlink node Item d = n ? n->data : 0; delete n; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return d; } @@ -690,14 +878,18 @@ QPtrCollection::Item QGList::takeLast() void QGList::clear() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif register QLNode *n = firstNode; firstNode = lastNode = curNode = 0; // initialize list numNodes = 0; curIndex = -1; - if ( iterators ) + if ( iterators ) { iterators->notifyClear( FALSE ); + } QLNode *prevNode; while ( n ) { // for all nodes ... @@ -706,6 +898,9 @@ void QGList::clear() n = n->next; delete prevNode; // deallocate node } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif } @@ -716,6 +911,9 @@ void QGList::clear() int QGList::findRef( QPtrCollection::Item d, bool fromStart ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif register QLNode *n; int index; if ( fromStart ) { // start from first node @@ -731,6 +929,9 @@ int QGList::findRef( QPtrCollection::Item d, bool fromStart ) } curNode = n; curIndex = n ? index : -1; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return curIndex; // return position of item } @@ -742,6 +943,9 @@ int QGList::findRef( QPtrCollection::Item d, bool fromStart ) int QGList::find( QPtrCollection::Item d, bool fromStart ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif register QLNode *n; int index; if ( fromStart ) { // start from first node @@ -757,6 +961,9 @@ int QGList::find( QPtrCollection::Item d, bool fromStart ) } curNode = n; curIndex = n ? index : -1; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return curIndex; // return position of item } @@ -767,6 +974,9 @@ int QGList::find( QPtrCollection::Item d, bool fromStart ) uint QGList::containsRef( QPtrCollection::Item d ) const { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif register QLNode *n = firstNode; uint count = 0; while ( n ) { // for all nodes... @@ -774,6 +984,9 @@ uint QGList::containsRef( QPtrCollection::Item d ) const count++; n = n->next; } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return count; } @@ -784,6 +997,9 @@ uint QGList::containsRef( QPtrCollection::Item d ) const uint QGList::contains( QPtrCollection::Item d ) const { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif register QLNode *n = firstNode; uint count = 0; QGList *that = (QGList*)this; // mutable for compareItems() @@ -792,6 +1008,9 @@ uint QGList::contains( QPtrCollection::Item d ) const count++; n = n->next; } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return count; } @@ -839,10 +1058,19 @@ uint QGList::contains( QPtrCollection::Item d ) const QPtrCollection::Item QGList::first() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif if ( firstNode ) { curIndex = 0; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return (curNode=firstNode)->data; } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return 0; } @@ -852,10 +1080,19 @@ QPtrCollection::Item QGList::first() QPtrCollection::Item QGList::last() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif if ( lastNode ) { curIndex = numNodes-1; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return (curNode=lastNode)->data; } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return 0; } @@ -865,15 +1102,24 @@ QPtrCollection::Item QGList::last() QPtrCollection::Item QGList::next() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif if ( curNode ) { if ( curNode->next ) { curIndex++; curNode = curNode->next; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return curNode->data; } curIndex = -1; curNode = 0; } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return 0; } @@ -883,15 +1129,24 @@ QPtrCollection::Item QGList::next() QPtrCollection::Item QGList::prev() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif if ( curNode ) { if ( curNode->prev ) { curIndex--; curNode = curNode->prev; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return curNode->data; } curIndex = -1; curNode = 0; } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return 0; } @@ -902,9 +1157,16 @@ QPtrCollection::Item QGList::prev() void QGList::toVector( QGVector *vector ) const { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif vector->clear(); - if ( !vector->resize( count() ) ) + if ( !vector->resize( count() ) ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return; + } register QLNode *n = firstNode; uint i = 0; while ( n ) { @@ -912,10 +1174,16 @@ void QGList::toVector( QGVector *vector ) const n = n->next; i++; } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif } void QGList::heapSortPushDown( QPtrCollection::Item* heap, int first, int last ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif int r = first; while( r <= last/2 ) { // Node r has only one child ? @@ -950,6 +1218,9 @@ void QGList::heapSortPushDown( QPtrCollection::Item* heap, int first, int last ) } } } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif } @@ -962,9 +1233,16 @@ void QGList::heapSortPushDown( QPtrCollection::Item* heap, int first, int last ) void QGList::sort() { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif uint n = count(); - if ( n < 2 ) + if ( n < 2 ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return; + } // Create the heap QPtrCollection::Item* realheap = new QPtrCollection::Item[ n ]; @@ -995,6 +1273,9 @@ void QGList::sort() } delete [] realheap; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif } @@ -1019,6 +1300,9 @@ QDataStream &operator<<( QDataStream &s, const QGList &list ) QDataStream &QGList::read( QDataStream &s ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif uint num; s >> num; // read number of items clear(); // clear list @@ -1042,6 +1326,9 @@ QDataStream &QGList::read( QDataStream &s ) } curNode = firstNode; curIndex = curNode ? 0 : -1; +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return s; } @@ -1051,12 +1338,18 @@ QDataStream &QGList::read( QDataStream &s ) QDataStream &QGList::write( QDataStream &s ) const { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif s << count(); // write number of items QLNode *n = firstNode; while ( n ) { // write all items write( s, n->data ); n = n->next; } +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return s; } @@ -1068,9 +1361,15 @@ QDataStream &QGList::write( QDataStream &s ) const */ QLNode* QGList::erase( QLNode* it ) { +#if defined(QT_THREAD_SUPPORT) + //mutex->lock(); +#endif QLNode* n = it; it = it->next; removeNode( n ); +#if defined(QT_THREAD_SUPPORT) + //mutex->unlock(); +#endif return it; } diff --git a/src/tools/qglist.h b/src/tools/qglist.h index fadc46c..dfacf47 100644 --- a/src/tools/qglist.h +++ b/src/tools/qglist.h @@ -59,6 +59,8 @@ private: QLNode( QPtrCollection::Item d ) { data = d; } }; +class QMutex; +class QGListPrivate; class QGListIteratorList; // internal helper class class Q_EXPORT QGList : public QPtrCollection // doubly linked generic list @@ -147,6 +149,12 @@ private: QLNode *locate( uint ); // get node at i'th pos QLNode *unlink(); // unlink node + +#if defined(QT_THREAD_SUPPORT) +// QMutex* mutex; +#endif + +// QGListPrivate* d; }; |