Fix a number of threading problems and crashes

This partially resolves Bug 1467
pull/2/head
Timothy Pearson 11 years ago
parent 7abfc2a181
commit 83d39cad27

@ -600,8 +600,9 @@ static QPostEventList *globalPostedEvents = 0; // list of posted events
uint qGlobalPostedEventsCount() uint qGlobalPostedEventsCount()
{ {
if (!globalPostedEvents) if (!globalPostedEvents) {
return 0; return 0;
}
return globalPostedEvents->count(); return globalPostedEvents->count();
} }
@ -2413,8 +2414,9 @@ void QApplication::aboutQt()
bool QApplication::notify( QObject *receiver, QEvent *e ) bool QApplication::notify( QObject *receiver, QEvent *e )
{ {
// no events are delivered after ~QApplication() has started // no events are delivered after ~QApplication() has started
if ( is_app_closing ) if ( is_app_closing ) {
return FALSE; return FALSE;
}
if ( receiver == 0 ) { // serious error if ( receiver == 0 ) { // serious error
#if defined(QT_CHECK_NULL) #if defined(QT_CHECK_NULL)
@ -2456,8 +2458,9 @@ bool QApplication::notify( QObject *receiver, QEvent *e )
} }
bool res = FALSE; bool res = FALSE;
if ( !receiver->isWidgetType() ) if ( !receiver->isWidgetType() ) {
res = internalNotify( receiver, e ); res = internalNotify( receiver, e );
}
else switch ( e->type() ) { else switch ( e->type() ) {
#ifndef QT_NO_ACCEL #ifndef QT_NO_ACCEL
case QEvent::Accel: case QEvent::Accel:
@ -2465,13 +2468,15 @@ bool QApplication::notify( QObject *receiver, QEvent *e )
QKeyEvent* key = (QKeyEvent*) e; QKeyEvent* key = (QKeyEvent*) e;
res = internalNotify( receiver, e ); res = internalNotify( receiver, e );
if ( !res && !key->isAccepted() ) if ( !res && !key->isAccepted() ) {
res = qt_dispatchAccelEvent( (QWidget*)receiver, key ); res = qt_dispatchAccelEvent( (QWidget*)receiver, key );
}
// next lines are for compatibility with Qt <= 3.0.x: old // next lines are for compatibility with Qt <= 3.0.x: old
// QAccel was listening on toplevel widgets // 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 ); res = internalNotify( ((QWidget*)receiver)->topLevelWidget(), e );
}
} }
break; break;
#endif //QT_NO_ACCEL #endif //QT_NO_ACCEL
@ -3275,8 +3280,9 @@ void QApplication::postEvent( QObject *receiver, QEvent *event )
qapp_cleanup_events.set( &globalPostedEvents ); qapp_cleanup_events.set( &globalPostedEvents );
} }
if ( !receiver->postedEvents ) if ( !receiver->postedEvents ) {
receiver->postedEvents = new QPostEventList; receiver->postedEvents = new QPostEventList;
}
QPostEventList * l = receiver->postedEvents; QPostEventList * l = receiver->postedEvents;
// if this is one of the compressible events, do compression // if this is one of the compressible events, do compression
@ -3374,8 +3380,9 @@ void QApplication::postEvent( QObject *receiver, QEvent *event )
} }
#endif #endif
if (currentEventLoop()) if (currentEventLoop()) {
currentEventLoop()->wakeUp(); currentEventLoop()->wakeUp();
}
} }
@ -3406,22 +3413,25 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type )
{ {
// Make sure the object hierarchy is stable before processing events // Make sure the object hierarchy is stable before processing events
// to avoid endless loops // to avoid endless loops
if ( receiver == 0 && event_type == 0 ) if ( receiver == 0 && event_type == 0 ) {
sendPostedEvents( 0, QEvent::ChildInserted ); sendPostedEvents( 0, QEvent::ChildInserted );
}
if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
return;
#ifdef QT_THREAD_SUPPORT #ifdef QT_THREAD_SUPPORT
QMutexLocker locker( postevent_mutex ); QMutexLocker locker( postevent_mutex );
#endif #endif
if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) {
return;
}
bool sent = TRUE; bool sent = TRUE;
while ( sent ) { while ( sent ) {
sent = FALSE; sent = FALSE;
if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) {
return; return;
}
// if we have a receiver, use the local list. Otherwise, use the // if we have a receiver, use the local list. Otherwise, use the
// global list // global list
@ -3438,7 +3448,7 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type )
|| receiver == pe->receiver ) // we send to THAT receiver || receiver == pe->receiver ) // we send to THAT receiver
&& ( event_type == 0 // we send all types && ( event_type == 0 // we send all types
|| event_type == pe->event->type() ) // we send THAT type || 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 // first, we diddle the event so that we can deliver
// it, and that noone will try to touch it later. // it, and that noone will try to touch it later.
pe->event->posted = FALSE; pe->event->posted = FALSE;
@ -3471,8 +3481,9 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type )
if ( e->type() == QEvent::Paint && r->isWidgetType() ) { if ( e->type() == QEvent::Paint && r->isWidgetType() ) {
QWidget * w = (QWidget*)r; QWidget * w = (QWidget*)r;
QPaintEvent * p = (QPaintEvent*)e; QPaintEvent * p = (QPaintEvent*)e;
if ( w->isVisible() ) if ( w->isVisible() ) {
w->repaint( p->reg, p->erase ); w->repaint( p->reg, p->erase );
}
} else { } else {
sent = TRUE; sent = TRUE;
QApplication::sendEvent( r, e ); QApplication::sendEvent( r, e );
@ -3493,10 +3504,12 @@ void QApplication::sendPostedEvents( QObject *receiver, int event_type )
if ( l == globalPostedEvents ) { if ( l == globalPostedEvents ) {
globalPostedEvents->first(); globalPostedEvents->first();
while( (pe=globalPostedEvents->current()) != 0 ) { while( (pe=globalPostedEvents->current()) != 0 ) {
if ( pe->event ) if ( pe->event ) {
globalPostedEvents->next(); globalPostedEvents->next();
else }
else {
globalPostedEvents->remove(); globalPostedEvents->remove();
}
} }
} }
} }

@ -75,8 +75,8 @@ class QSocketNotifier;
struct QSockNotGPollFD struct QSockNotGPollFD
{ {
QSocketNotifier *obj; QSocketNotifier *obj;
GPollFD gPollFD; GPollFD gPollFD;
gushort events; // save events gushort events; // save events
bool pending; bool pending;
}; };
@ -84,25 +84,10 @@ struct QSockNotGPollFD
class QEventLoopPrivate class QEventLoopPrivate
{ {
public: public:
QEventLoopPrivate() QEventLoopPrivate();
{ ~QEventLoopPrivate();
#if defined(Q_WS_X11)
xfd = -1; void reset();
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;
}
int looplevel; int looplevel;
int quitcode; int quitcode;

@ -45,6 +45,11 @@
#include "qapplication.h" #include "qapplication.h"
#include "qbitarray.h" #include "qbitarray.h"
#include "qmutex.h" #include "qmutex.h"
#if defined(QT_THREAD_SUPPORT)
#include "qthread.h"
#endif
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
@ -87,22 +92,25 @@
// //
struct TimerInfo { // internal timer info struct TimerInfo { // internal timer info
int id; // - timer identifier int id; // - timer identifier
timeval interval; // - timer interval timeval interval; // - timer interval
timeval timeout; // - when to sent event timeval timeout; // - when to sent event
QObject *obj; // - object to receive 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 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(); void cleanupTimers();
static timeval watchtime; // watch if time is turned back static timeval watchtime; // watch if time is turned back
timeval *qt_wait_timer(); timeval *qt_wait_timer();
timeval *qt_wait_timer_max = 0; timeval *qt_wait_timer_max = 0;
// //
// Internal operator functions for timevals // 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 ) static inline bool operator<( const timeval &t1, const timeval &t2 )
{ {
return t1.tv_sec < t2.tv_sec || return (t1.tv_sec < t2.tv_sec) || ((t1.tv_sec == t2.tv_sec) && (t1.tv_usec < t2.tv_usec));
(t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec);
} }
static inline bool operator==( const timeval &t1, const timeval &t2 ) 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 ) static inline timeval &operator+=( timeval &t1, const timeval &t2 )
{ {
t1.tv_sec += t2.tv_sec; t1.tv_sec += t2.tv_sec;
if ( (t1.tv_usec += t2.tv_usec) >= 1000000 ) { if ( (t1.tv_usec += t2.tv_usec) >= 1000000 ) {
t1.tv_sec++; t1.tv_sec++;
t1.tv_usec -= 1000000; t1.tv_usec -= 1000000;
} }
return t1; return t1;
} }
static inline timeval operator+( const timeval &t1, const timeval &t2 ) static inline timeval operator+( const timeval &t1, const timeval &t2 )
{ {
timeval tmp; timeval tmp;
tmp.tv_sec = t1.tv_sec + t2.tv_sec; tmp.tv_sec = t1.tv_sec + t2.tv_sec;
if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 ) { if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 ) {
tmp.tv_sec++; tmp.tv_sec++;
tmp.tv_usec -= 1000000; tmp.tv_usec -= 1000000;
} }
return tmp; return tmp;
} }
static inline timeval operator-( const timeval &t1, const timeval &t2 ) static inline timeval operator-( const timeval &t1, const timeval &t2 )
{ {
timeval tmp; timeval tmp;
tmp.tv_sec = t1.tv_sec - t2.tv_sec; tmp.tv_sec = t1.tv_sec - t2.tv_sec;
if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 ) { if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 ) {
tmp.tv_sec--; tmp.tv_sec--;
tmp.tv_usec += 1000000; tmp.tv_usec += 1000000;
} }
return tmp; return tmp;
} }
@ -159,68 +166,84 @@ static inline timeval operator-( const timeval &t1, const timeval &t2 )
static int allocTimerId() // find avail timer identifier static int allocTimerId() // find avail timer identifier
{ {
int i = timerBitVec->size()-1; int i = timerBitVec->size()-1;
while ( i >= 0 && (*timerBitVec)[i] ) while ( i >= 0 && (*timerBitVec)[i] ) {
i--; i--;
if ( i < 0 ) { }
i = timerBitVec->size(); if ( i < 0 ) {
timerBitVec->resize( 4 * i ); i = timerBitVec->size();
for( int j=timerBitVec->size()-1; j > i; j-- ) timerBitVec->resize( 4 * i );
timerBitVec->clearBit( j ); for( int j=timerBitVec->size()-1; j > i; j-- ) {
} timerBitVec->clearBit( j );
timerBitVec->setBit( i ); }
return i+1; }
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(); #if defined(QT_THREAD_SUPPORT)
int index = 0; timerListMutex->lock();
#endif
TimerInfo *t = timerList->first();
int index = 0;
#if defined(QT_DEBUG) #if defined(QT_DEBUG)
int dangerCount = 0; int dangerCount = 0;
#endif #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 defined(QT_DEBUG)
if ( t->obj == ti->obj ) if ( t->obj == ti->obj ) {
dangerCount++; dangerCount++;
}
#endif #endif
t = timerList->next(); t = timerList->next();
index++; index++;
} }
timerList->insert( index, ti ); // inserts sorted timerList->insert( index, ti ); // inserts sorted
#if defined(QT_DEBUG) #if defined(QT_DEBUG)
if ( dangerCount > 16 ) if ( dangerCount > 16 ) {
qDebug( "QObject: %d timers now exist for object %s::%s", qDebug( "QObject: %d timers now exist for object %s::%s", dangerCount, ti->obj->className(), ti->obj->name() );
dangerCount, ti->obj->className(), ti->obj->name() ); }
#endif
#if defined(QT_THREAD_SUPPORT)
timerListMutex->unlock();
#endif #endif
} }
static inline void getTime( timeval &t ) // get time of day static inline void getTime( timeval &t ) // get time of day
{ {
gettimeofday( &t, 0 ); gettimeofday( &t, 0 );
while ( t.tv_usec >= 1000000 ) { // NTP-related fix while ( t.tv_usec >= 1000000 ) { // NTP-related fix
t.tv_usec -= 1000000; t.tv_usec -= 1000000;
t.tv_sec++; t.tv_sec++;
} }
while ( t.tv_usec < 0 ) { while ( t.tv_usec < 0 ) {
if ( t.tv_sec > 0 ) { if ( t.tv_sec > 0 ) {
t.tv_usec += 1000000; t.tv_usec += 1000000;
t.tv_sec--; t.tv_sec--;
} else { }
t.tv_usec = 0; else {
break; 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; #if defined(QT_THREAD_SUPPORT)
register TimerInfo *t = timerList->first(); timerListMutex->lock();
while ( t ) { // repair all timers #endif
t->timeout = t->timeout - diff; timeval diff = watchtime - time;
t = timerList->next(); 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() timeval *qt_wait_timer()
{ {
static timeval tm; #if defined(QT_THREAD_SUPPORT)
bool first = TRUE; if (timerListMutex) timerListMutex->lock();
timeval currentTime; #endif
if ( timerList && timerList->count() ) { // there are waiting timers static timeval tm;
getTime( currentTime ); bool first = TRUE;
if ( first ) { timeval currentTime;
if ( currentTime < watchtime ) // clock was turned back if ( timerList && timerList->count() ) { // there are waiting timers
repairTimer( currentTime ); getTime( currentTime );
first = FALSE; if ( first ) {
watchtime = currentTime; 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 ( qt_wait_timer_max ) {
if ( currentTime < t->timeout ) { // time to wait tm = *qt_wait_timer_max;
tm = t->timeout - currentTime; #if defined(QT_THREAD_SUPPORT)
} else { if (timerListMutex) timerListMutex->unlock();
tm.tv_sec = 0; // no time to wait #endif
tm.tv_usec = 0; return &tm;
} }
if ( qt_wait_timer_max && *qt_wait_timer_max < tm ) #if defined(QT_THREAD_SUPPORT)
tm = *qt_wait_timer_max; if (timerListMutex) timerListMutex->unlock();
return &tm; #endif
} return 0; // no timers
if ( qt_wait_timer_max ) {
tm = *qt_wait_timer_max;
return &tm;
}
return 0; // no timers
} }
// Timer initialization // Timer initialization
static void initTimers() // initialize timers static void initTimers() // initialize timers
{ {
timerBitVec = new QBitArray( 128 ); timerBitVec = new QBitArray( 128 );
Q_CHECK_PTR( timerBitVec ); Q_CHECK_PTR( timerBitVec );
int i = timerBitVec->size(); int i = timerBitVec->size();
while( i-- > 0 ) while( i-- > 0 ) {
timerBitVec->clearBit( i ); timerBitVec->clearBit( i );
timerList = new TimerList; }
Q_CHECK_PTR( timerList ); timerList = new TimerList;
timerList->setAutoDelete( TRUE ); #if defined(QT_THREAD_SUPPORT)
gettimeofday( &watchtime, 0 ); timerListMutex = new QMutex(true);
#endif
Q_CHECK_PTR( timerList );
timerList->setAutoDelete( TRUE );
gettimeofday( &watchtime, 0 );
} }
// Timer cleanup // Timer cleanup
void cleanupTimers() void cleanupTimers()
{ {
delete timerList; delete timerList;
timerList = 0; timerList = 0;
delete timerBitVec; delete timerBitVec;
timerBitVec = 0; timerBitVec = 0;
#if defined(QT_THREAD_SUPPORT)
delete timerListMutex;
timerListMutex = 0;
#endif
} }
// Main timer functions for starting and killing timers // Main timer functions for starting and killing timers
int qStartTimer( int interval, QObject *obj ) int qStartTimer( int interval, QObject *obj )
{ {
if ( !timerList ) // initialize timer data if ( !timerList ) { // initialize timer data
initTimers(); initTimers();
int id = allocTimerId(); // get free timer id }
if ( id <= 0 || int id = allocTimerId(); // get free timer id
id > (int)timerBitVec->size() || !obj )// cannot create timer if ( (id <= 0) || (id > (int)timerBitVec->size()) || (!obj) ) { // cannot create timer
return 0; return 0;
timerBitVec->setBit( id-1 ); // set timer active }
TimerInfo *t = new TimerInfo; // create timer timerBitVec->setBit( id-1 ); // set timer active
Q_CHECK_PTR( t ); TimerInfo *t = new TimerInfo; // create timer
t->id = id; Q_CHECK_PTR( t );
t->interval.tv_sec = interval/1000; t->id = id;
t->interval.tv_usec = (interval%1000)*1000; t->interval.tv_sec = interval/1000;
timeval currentTime; t->interval.tv_usec = (interval%1000)*1000;
getTime( currentTime ); timeval currentTime;
t->timeout = currentTime + t->interval; getTime( currentTime );
t->obj = obj; t->timeout = currentTime + t->interval;
insertTimer( t ); // put timer in list t->obj = obj;
return id; insertTimer( t ); // put timer in list
return id;
} }
bool qKillTimer( int id ) bool qKillTimer( int id )
{ {
register TimerInfo *t; register TimerInfo *t;
if ( !timerList || id <= 0 || if ( (!timerList) || (id <= 0) || (id > (int)timerBitVec->size()) || (!timerBitVec->testBit( id-1 )) ) {
id > (int)timerBitVec->size() || !timerBitVec->testBit( id-1 ) ) return FALSE; // not init'd or invalid timer
return FALSE; // not init'd or invalid timer }
t = timerList->first(); #if defined(QT_THREAD_SUPPORT)
while ( t && t->id != id ) // find timer info in list timerListMutex->lock();
t = timerList->next(); #endif
if ( t ) { // id found t = timerList->first();
timerBitVec->clearBit( id-1 ); // set timer inactive while ( t && t->id != id ) { // find timer info in list
return timerList->remove(); t = timerList->next();
} }
else // id not found if ( t ) { // id found
return FALSE; 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 ) bool qKillTimer( QObject *obj )
{ {
register TimerInfo *t; register TimerInfo *t;
if ( !timerList ) // not initialized if ( !timerList ) { // not initialized
return FALSE; 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();
} }
} #if defined(QT_THREAD_SUPPORT)
return TRUE; 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 ) void QEventLoop::registerSocketNotifier( QSocketNotifier *notifier )
{ {
int sockfd = notifier->socket(); int sockfd = notifier->socket();
int type = notifier->type(); int type = notifier->type();
if ( sockfd < 0 || type < 0 || type > 2 || notifier == 0 ) { if ( sockfd < 0 || type < 0 || type > 2 || notifier == 0 ) {
@ -378,13 +467,13 @@ void QEventLoop::registerSocketNotifier( QSocketNotifier *notifier )
QSockNotGPollFD *sn; QSockNotGPollFD *sn;
/* /*
if ( ! list ) { if ( ! list ) {
// create new list, the QSockNotType destructor will delete it for us // create new list, the QSockNotType destructor will delete it for us
list = new QPtrList<QSockNot>; list = new QPtrList<QSockNot>;
Q_CHECK_PTR( list ); Q_CHECK_PTR( list );
list->setAutoDelete( TRUE ); list->setAutoDelete( TRUE );
d->sn_list = list; d->sn_list = list;
} }
*/ */
gushort events=0; gushort events=0;
@ -400,10 +489,10 @@ void QEventLoop::registerSocketNotifier( QSocketNotifier *notifier )
break; break;
} }
sn = new QSockNotGPollFD; sn = new QSockNotGPollFD;
Q_CHECK_PTR( sn ); Q_CHECK_PTR( sn );
sn->obj = notifier; sn->obj = notifier;
sn->gPollFD.fd = sockfd; sn->gPollFD.fd = sockfd;
sn->gPollFD.events = events; sn->gPollFD.events = events;
sn->events = events; // save events! sn->events = events; // save events!
sn->pending = FALSE; sn->pending = FALSE;
@ -429,21 +518,24 @@ void QEventLoop::unregisterSocketNotifier( QSocketNotifier *notifier )
printf("unregister socket notifier %d\n", sockfd); printf("unregister socket notifier %d\n", sockfd);
#endif #endif
QPtrList<QSockNotGPollFD> *list = &d->sn_list; QPtrList<QSockNotGPollFD> *list = &d->sn_list;
QSockNotGPollFD *sn; QSockNotGPollFD *sn;
if ( ! list ) if ( ! list ) {
return; return;
sn = list->first(); }
while ( sn && !(sn->obj == notifier) ) sn = list->first();
sn = list->next(); while ( sn && !(sn->obj == notifier) ) {
if ( !sn ) // not found sn = list->next();
return; }
if ( !sn ) { // not found
return;
}
d->sn_pending_list.removeRef( sn ); 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); 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 int QEventLoop::timeToWait() const
{ {
timeval *tm = qt_wait_timer(); timeval *tm = qt_wait_timer();
if ( ! tm ) // no active timers if ( !tm ) { // no active timers
return -1; return -1;
return (tm->tv_sec*1000) + (tm->tv_usec/1000); }
return (tm->tv_sec*1000) + (tm->tv_usec/1000);
} }
int QEventLoop::activateTimers() int QEventLoop::activateTimers()
{ {
if ( !timerList || !timerList->count() ) // no timers if ( !timerList || !timerList->count() ) { // no timers
return 0; 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;
} }
t = timerList->first(); #if defined(QT_THREAD_SUPPORT)
if ( !t || currentTime < t->timeout ) // no timer has expired timerListMutex->lock();
break; #endif
if ( ! begin ) { bool first = TRUE;
begin = t; timeval currentTime;
} else if ( begin == t ) { int n_act = 0, maxCount = timerList->count();
// avoid sending the same timer multiple times TimerInfo *begin = 0;
break; register TimerInfo *t;
} else if ( t->interval < begin->interval || t->interval == begin->interval ) {
begin = 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 #if defined(QT_THREAD_SUPPORT)
t->timeout += t->interval; timerListMutex->unlock();
if ( t->timeout < currentTime ) #endif
t->timeout = currentTime + t->interval; return n_act;
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;
} }
int QEventLoop::activateSocketNotifiers() int QEventLoop::activateSocketNotifiers()
{ {
if ( d->sn_pending_list.isEmpty() ) if ( d->sn_pending_list.isEmpty() ) {
return 0; return 0;
}
// activate entries // activate entries
int n_act = 0; int n_act = 0;
@ -584,7 +709,17 @@ int QEventLoop::activateSocketNotifiers()
printf("activate sn : send event fd=%d\n", sn->gPollFD.fd ); printf("activate sn : send event fd=%d\n", sn->gPollFD.fd );
#endif #endif
sn->pending = FALSE; 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++; n_act++;
} }
} }

@ -484,8 +484,9 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
//if ( list ) { //if ( list ) {
QSockNotGPollFD *sn = list->first(); QSockNotGPollFD *sn = list->first();
while ( sn ) { while ( sn ) {
if ( sn->gPollFD.revents ) if ( sn->gPollFD.revents ) {
return TRUE; return TRUE;
}
sn = list->next(); sn = list->next();
} }
//} //}
@ -513,7 +514,7 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
} }
// check if we have timers to activate? // 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 )) { if (tm && (tm->tv_sec == 0 && tm->tv_usec == 0 )) {
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) qtwaittimer!\n"); printf("inside gsourceCheck(2) qtwaittimer!\n");
@ -582,14 +583,18 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
sn = list->next(); sn = list->next();
} }
// } // }
nevents += activateSocketNotifiers(); if (QApplication::isGuiThread()) {
nevents += activateSocketNotifiers();
}
} }
// activate timers // activate timers
if ( ! ( flags & 0x08 ) ) { if ( ! ( flags & 0x08 ) ) {
// 0x08 == ExcludeTimers for X11 only // 0x08 == ExcludeTimers for X11 only
nevents += activateTimers(); if (QApplication::isGuiThread()) {
nevents += activateTimers();
}
} }
// return true if we handled events, false otherwise // return true if we handled events, false otherwise

@ -610,11 +610,13 @@ QObject::~QObject()
blockSig = 0; // unblock signals to keep QGuardedPtr happy blockSig = 0; // unblock signals to keep QGuardedPtr happy
emit destroyed( this ); emit destroyed( this );
emit destroyed(); emit destroyed();
if ( objname ) if ( objname ) {
delete [] (char*)objname; delete [] (char*)objname;
}
objname = 0; objname = 0;
if ( pendTimer ) // might be pending timers if ( pendTimer ) { // might be pending timers
qKillTimer( this ); qKillTimer( this );
}
QApplication::removePostedEvents( this ); QApplication::removePostedEvents( this );
if ( isTree ) { if ( isTree ) {
remove_tree( this ); // remove from global root list remove_tree( this ); // remove from global root list
@ -924,12 +926,17 @@ void destroyDeepCopiedQUObjectArray(QUObject* uArray)
bool QObject::event( QEvent *e ) bool QObject::event( QEvent *e )
{ {
#if defined(QT_CHECK_NULL) #if defined(QT_CHECK_NULL)
if ( e == 0 ) if ( e == 0 ) {
qWarning( "QObject::event: Null events are not permitted" ); qWarning( "QObject::event: Null events are not permitted" );
}
#endif #endif
if ( wasDeleted ) {
return TRUE;
}
if ( eventFilters ) { // try filters if ( eventFilters ) { // try filters
if ( activate_filters(e) ) // stopped by a filter if ( activate_filters(e) ) { // stopped by a filter
return TRUE; return TRUE;
}
} }
switch ( e->type() ) { switch ( e->type() ) {

@ -43,6 +43,10 @@
#include "qdatastream.h" #include "qdatastream.h"
#include "qvaluelist.h" #include "qvaluelist.h"
#if defined(QT_THREAD_SUPPORT)
#include "qmutex.h"
#endif // defined(QT_THREAD_SUPPORT)
/*! /*!
\class QLNode qglist.h \class QLNode qglist.h
\reentrant \reentrant
@ -221,6 +225,9 @@ QDataStream &QGList::write( QDataStream &s, QPtrCollection::Item ) const
QGList::QGList() QGList::QGList()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex = new QMutex(true);
#endif
firstNode = lastNode = curNode = 0; // initialize list firstNode = lastNode = curNode = 0; // initialize list
numNodes = 0; numNodes = 0;
curIndex = -1; curIndex = -1;
@ -234,6 +241,9 @@ QGList::QGList()
QGList::QGList( const QGList & list ) QGList::QGList( const QGList & list )
: QPtrCollection( list ) : QPtrCollection( list )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex = new QMutex(true);
#endif
firstNode = lastNode = curNode = 0; // initialize list firstNode = lastNode = curNode = 0; // initialize list
numNodes = 0; numNodes = 0;
curIndex = -1; curIndex = -1;
@ -258,6 +268,9 @@ QGList::~QGList()
// twice on the same address! This is insane but let's try not to crash // twice on the same address! This is insane but let's try not to crash
// here. // here.
iterators = 0; 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 bool QGList::operator==( const QGList &list ) const
{ {
if ( count() != list.count() ) if ( count() != list.count() ) {
return FALSE; return FALSE;
}
if ( count() == 0 ) if ( count() == 0 ) {
return TRUE; return TRUE;
}
QLNode *n1 = firstNode; QLNode *n1 = firstNode;
QLNode *n2 = list.firstNode; QLNode *n2 = list.firstNode;
@ -322,8 +337,15 @@ bool QGList::operator==( const QGList &list ) const
QLNode *QGList::locate( uint index ) 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; return curNode;
}
if ( !curNode && firstNode ) { // set current node if ( !curNode && firstNode ) { // set current node
curNode = firstNode; curNode = firstNode;
curIndex = 0; curIndex = 0;
@ -332,13 +354,18 @@ QLNode *QGList::locate( uint index )
int distance = index - curIndex; // node distance to cur node int distance = index - curIndex; // node distance to cur node
bool forward; // direction to traverse bool forward; // direction to traverse
if ( index >= numNodes ) if ( index >= numNodes ) {
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return 0; return 0;
}
if ( distance < 0 ) if ( distance < 0 ) {
distance = -distance; distance = -distance;
}
if ( (uint)distance < index && (uint)distance < numNodes - index ) { if ( (uint)distance < index && (uint)distance < numNodes - index ) {
node = curNode; // start from current node node = curNode; // start from current node
forward = index > (uint)curIndex; forward = index > (uint)curIndex;
} else if ( index < numNodes - index ) { // start from first node } else if ( index < numNodes - index ) { // start from first node
node = firstNode; node = firstNode;
@ -352,13 +379,18 @@ QLNode *QGList::locate( uint index )
forward = FALSE; forward = FALSE;
} }
if ( forward ) { // now run through nodes if ( forward ) { // now run through nodes
while ( distance-- ) while ( distance-- ) {
node = node->next; node = node->next;
}
} else { } else {
while ( distance-- ) while ( distance-- ) {
node = node->prev; node = node->prev;
}
} }
curIndex = index; // must update index curIndex = index; // must update index
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return curNode = node; return curNode = node;
} }
@ -369,6 +401,9 @@ QLNode *QGList::locate( uint index )
void QGList::inSort( QPtrCollection::Item d ) void QGList::inSort( QPtrCollection::Item d )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
int index = 0; int index = 0;
register QLNode *n = firstNode; register QLNode *n = firstNode;
while ( n && compareItems(n->data,d) < 0 ){ // find position in list while ( n && compareItems(n->data,d) < 0 ){ // find position in list
@ -376,6 +411,9 @@ void QGList::inSort( QPtrCollection::Item d )
index++; index++;
} }
insertAt( index, d ); 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 ) void QGList::prepend( QPtrCollection::Item d )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
register QLNode *n = new QLNode( newItem(d) ); register QLNode *n = new QLNode( newItem(d) );
Q_CHECK_PTR( n ); Q_CHECK_PTR( n );
n->prev = 0; n->prev = 0;
@ -395,6 +436,9 @@ void QGList::prepend( QPtrCollection::Item d )
firstNode = curNode = n; // curNode affected firstNode = curNode = n; // curNode affected
numNodes++; numNodes++;
curIndex = 0; 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 ) void QGList::append( QPtrCollection::Item d )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
register QLNode *n = new QLNode( newItem(d) ); register QLNode *n = new QLNode( newItem(d) );
Q_CHECK_PTR( n ); Q_CHECK_PTR( n );
n->next = 0; n->next = 0;
if ( (n->prev = lastNode) ) // list is not empty if ( (n->prev = lastNode) ) { // list is not empty
lastNode->next = n; lastNode->next = n;
else // initialize list }
else { // initialize list
firstNode = n; firstNode = n;
}
lastNode = curNode = n; // curNode affected lastNode = curNode = n; // curNode affected
curIndex = numNodes; curIndex = numNodes;
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 ) bool QGList::insertAt( uint index, QPtrCollection::Item d )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
if ( index == 0 ) { if ( index == 0 ) {
prepend( d ); prepend( d );
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return TRUE; return TRUE;
} else if ( index == numNodes ) { }
else if ( index == numNodes ) {
append( d ); append( d );
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return TRUE; return TRUE;
} }
QLNode *nextNode = locate( index ); QLNode *nextNode = locate( index );
if ( !nextNode ) if ( !nextNode ) {
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return FALSE; return FALSE;
}
QLNode *prevNode = nextNode->prev; QLNode *prevNode = nextNode->prev;
register QLNode *n = new QLNode( newItem(d) ); register QLNode *n = new QLNode( newItem(d) );
Q_CHECK_PTR( n ); Q_CHECK_PTR( n );
nextNode->prev = n; nextNode->prev = n;
Q_ASSERT( (!((curIndex > 0) && (!prevNode))) );
prevNode->next = n; prevNode->next = n;
n->prev = prevNode; // link new node into list n->prev = prevNode; // link new node into list
n->next = nextNode; n->next = nextNode;
curNode = n; // curIndex set by locate() curNode = n; // curIndex set by locate()
numNodes++; numNodes++;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return TRUE; return TRUE;
} }
@ -452,18 +522,30 @@ bool QGList::insertAt( uint index, QPtrCollection::Item d )
void QGList::relinkNode( QLNode *n ) 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; return;
}
curNode = n; curNode = n;
unlink(); unlink();
n->prev = 0; n->prev = 0;
if ( (n->next = firstNode) ) // list is not empty if ( (n->next = firstNode) ) { // list is not empty
firstNode->prev = n; firstNode->prev = n;
else // initialize list }
else { // initialize list
lastNode = n; lastNode = n;
}
firstNode = curNode = n; // curNode affected firstNode = curNode = n; // curNode affected
numNodes++; numNodes++;
curIndex = 0; curIndex = 0;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
} }
@ -473,8 +555,15 @@ void QGList::relinkNode( QLNode *n )
QLNode *QGList::unlink() 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; return 0;
}
register QLNode *n = curNode; // unlink this node register QLNode *n = curNode; // unlink this node
if ( n == firstNode ) { // removing first node ? if ( n == firstNode ) { // removing first node ?
if ( (firstNode = n->next) ) { if ( (firstNode = n->next) ) {
@ -500,9 +589,13 @@ QLNode *QGList::unlink()
curIndex--; curIndex--;
} }
if ( iterators ) if ( iterators ) {
iterators->notifyRemove( n, curNode ); iterators->notifyRemove( n, curNode );
}
numNodes--; numNodes--;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return n; return n;
} }
@ -513,6 +606,9 @@ QLNode *QGList::unlink()
bool QGList::removeNode( QLNode *n ) bool QGList::removeNode( QLNode *n )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
#if defined(QT_CHECK_NULL) #if defined(QT_CHECK_NULL)
if ( n == 0 || (n->prev && n->prev->next != n) || if ( n == 0 || (n->prev && n->prev->next != n) ||
(n->next && n->next->prev != n) ) { (n->next && n->next->prev != n) ) {
@ -526,6 +622,9 @@ bool QGList::removeNode( QLNode *n )
delete n; delete n;
curNode = firstNode; curNode = firstNode;
curIndex = curNode ? 0 : -1; curIndex = curNode ? 0 : -1;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return TRUE; return TRUE;
} }
@ -537,13 +636,27 @@ bool QGList::removeNode( QLNode *n )
bool QGList::remove( QPtrCollection::Item d ) 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; return FALSE;
}
QLNode *n = unlink(); QLNode *n = unlink();
if ( !n ) if ( !n ) {
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return FALSE; return FALSE;
}
deleteItem( n->data ); deleteItem( n->data );
delete n; delete n;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return TRUE; return TRUE;
} }
@ -553,13 +666,27 @@ bool QGList::remove( QPtrCollection::Item d )
bool QGList::removeRef( 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; return FALSE;
}
QLNode *n = unlink(); QLNode *n = unlink();
if ( !n ) if ( !n ) {
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return FALSE; return FALSE;
}
deleteItem( n->data ); deleteItem( n->data );
delete n; delete n;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return TRUE; return TRUE;
} }
@ -581,13 +708,27 @@ bool QGList::removeRef( QPtrCollection::Item d )
bool QGList::removeAt( uint index ) 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; return FALSE;
}
QLNode *n = unlink(); QLNode *n = unlink();
if ( !n ) if ( !n ) {
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return FALSE; return FALSE;
}
deleteItem( n->data ); deleteItem( n->data );
delete n; delete n;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return TRUE; return TRUE;
} }
@ -597,13 +738,23 @@ bool QGList::removeAt( uint index )
*/ */
bool QGList::replaceAt( uint index, QPtrCollection::Item d ) bool QGList::replaceAt( uint index, QPtrCollection::Item d )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
QLNode *n = locate( index ); QLNode *n = locate( index );
if ( !n ) if ( !n ) {
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return FALSE; return FALSE;
}
if ( n->data != d ) { if ( n->data != d ) {
deleteItem( n->data ); deleteItem( n->data );
n->data = newItem( d ); n->data = newItem( d );
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return TRUE; return TRUE;
} }
@ -615,10 +766,16 @@ bool QGList::replaceAt( uint index, QPtrCollection::Item d )
QPtrCollection::Item QGList::takeNode( QLNode *n ) QPtrCollection::Item QGList::takeNode( QLNode *n )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
#if defined(QT_CHECK_NULL) #if defined(QT_CHECK_NULL)
if ( n == 0 || (n->prev && n->prev->next != n) || if ( n == 0 || (n->prev && n->prev->next != n) ||
(n->next && n->next->prev != n) ) { (n->next && n->next->prev != n) ) {
qWarning( "QGList::takeNode: Corrupted node" ); qWarning( "QGList::takeNode: Corrupted node" );
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return 0; return 0;
} }
#endif #endif
@ -628,6 +785,9 @@ QPtrCollection::Item QGList::takeNode( QLNode *n )
delete n; // delete the node, not data delete n; // delete the node, not data
curNode = firstNode; curNode = firstNode;
curIndex = curNode ? 0 : -1; curIndex = curNode ? 0 : -1;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return d; return d;
} }
@ -637,9 +797,15 @@ QPtrCollection::Item QGList::takeNode( QLNode *n )
QPtrCollection::Item QGList::take() QPtrCollection::Item QGList::take()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
QLNode *n = unlink(); // unlink node QLNode *n = unlink(); // unlink node
Item d = n ? n->data : 0; Item d = n ? n->data : 0;
delete n; // delete node, keep contents delete n; // delete node, keep contents
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return d; return d;
} }
@ -649,11 +815,21 @@ QPtrCollection::Item QGList::take()
QPtrCollection::Item QGList::takeAt( uint index ) 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; return 0;
}
QLNode *n = unlink(); // unlink node QLNode *n = unlink(); // unlink node
Item d = n ? n->data : 0; Item d = n ? n->data : 0;
delete n; // delete node, keep contents delete n; // delete node, keep contents
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return d; return d;
} }
@ -663,10 +839,16 @@ QPtrCollection::Item QGList::takeAt( uint index )
QPtrCollection::Item QGList::takeFirst() QPtrCollection::Item QGList::takeFirst()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
first(); first();
QLNode *n = unlink(); // unlink node QLNode *n = unlink(); // unlink node
Item d = n ? n->data : 0; Item d = n ? n->data : 0;
delete n; delete n;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return d; return d;
} }
@ -676,10 +858,16 @@ QPtrCollection::Item QGList::takeFirst()
QPtrCollection::Item QGList::takeLast() QPtrCollection::Item QGList::takeLast()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
last(); last();
QLNode *n = unlink(); // unlink node QLNode *n = unlink(); // unlink node
Item d = n ? n->data : 0; Item d = n ? n->data : 0;
delete n; delete n;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return d; return d;
} }
@ -690,14 +878,18 @@ QPtrCollection::Item QGList::takeLast()
void QGList::clear() void QGList::clear()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
register QLNode *n = firstNode; register QLNode *n = firstNode;
firstNode = lastNode = curNode = 0; // initialize list firstNode = lastNode = curNode = 0; // initialize list
numNodes = 0; numNodes = 0;
curIndex = -1; curIndex = -1;
if ( iterators ) if ( iterators ) {
iterators->notifyClear( FALSE ); iterators->notifyClear( FALSE );
}
QLNode *prevNode; QLNode *prevNode;
while ( n ) { // for all nodes ... while ( n ) { // for all nodes ...
@ -706,6 +898,9 @@ void QGList::clear()
n = n->next; n = n->next;
delete prevNode; // deallocate node 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 ) int QGList::findRef( QPtrCollection::Item d, bool fromStart )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
register QLNode *n; register QLNode *n;
int index; int index;
if ( fromStart ) { // start from first node if ( fromStart ) { // start from first node
@ -731,6 +929,9 @@ int QGList::findRef( QPtrCollection::Item d, bool fromStart )
} }
curNode = n; curNode = n;
curIndex = n ? index : -1; curIndex = n ? index : -1;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return curIndex; // return position of item 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 ) int QGList::find( QPtrCollection::Item d, bool fromStart )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
register QLNode *n; register QLNode *n;
int index; int index;
if ( fromStart ) { // start from first node if ( fromStart ) { // start from first node
@ -757,6 +961,9 @@ int QGList::find( QPtrCollection::Item d, bool fromStart )
} }
curNode = n; curNode = n;
curIndex = n ? index : -1; curIndex = n ? index : -1;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return curIndex; // return position of item 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 uint QGList::containsRef( QPtrCollection::Item d ) const
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
register QLNode *n = firstNode; register QLNode *n = firstNode;
uint count = 0; uint count = 0;
while ( n ) { // for all nodes... while ( n ) { // for all nodes...
@ -774,6 +984,9 @@ uint QGList::containsRef( QPtrCollection::Item d ) const
count++; count++;
n = n->next; n = n->next;
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return count; return count;
} }
@ -784,6 +997,9 @@ uint QGList::containsRef( QPtrCollection::Item d ) const
uint QGList::contains( QPtrCollection::Item d ) const uint QGList::contains( QPtrCollection::Item d ) const
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
register QLNode *n = firstNode; register QLNode *n = firstNode;
uint count = 0; uint count = 0;
QGList *that = (QGList*)this; // mutable for compareItems() QGList *that = (QGList*)this; // mutable for compareItems()
@ -792,6 +1008,9 @@ uint QGList::contains( QPtrCollection::Item d ) const
count++; count++;
n = n->next; n = n->next;
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return count; return count;
} }
@ -839,10 +1058,19 @@ uint QGList::contains( QPtrCollection::Item d ) const
QPtrCollection::Item QGList::first() QPtrCollection::Item QGList::first()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
if ( firstNode ) { if ( firstNode ) {
curIndex = 0; curIndex = 0;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return (curNode=firstNode)->data; return (curNode=firstNode)->data;
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return 0; return 0;
} }
@ -852,10 +1080,19 @@ QPtrCollection::Item QGList::first()
QPtrCollection::Item QGList::last() QPtrCollection::Item QGList::last()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
if ( lastNode ) { if ( lastNode ) {
curIndex = numNodes-1; curIndex = numNodes-1;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return (curNode=lastNode)->data; return (curNode=lastNode)->data;
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return 0; return 0;
} }
@ -865,15 +1102,24 @@ QPtrCollection::Item QGList::last()
QPtrCollection::Item QGList::next() QPtrCollection::Item QGList::next()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
if ( curNode ) { if ( curNode ) {
if ( curNode->next ) { if ( curNode->next ) {
curIndex++; curIndex++;
curNode = curNode->next; curNode = curNode->next;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return curNode->data; return curNode->data;
} }
curIndex = -1; curIndex = -1;
curNode = 0; curNode = 0;
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return 0; return 0;
} }
@ -883,15 +1129,24 @@ QPtrCollection::Item QGList::next()
QPtrCollection::Item QGList::prev() QPtrCollection::Item QGList::prev()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
if ( curNode ) { if ( curNode ) {
if ( curNode->prev ) { if ( curNode->prev ) {
curIndex--; curIndex--;
curNode = curNode->prev; curNode = curNode->prev;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return curNode->data; return curNode->data;
} }
curIndex = -1; curIndex = -1;
curNode = 0; curNode = 0;
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return 0; return 0;
} }
@ -902,9 +1157,16 @@ QPtrCollection::Item QGList::prev()
void QGList::toVector( QGVector *vector ) const void QGList::toVector( QGVector *vector ) const
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
vector->clear(); vector->clear();
if ( !vector->resize( count() ) ) if ( !vector->resize( count() ) ) {
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return; return;
}
register QLNode *n = firstNode; register QLNode *n = firstNode;
uint i = 0; uint i = 0;
while ( n ) { while ( n ) {
@ -912,10 +1174,16 @@ void QGList::toVector( QGVector *vector ) const
n = n->next; n = n->next;
i++; i++;
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
} }
void QGList::heapSortPushDown( QPtrCollection::Item* heap, int first, int last ) void QGList::heapSortPushDown( QPtrCollection::Item* heap, int first, int last )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
int r = first; int r = first;
while( r <= last/2 ) { while( r <= last/2 ) {
// Node r has only one child ? // 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() void QGList::sort()
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
uint n = count(); uint n = count();
if ( n < 2 ) if ( n < 2 ) {
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return; return;
}
// Create the heap // Create the heap
QPtrCollection::Item* realheap = new QPtrCollection::Item[ n ]; QPtrCollection::Item* realheap = new QPtrCollection::Item[ n ];
@ -995,6 +1273,9 @@ void QGList::sort()
} }
delete [] realheap; 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 ) QDataStream &QGList::read( QDataStream &s )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
uint num; uint num;
s >> num; // read number of items s >> num; // read number of items
clear(); // clear list clear(); // clear list
@ -1042,6 +1326,9 @@ QDataStream &QGList::read( QDataStream &s )
} }
curNode = firstNode; curNode = firstNode;
curIndex = curNode ? 0 : -1; curIndex = curNode ? 0 : -1;
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return s; return s;
} }
@ -1051,12 +1338,18 @@ QDataStream &QGList::read( QDataStream &s )
QDataStream &QGList::write( QDataStream &s ) const QDataStream &QGList::write( QDataStream &s ) const
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
s << count(); // write number of items s << count(); // write number of items
QLNode *n = firstNode; QLNode *n = firstNode;
while ( n ) { // write all items while ( n ) { // write all items
write( s, n->data ); write( s, n->data );
n = n->next; n = n->next;
} }
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return s; return s;
} }
@ -1068,9 +1361,15 @@ QDataStream &QGList::write( QDataStream &s ) const
*/ */
QLNode* QGList::erase( QLNode* it ) QLNode* QGList::erase( QLNode* it )
{ {
#if defined(QT_THREAD_SUPPORT)
//mutex->lock();
#endif
QLNode* n = it; QLNode* n = it;
it = it->next; it = it->next;
removeNode( n ); removeNode( n );
#if defined(QT_THREAD_SUPPORT)
//mutex->unlock();
#endif
return it; return it;
} }

@ -59,6 +59,8 @@ private:
QLNode( QPtrCollection::Item d ) { data = d; } QLNode( QPtrCollection::Item d ) { data = d; }
}; };
class QMutex;
class QGListPrivate;
class QGListIteratorList; // internal helper class class QGListIteratorList; // internal helper class
class Q_EXPORT QGList : public QPtrCollection // doubly linked generic list 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 *locate( uint ); // get node at i'th pos
QLNode *unlink(); // unlink node QLNode *unlink(); // unlink node
#if defined(QT_THREAD_SUPPORT)
// QMutex* mutex;
#endif
// QGListPrivate* d;
}; };

Loading…
Cancel
Save