diff options
-rw-r--r-- | src/kernel/ntqapplication.h | 5 | ||||
-rw-r--r-- | src/kernel/ntqobject.h | 1 | ||||
-rw-r--r-- | src/kernel/ntqobjectdefs.h | 3 | ||||
-rw-r--r-- | src/kernel/ntqstyle.h | 36 | ||||
-rw-r--r-- | src/kernel/ntqthread.h | 8 | ||||
-rw-r--r-- | src/kernel/qapplication.cpp | 142 | ||||
-rw-r--r-- | src/kernel/qeventloop_unix_glib.cpp | 82 | ||||
-rw-r--r-- | src/kernel/qeventloop_x11_glib.cpp | 4 | ||||
-rw-r--r-- | src/kernel/qobject.cpp | 199 | ||||
-rw-r--r-- | src/kernel/qstyle.cpp | 188 | ||||
-rw-r--r-- | src/kernel/qthread.cpp | 4 | ||||
-rw-r--r-- | src/kernel/qthread_unix.cpp | 40 | ||||
-rw-r--r-- | src/moc/moc.y | 5 | ||||
-rw-r--r-- | src/moc/moc_yacc.cpp | 5 | ||||
-rw-r--r-- | src/styles/qcommonstyle.cpp | 13 | ||||
-rw-r--r-- | src/tools/ntqshared.h | 1 | ||||
-rw-r--r-- | src/tools/ntqstring.h | 46 | ||||
-rw-r--r-- | src/tools/qstring.cpp | 329 | ||||
-rw-r--r-- | src/tools/qthreadinstance_p.h | 1 | ||||
-rw-r--r-- | tutorial/t15/main.cpp | 2 |
20 files changed, 914 insertions, 200 deletions
diff --git a/src/kernel/ntqapplication.h b/src/kernel/ntqapplication.h index 557658ae2..ce8aa3d83 100644 --- a/src/kernel/ntqapplication.h +++ b/src/kernel/ntqapplication.h @@ -352,11 +352,12 @@ private slots: void postIMEvent( TQObject *receiver, TQIMEvent *event ); #endif -private: +public: #ifdef QT_THREAD_SUPPORT static TQMutex *tqt_mutex; #endif // QT_THREAD_SUPPORT +private: int app_argc; char **app_argv; bool quit_now; @@ -434,6 +435,7 @@ private: friend class TQDialog; friend class TQAccelManager; friend class TQEvent; + friend class TQThread; friend class TQTranslator; friend class TQEventLoop; friend Q_EXPORT void tqt_ucm_initialize( TQApplication * ); @@ -457,6 +459,7 @@ public: static TQThread* guiThread(); #endif static bool isGuiThread(); + static void threadTerminationHandler( TQThread * ); }; inline int TQApplication::argc() const diff --git a/src/kernel/ntqobject.h b/src/kernel/ntqobject.h index 781697ceb..38ea7ba97 100644 --- a/src/kernel/ntqobject.h +++ b/src/kernel/ntqobject.h @@ -46,6 +46,7 @@ #include "ntqwindowdefs.h" #include "ntqstring.h" #include "ntqevent.h" +#include "ntqmutex.h" #include "ntqnamespace.h" #endif // QT_H diff --git a/src/kernel/ntqobjectdefs.h b/src/kernel/ntqobjectdefs.h index 11401308b..a3c2ac4da 100644 --- a/src/kernel/ntqobjectdefs.h +++ b/src/kernel/ntqobjectdefs.h @@ -157,6 +157,7 @@ class TQMetaObject; class TQSignal; class TQConnection; class TQEvent; +class TQMutex; struct TQMetaData; class TQConnectionList; class TQConnectionListIt; @@ -165,6 +166,8 @@ class TQObjectList; class TQObjectListIt; class TQMemberDict; +extern TQMutex *tqt_sharedMetaObjectMutex; + Q_EXPORT void *tqt_find_obj_child( TQObject *, const char *, const char * ); #define Q_CHILD(parent,type,name) \ ((type*)tqt_find_obj_child(parent,#type,name)) diff --git a/src/kernel/ntqstyle.h b/src/kernel/ntqstyle.h index 9121b1431..d15f52952 100644 --- a/src/kernel/ntqstyle.h +++ b/src/kernel/ntqstyle.h @@ -59,30 +59,24 @@ class TQTab; class TQListViewItem; class TQCheckListItem; -class TQStyleOption { +class Q_EXPORT TQStyleOption { public: enum StyleOptionDefault { Default }; - TQStyleOption(StyleOptionDefault=Default) : def(TRUE), tb(NULL), cli(NULL), tbh(NULL) {} - - // Note: we don't use default arguments since that is unnecessary - // initialization. - TQStyleOption(int in1) : - def(FALSE), tb(NULL), i1(in1), cli(NULL), tbh(NULL) {} - TQStyleOption(int in1, int in2) : - def(FALSE), tb(NULL), i1(in1), i2(in2), cli(NULL), tbh(NULL) {} - TQStyleOption(int in1, int in2, int in3, int in4) : - def(FALSE), tb(NULL), i1(in1), i2(in2), i3(in3), i4(in4), cli(NULL), tbh(NULL) {} - TQStyleOption(TQMenuItem* m) : def(FALSE), mi(m), tb(NULL), cli(NULL), tbh(NULL) {} - TQStyleOption(TQMenuItem* m, int in1) : def(FALSE), mi(m), tb(NULL), i1(in1), cli(NULL), tbh(NULL) {} - TQStyleOption(TQMenuItem* m, int in1, int in2) : def(FALSE), mi(m), tb(NULL), i1(in1), i2(in2), cli(NULL), tbh(NULL) {} - TQStyleOption(const TQColor& c) : def(FALSE), tb(NULL), cl(&c), cli(NULL), tbh(NULL) {} - TQStyleOption(TQTab* t) : def(FALSE), tb(t), cli(NULL), tbh(NULL) {} - TQStyleOption(TQListViewItem* i) : def(FALSE), tb(NULL), li(i), cli(NULL), tbh(NULL) {} - TQStyleOption(TQCheckListItem* i) : def(FALSE), tb(NULL), cli(i), tbh(NULL) {} - TQStyleOption(TQt::ArrowType a) : def(FALSE), tb(NULL), i1((int)a), cli(NULL), tbh(NULL) {} - TQStyleOption(const TQRect& r) : def(FALSE), tb(NULL), i1(r.x()), i2(r.y()), i3(r.width()), i4(r.height()), cli(NULL), tbh(NULL) {} - TQStyleOption(TQWidget *w) : def(FALSE), tb(NULL), cli(NULL), p1((void*)w), tbh(NULL) {} + TQStyleOption(StyleOptionDefault=Default); + TQStyleOption(int in1); + TQStyleOption(int in1, int in2); + TQStyleOption(int in1, int in2, int in3, int in4); + TQStyleOption(TQMenuItem* m); + TQStyleOption(TQMenuItem* m, int in1); + TQStyleOption(TQMenuItem* m, int in1, int in2); + TQStyleOption(const TQColor& c); + TQStyleOption(TQTab* t); + TQStyleOption(TQListViewItem* i); + TQStyleOption(TQCheckListItem* i); + TQStyleOption(TQt::ArrowType a); + TQStyleOption(const TQRect& r); + TQStyleOption(TQWidget *w); bool isDefault() const { return def; } diff --git a/src/kernel/ntqthread.h b/src/kernel/ntqthread.h index 824578c20..5a8327101 100644 --- a/src/kernel/ntqthread.h +++ b/src/kernel/ntqthread.h @@ -108,6 +108,14 @@ public: bool finished() const; bool running() const; + enum CleanupType { + CleanupNone, + CleanupMergeObjects + }; + + CleanupType cleanupType(); + void setCleanupType(CleanupType); + protected: virtual void run() = 0; diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp index 64f4dfa4b..10e25adb6 100644 --- a/src/kernel/qapplication.cpp +++ b/src/kernel/qapplication.cpp @@ -377,8 +377,13 @@ int TQApplication::composedUnicode = 0; #ifdef QT_THREAD_SUPPORT TQMutex *TQApplication::tqt_mutex = 0; -static TQMutex *postevent_mutex = 0; -static TQt::HANDLE tqt_application_thread_id = 0; +TQMutex *tqt_sharedStringMutex = 0; +Q_EXPORT TQMutex * tqt_sharedMetaObjectMutex = 0; +#ifdef QT_USE_GLIBMAINLOOP +TQMutex *tqt_timerListMutex = 0; +#endif // QT_USE_GLIBMAINLOOP +static TQMutex *postevent_mutex = 0; +static TQt::HANDLE tqt_application_thread_id = 0; Q_EXPORT TQt::HANDLE tqt_get_application_thread_id() { return tqt_application_thread_id; @@ -600,6 +605,10 @@ static TQPostEventList *globalPostedEvents = 0; // list of posted events uint qGlobalPostedEventsCount() { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( postevent_mutex ); +#endif // QT_THREAD_SUPPORT + if (!globalPostedEvents) { return 0; } @@ -1015,6 +1024,11 @@ void TQApplication::initialize( int argc, char **argv ) { #ifdef QT_THREAD_SUPPORT tqt_mutex = new TQMutex( TRUE ); + tqt_sharedStringMutex = new TQMutex( TRUE ); + tqt_sharedMetaObjectMutex = new TQMutex( TRUE ); +#ifdef QT_USE_GLIBMAINLOOP + tqt_timerListMutex = new TQMutex( TRUE ); +#endif // QT_USE_GLIBMAINLOOP postevent_mutex = new TQMutex( TRUE ); tqt_application_thread_id = TQThread::currentThread(); #endif // QT_THREAD_SUPPORT @@ -1184,6 +1198,17 @@ TQApplication::~TQApplication() session_key = 0; #endif //QT_NO_SESSIONMANAGER +#ifdef QT_THREAD_SUPPORT + delete tqt_sharedMetaObjectMutex; + tqt_sharedMetaObjectMutex = 0; + delete tqt_sharedStringMutex; + tqt_sharedStringMutex = 0; +#ifdef QT_USE_GLIBMAINLOOP + delete tqt_timerListMutex; + tqt_timerListMutex = 0; +#endif // QT_USE_GLIBMAINLOOP +#endif // QT_THREAD_SUPPORT + tqt_explicit_app_style = FALSE; tqt_app_has_font = FALSE; app_tracking = 0; @@ -2425,35 +2450,40 @@ bool TQApplication::notify( TQObject *receiver, TQEvent *e ) return FALSE; } - if ( e->type() == TQEvent::ChildRemoved && receiver->postedEvents && globalPostedEvents) { + if ( receiver && (e->type() == TQEvent::Destroy) ) { + return TRUE; + } + if ( e->type() == TQEvent::ChildRemoved && receiver->postedEvents) { #ifdef QT_THREAD_SUPPORT TQMutexLocker locker( postevent_mutex ); #endif // QT_THREAD_SUPPORT - // the TQObject destructor calls TQObject::removeChild, which calls - // TQApplication::sendEvent() directly. this can happen while the event - // loop is in the middle of posting events, and when we get here, we may - // not have any more posted events for this object. - if ( receiver->postedEvents ) { - // if this is a child remove event and the child insert - // hasn't been dispatched yet, kill that insert - TQPostEventList * l = receiver->postedEvents; - TQObject * c = ((TQChildEvent*)e)->child(); - TQPostEvent * pe; - l->first(); - while( ( pe = l->current()) != 0 ) { - if ( pe->event && pe->receiver == receiver && - pe->event->type() == TQEvent::ChildInserted && - ((TQChildEvent*)pe->event)->child() == c ) { - pe->event->posted = FALSE; - delete pe->event; - pe->event = 0; - l->remove(); - continue; + if (globalPostedEvents) { + // the TQObject destructor calls TQObject::removeChild, which calls + // TQApplication::sendEvent() directly. this can happen while the event + // loop is in the middle of posting events, and when we get here, we may + // not have any more posted events for this object. + if ( receiver->postedEvents ) { + // if this is a child remove event and the child insert + // hasn't been dispatched yet, kill that insert + TQPostEventList * l = receiver->postedEvents; + TQObject * c = ((TQChildEvent*)e)->child(); + TQPostEvent * pe; + l->first(); + while( ( pe = l->current()) != 0 ) { + if ( pe->event && pe->receiver == receiver && + pe->event->type() == TQEvent::ChildInserted && + ((TQChildEvent*)pe->event)->child() == c ) { + pe->event->posted = FALSE; + delete pe->event; + pe->event = 0; + l->remove(); + continue; + } + l->next(); + } } - l->next(); - } } } @@ -3545,8 +3575,9 @@ void TQApplication::removePostedEvents( TQObject *receiver ) void TQApplication::removePostedEvents( TQObject *receiver, int event_type ) { - if ( !receiver ) + if ( !receiver ) { return; + } #ifdef QT_THREAD_SUPPORT TQMutexLocker locker( postevent_mutex ); @@ -3556,8 +3587,9 @@ void TQApplication::removePostedEvents( TQObject *receiver, int event_type ) // happen while the event loop is in the middle of posting events, // and when we get here, we may not have any more posted events // for this object. - if ( !receiver->postedEvents ) + if ( !receiver->postedEvents ) { return; + } // iterate over the object-specifc list and delete the events. // leave the TQPostEvent objects; they'll be deleted by @@ -3596,8 +3628,13 @@ void TQApplication::removePostedEvents( TQObject *receiver, int event_type ) void TQApplication::removePostedEvent( TQEvent * event ) { - if ( !event || !event->posted ) + if ( !event || !event->posted ) { return; + } + +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( postevent_mutex ); +#endif // QT_THREAD_SUPPORT if ( !globalPostedEvents ) { #if defined(QT_DEBUG) @@ -3607,10 +3644,6 @@ void TQApplication::removePostedEvent( TQEvent * event ) #endif } -#ifdef QT_THREAD_SUPPORT - TQMutexLocker locker( postevent_mutex ); -#endif // QT_THREAD_SUPPORT - TQPostEventListIt it( *globalPostedEvents ); TQPostEvent * pe; while( (pe = it.current()) != 0 ) { @@ -3696,6 +3729,51 @@ void TQApplication::removePostedEvent( TQEvent * event ) } } +void tqThreadTerminationHandlerRecursive( TQObject* object, TQThread* originThread, TQThread* destinationThread ) { +#ifdef QT_THREAD_SUPPORT + TQThread* objectThread = object->contextThreadObject(); + if (objectThread != destinationThread) { + TQThread::CleanupType cleanupType = objectThread->cleanupType(); + if (cleanupType == TQThread::CleanupMergeObjects) { + object->moveToThread(destinationThread); + } + else if (cleanupType == TQThread::CleanupNone) { + // Do nothing +#if defined(QT_DEBUG) + tqDebug( "TQApplication::threadTerminationHandler: object %p still owned by thread %p at thread termination!", object, objectThread); +#endif // QT_DEBUG + } + else { + // Do nothing +#if defined(QT_DEBUG) + tqDebug( "TQApplication::threadTerminationHandler: invalid thread termination cleanup type %d specified", cleanupType); +#endif // QT_DEBUG + } + } + TQObjectList children = object->childrenListObject(); + TQObject *childObject; + for ( childObject = children.first(); childObject; childObject = children.next() ) { + tqThreadTerminationHandlerRecursive(childObject, originThread, destinationThread); + } +#endif // QT_THREAD_SUPPORT +} + +/*!\internal + + Migrates all objects from the specified thread in preparation + for thread destruction. + */ +void TQApplication::threadTerminationHandler( TQThread *originThread ) { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( tqt_mutex ); + TQThread* destinationThread = guiThread(); + const TQObjectList* objects = TQObject::objectTrees(); + for ( TQObjectListIt objectit( *objects ) ; *objectit; ++objectit ) { + tqThreadTerminationHandlerRecursive((*objectit), originThread, destinationThread); + } +#endif // QT_THREAD_SUPPORT +} + /*!\internal Sets the active window in reaction to a system event. Call this diff --git a/src/kernel/qeventloop_unix_glib.cpp b/src/kernel/qeventloop_unix_glib.cpp index 66bbcada0..1decd8f1b 100644 --- a/src/kernel/qeventloop_unix_glib.cpp +++ b/src/kernel/qeventloop_unix_glib.cpp @@ -55,6 +55,12 @@ #include <glib.h> +#ifdef QT_THREAD_SUPPORT +#ifdef QT_USE_GLIBMAINLOOP +extern TQMutex *tqt_timerListMutex; +#endif // QT_USE_GLIBMAINLOOP +#endif // QT_THREAD_SUPPORT + /***************************************************************************** Timer handling; UNIX has no application timer support so we'll have to make our own from scratch. @@ -102,9 +108,6 @@ typedef TQPtrList<TimerInfo> TimerList; // list of TimerInfo structs static TQBitArray *timerBitVec; // timer bit vector static TimerList *timerList = 0; // timer list -#if defined(QT_THREAD_SUPPORT) -static TQMutex *timerListMutex = 0; // timer list mutex -#endif static void initTimers(); void cleanupTimers(); @@ -184,7 +187,7 @@ static int allocTimerId() // find avail timer identifier static void insertTimer( const TimerInfo *ti ) // insert timer info into list { #if defined(QT_THREAD_SUPPORT) - timerListMutex->lock(); + tqt_timerListMutex->lock(); #endif TimerInfo *t = timerList->first(); int index = 0; @@ -207,7 +210,7 @@ static void insertTimer( const TimerInfo *ti ) // insert timer info into list } #endif #if defined(QT_THREAD_SUPPORT) - timerListMutex->unlock(); + tqt_timerListMutex->unlock(); #endif } @@ -233,7 +236,7 @@ static inline void getTime( timeval &t ) // get time of day static void repairTimer( const timeval &time ) // repair broken timer { #if defined(QT_THREAD_SUPPORT) - timerListMutex->lock(); + tqt_timerListMutex->lock(); #endif timeval diff = watchtime - time; register TimerInfo *t = timerList->first(); @@ -242,7 +245,7 @@ static void repairTimer( const timeval &time ) // repair broken timer t = timerList->next(); } #if defined(QT_THREAD_SUPPORT) - timerListMutex->unlock(); + tqt_timerListMutex->unlock(); #endif } @@ -260,7 +263,7 @@ static void repairTimer( const timeval &time ) // repair broken timer timeval *qt_wait_timer() { #if defined(QT_THREAD_SUPPORT) - if (timerListMutex) timerListMutex->lock(); + tqt_timerListMutex->lock(); #endif static timeval tm; bool first = TRUE; @@ -286,19 +289,19 @@ timeval *qt_wait_timer() tm = *qt_wait_timer_max; } #if defined(QT_THREAD_SUPPORT) - if (timerListMutex) timerListMutex->unlock(); + tqt_timerListMutex->unlock(); #endif return &tm; } if ( qt_wait_timer_max ) { tm = *qt_wait_timer_max; #if defined(QT_THREAD_SUPPORT) - if (timerListMutex) timerListMutex->unlock(); + tqt_timerListMutex->unlock(); #endif return &tm; } #if defined(QT_THREAD_SUPPORT) - if (timerListMutex) timerListMutex->unlock(); + tqt_timerListMutex->unlock(); #endif return 0; // no timers } @@ -314,7 +317,7 @@ static void initTimers() // initialize timers } timerList = new TimerList; #if defined(QT_THREAD_SUPPORT) - timerListMutex = new TQMutex(true); + tqt_timerListMutex = new TQMutex(true); #endif TQ_CHECK_PTR( timerList ); timerList->setAutoDelete( TRUE ); @@ -328,20 +331,25 @@ void cleanupTimers() 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, TQObject *obj ) { +#if defined(QT_THREAD_SUPPORT) + if (tqt_timerListMutex) tqt_timerListMutex->lock(); +#endif if ( !timerList ) { // initialize timer data initTimers(); +#if defined(QT_THREAD_SUPPORT) + if (tqt_timerListMutex) tqt_timerListMutex->lock(); +#endif } int id = allocTimerId(); // get free timer id if ( (id <= 0) || (id > (int)timerBitVec->size()) || (!obj) ) { // cannot create timer +#if defined(QT_THREAD_SUPPORT) + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); +#endif return 0; } timerBitVec->setBit( id-1 ); // set timer active @@ -355,18 +363,24 @@ int qStartTimer( int interval, TQObject *obj ) t->timeout = currentTime + t->interval; t->obj = obj; insertTimer( t ); // put timer in list +#if defined(QT_THREAD_SUPPORT) + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); +#endif return id; } bool qKillTimer( int id ) { +#if defined(QT_THREAD_SUPPORT) + if (tqt_timerListMutex) tqt_timerListMutex->lock(); +#endif 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(); + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); #endif + return FALSE; // not init'd or invalid timer + } t = timerList->first(); while ( t && t->id != id ) { // find timer info in list t = timerList->next(); @@ -376,13 +390,13 @@ bool qKillTimer( int id ) timerBitVec->clearBit( id-1 ); // set timer inactive ret = timerList->remove(); #if defined(QT_THREAD_SUPPORT) - timerListMutex->unlock(); + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); #endif return ret; } else { // id not found #if defined(QT_THREAD_SUPPORT) - timerListMutex->unlock(); + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); #endif return FALSE; } @@ -390,13 +404,16 @@ bool qKillTimer( int id ) bool qKillTimer( TQObject *obj ) { +#if defined(QT_THREAD_SUPPORT) + if (tqt_timerListMutex) tqt_timerListMutex->lock(); +#endif register TimerInfo *t; if ( !timerList ) { // not initialized - return FALSE; - } #if defined(QT_THREAD_SUPPORT) - timerListMutex->lock(); + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); #endif + return FALSE; + } t = timerList->first(); while ( t ) { // check all timers if ( t->obj == obj ) { // object found @@ -409,7 +426,7 @@ bool qKillTimer( TQObject *obj ) } } #if defined(QT_THREAD_SUPPORT) - timerListMutex->unlock(); + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); #endif return TRUE; } @@ -615,12 +632,15 @@ int TQEventLoop::timeToWait() const int TQEventLoop::activateTimers() { +#if defined(QT_THREAD_SUPPORT) + if (tqt_timerListMutex) tqt_timerListMutex->lock(); +#endif if ( !timerList || !timerList->count() ) { // no timers - return 0; - } #if defined(QT_THREAD_SUPPORT) - timerListMutex->lock(); + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); #endif + return 0; + } bool first = TRUE; timeval currentTime; int n_act = 0, maxCount = timerList->count(); @@ -663,7 +683,7 @@ int TQEventLoop::activateTimers() n_act++; } #if defined(QT_THREAD_SUPPORT) - timerListMutex->unlock(); + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); #endif TQTimerEvent e( t->id ); #if defined(QT_THREAD_SUPPORT) @@ -678,14 +698,14 @@ int TQEventLoop::activateTimers() TQApplication::sendEvent( t->obj, &e ); // send event #endif // defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT) - timerListMutex->lock(); + if (tqt_timerListMutex) tqt_timerListMutex->lock(); #endif if ( timerList->findRef( begin ) == -1 ) { begin = 0; } } #if defined(QT_THREAD_SUPPORT) - timerListMutex->unlock(); + if (tqt_timerListMutex) tqt_timerListMutex->unlock(); #endif return n_act; } diff --git a/src/kernel/qeventloop_x11_glib.cpp b/src/kernel/qeventloop_x11_glib.cpp index f19f02f1e..df607ce78 100644 --- a/src/kernel/qeventloop_x11_glib.cpp +++ b/src/kernel/qeventloop_x11_glib.cpp @@ -629,6 +629,10 @@ bool TQEventLoop::gsourceDispatch(GSource *gs) { bool TQEventLoop::hasPendingEvents() const { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( TQApplication::tqt_mutex ); +#endif // QT_THREAD_SUPPORT + extern uint qGlobalPostedEventsCount(); // from qapplication.cpp return ( qGlobalPostedEventsCount() || ( (tqt_is_gui_used && TQApplication::isGuiThread()) ? XPending( TQPaintDevice::x11AppDisplay() ) : 0)); } diff --git a/src/kernel/qobject.cpp b/src/kernel/qobject.cpp index 2e3843761..d8b2047a0 100644 --- a/src/kernel/qobject.cpp +++ b/src/kernel/qobject.cpp @@ -73,6 +73,8 @@ public: } #endif TQThread* ownThread; + TQMutex* senderObjectListMutex; + TQMutex* childObjectListMutex; bool disableThreadPostedEvents; }; @@ -83,6 +85,10 @@ void TQObject::moveToThread_helper(TQThread *targetThread) TQEvent e(TQEvent::ThreadChange); TQApplication::sendEvent(this, &e); +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( d->childObjectListMutex ); +#endif // QT_THREAD_SUPPORT + if (childObjects) { TQObject *child; TQObjectListIt it(*childObjects); @@ -97,12 +103,16 @@ void TQObject::setThreadObject_helper(TQThread *targetThread) { d->ownThread = targetThread; +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( d->childObjectListMutex ); +#endif // QT_THREAD_SUPPORT + if (childObjects) { TQObject *child; TQObjectListIt it(*childObjects); while ( (child=it.current()) ) { ++it; - child->moveToThread_helper(targetThread); + child->setThreadObject_helper(targetThread); } } } @@ -123,7 +133,9 @@ void TQObject::setThreadObject_helper(TQThread *targetThread) */ void TQObject::moveToThread(TQThread *targetThread) { +#ifdef QT_THREAD_SUPPORT TQMutexLocker locker( TQApplication::tqt_mutex ); +#endif // QT_THREAD_SUPPORT if (parentObj) { #if defined(QT_DEBUG) @@ -179,11 +191,23 @@ void TQObject::disableThreadPostedEvents(bool disable) { class TQSenderObjectList : public TQObjectList, public TQShared { -public: - TQSenderObjectList() : currentSender( 0 ) { } - TQObject *currentSender; + public: + TQSenderObjectList(); + ~TQSenderObjectList(); + + public: + TQObject *currentSender; + TQMutex *listMutex; }; +TQSenderObjectList::TQSenderObjectList() : currentSender( 0 ) { + listMutex = new TQMutex( TRUE ); +} + +TQSenderObjectList::~TQSenderObjectList() { + delete listMutex; +} + class Q_EXPORT TQMetaCallEvent : public TQEvent { public: @@ -369,8 +393,9 @@ bool qKillTimer( TQObject *obj ); static void removeObjFromList( TQObjectList *objList, const TQObject *obj, bool single=FALSE ) { - if ( !objList ) + if ( !objList ) { return; + } int index = objList->findRef( obj ); while ( index >= 0 ) { objList->remove(); @@ -585,20 +610,25 @@ TQObject::TQObject( TQObject *parent, const char *name ) postedEvents( 0 ), // no events posted d( 0 ) { - if ( !metaObj ) // will create object dict + if ( !d ) { + d = new TQObjectPrivate(0); + } + + d->ownThread = TQThread::currentThreadObject(); + d->senderObjectListMutex = new TQMutex( TRUE ); + d->childObjectListMutex = new TQMutex( TRUE ); + + if ( !metaObj ) { // will create object dict (void) staticMetaObject(); + } if ( parent ) { // add object to parent parent->insertChild( this ); - } else { + } + else { insert_tree( this ); isTree = TRUE; } - - if ( !d ) - d = new TQObjectPrivate(0); - - d->ownThread = TQThread::currentThreadObject(); } @@ -630,10 +660,15 @@ TQObject::~TQObject() #endif return; } + if (tqApp) { + TQEvent destroyEvent(TQEvent::Destroy); + tqApp->notify(this, &destroyEvent); + } wasDeleted = 1; blockSig = 0; // unblock signals to keep TQGuardedPtr happy emit destroyed( this ); emit destroyed(); + if ( objname ) { delete [] (char*)objname; } @@ -669,8 +704,9 @@ TQObject::~TQObject() TQConnectionListIt cit(*clist); while( (c=cit.current()) ) { // for each connected slot... ++cit; - if ( (obj=c->object()) ) + if ( (obj=c->object()) ) { removeObjFromList( obj->senderObjects, this ); + } } } delete connections; @@ -691,6 +727,11 @@ TQObject::~TQObject() delete childObjects; } +#ifdef QT_THREAD_SUPPORT + delete d->childObjectListMutex; + delete d->senderObjectListMutex; +#endif // QT_THREAD_SUPPORT + delete d; } @@ -985,11 +1026,17 @@ bool TQObject::event( TQEvent *e ) TQSenderObjectList* sol; TQObject* oldSender = 0; sol = senderObjects; +#ifdef QT_THREAD_SUPPORT + sol->listMutex->lock(); +#endif // QT_THREAD_SUPPORT if ( sol ) { oldSender = sol->currentSender; sol->ref(); sol->currentSender = metaEvent->sender(); } +#ifdef QT_THREAD_SUPPORT + sol->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT TQUObject *o = metaEvent->data(); if (metaEvent->type() == TQMetaCallEvent::MetaCallEmit) { tqt_emit( metaEvent->id(), o ); @@ -997,12 +1044,20 @@ bool TQObject::event( TQEvent *e ) if (metaEvent->type() == TQMetaCallEvent::MetaCallInvoke) { tqt_invoke( metaEvent->id(), o ); } +#ifdef QT_THREAD_SUPPORT + sol->listMutex->lock(); +#endif // QT_THREAD_SUPPORT if (sol ) { sol->currentSender = oldSender; if ( sol->deref() ) { + sol->listMutex->unlock(); delete sol; + sol = NULL; } } +#ifdef QT_THREAD_SUPPORT + if (sol) sol->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT } else { tqWarning("TQObject: Ignoring metacall event from non-owning thread"); @@ -1509,6 +1564,10 @@ TQConnectionList *TQObject::receivers( int signal ) const void TQObject::insertChild( TQObject *obj ) { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( d->childObjectListMutex ); +#endif // QT_THREAD_SUPPORT + if ( obj->isTree ) { remove_tree( obj ); obj->isTree = FALSE; @@ -1551,6 +1610,10 @@ void TQObject::insertChild( TQObject *obj ) void TQObject::removeChild( TQObject *obj ) { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( d->childObjectListMutex ); +#endif // QT_THREAD_SUPPORT + if ( childObjects && childObjects->removeRef(obj) ) { obj->parentObj = 0; if ( !obj->wasDeleted ) { @@ -2135,9 +2198,25 @@ void TQObject::connectInternal( const TQObject *sender, int signal_index, const TQConnection *c = new TQConnection( r, member_index, rm ? rm->name : "qt_invoke", membcode ); TQ_CHECK_PTR( c ); clist->append( c ); - if ( !r->senderObjects ) // create list of senders + if ( !r->senderObjects ) { // create list of senders +#ifdef QT_THREAD_SUPPORT + r->d->senderObjectListMutex->lock(); +#endif // QT_THREAD_SUPPORT r->senderObjects = new TQSenderObjectList; +#ifdef QT_THREAD_SUPPORT + r->senderObjects->listMutex->lock(); + r->d->senderObjectListMutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + else { +#ifdef QT_THREAD_SUPPORT + r->senderObjects->listMutex->lock(); +#endif // QT_THREAD_SUPPORT + } r->senderObjects->append( s ); // add sender to list +#ifdef QT_THREAD_SUPPORT + r->senderObjects->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT } @@ -2343,13 +2422,25 @@ bool TQObject::disconnectInternal( const TQObject *sender, int signal_index, c = clist->first(); while ( c ) { // for all receivers... if ( r == 0 ) { // remove all receivers +#ifdef QT_THREAD_SUPPORT + if (c->object()->senderObjects) c->object()->senderObjects->listMutex->lock(); +#endif // QT_THREAD_SUPPORT removeObjFromList( c->object()->senderObjects, s ); +#ifdef QT_THREAD_SUPPORT + if (c->object()->senderObjects) c->object()->senderObjects->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT success = TRUE; c = clist->next(); } else if ( r == c->object() && ( (member_index == -1) || ((member_index == c->member()) && (c->memberType() == membcode)) ) ) { +#ifdef QT_THREAD_SUPPORT + if (c->object()->senderObjects) c->object()->senderObjects->listMutex->lock(); +#endif // QT_THREAD_SUPPORT removeObjFromList( c->object()->senderObjects, s, TRUE ); +#ifdef QT_THREAD_SUPPORT + if (c->object()->senderObjects) c->object()->senderObjects->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT success = TRUE; clist->remove(); c = clist->current(); @@ -2368,13 +2459,25 @@ bool TQObject::disconnectInternal( const TQObject *sender, int signal_index, c = clist->first(); while ( c ) { // for all receivers... if ( r == 0 ) { // remove all receivers +#ifdef QT_THREAD_SUPPORT + if (c->object()->senderObjects) c->object()->senderObjects->listMutex->lock(); +#endif // QT_THREAD_SUPPORT removeObjFromList( c->object()->senderObjects, s, TRUE ); +#ifdef QT_THREAD_SUPPORT + if (c->object()->senderObjects) c->object()->senderObjects->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT success = TRUE; c = clist->next(); } else if ( r == c->object() && ( (member_index == -1) || ((member_index == c->member()) && (c->memberType() == membcode)) ) ) { +#ifdef QT_THREAD_SUPPORT + if (c->object()->senderObjects) c->object()->senderObjects->listMutex->lock(); +#endif // QT_THREAD_SUPPORT removeObjFromList( c->object()->senderObjects, s, TRUE ); +#ifdef QT_THREAD_SUPPORT + if (c->object()->senderObjects) c->object()->senderObjects->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT success = TRUE; clist->remove(); c = clist->current(); @@ -2382,8 +2485,9 @@ bool TQObject::disconnectInternal( const TQObject *sender, int signal_index, c = clist->next(); } } - if ( r == 0 ) // disconnect all receivers + if ( r == 0 ) { // disconnect all receivers s->connections->insert( signal_index, 0 ); + } } return success; } @@ -2578,11 +2682,13 @@ void TQObject::activate_signal( int signal ) } #endif - if ( !connections || signalsBlocked() || signal < 0 ) + if ( !connections || signalsBlocked() || signal < 0 ) { return; + } TQConnectionList *clist = connections->at( signal ); - if ( !clist ) + if ( !clist ) { return; + } TQUObject o[1]; o[0].isLastObject = true; activate_signal( clist, o ); @@ -2592,12 +2698,14 @@ void TQObject::activate_signal( int signal ) void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) { - if ( !clist ) + if ( !clist ) { return; + } #ifndef QT_NO_PRELIMINARY_SIGNAL_SPY - if ( tqt_preliminary_signal_spy ) + if ( tqt_preliminary_signal_spy ) { qt_spy_signal( this, connections->findRef( clist), o ); + } #endif const TQThread *currentThread = TQThread::currentThreadObject(); @@ -2610,6 +2718,9 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) c = clist->first(); object = c->object(); sol = object->senderObjects; +#ifdef QT_THREAD_SUPPORT + sol->listMutex->lock(); +#endif // QT_THREAD_SUPPORT if ( sol ) { oldSender = sol->currentSender; sol->ref(); @@ -2617,7 +2728,13 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) } if ( c->memberType() == TQSIGNAL_CODE ) { if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) { +#ifdef QT_THREAD_SUPPORT + sol->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT object->tqt_emit( c->member(), o ); +#ifdef QT_THREAD_SUPPORT + sol->listMutex->lock(); +#endif // QT_THREAD_SUPPORT } else { if (object->d->ownThread && !object->d->ownThread->finished()) { @@ -2627,7 +2744,13 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) } else { if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) { +#ifdef QT_THREAD_SUPPORT + sol->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT object->tqt_invoke( c->member(), o ); +#ifdef QT_THREAD_SUPPORT + sol->listMutex->lock(); +#endif // QT_THREAD_SUPPORT } else { if (object->d->ownThread && !object->d->ownThread->finished()) { @@ -2637,9 +2760,15 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) } if ( sol ) { sol->currentSender = oldSender; - if ( sol->deref() ) + if ( sol->deref() ) { + sol->listMutex->unlock(); delete sol; + sol = NULL; + } } +#ifdef QT_THREAD_SUPPORT + if (sol) sol->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT } else { TQConnection *cd = 0; TQConnectionListIt it(*clist); @@ -2650,6 +2779,9 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) cd = c; object = c->object(); sol = object->senderObjects; +#ifdef QT_THREAD_SUPPORT + sol->listMutex->lock(); +#endif // QT_THREAD_SUPPORT if ( sol ) { oldSender = sol->currentSender; sol->ref(); @@ -2657,7 +2789,13 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) } if ( c->memberType() == TQSIGNAL_CODE ) { if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) { +#ifdef QT_THREAD_SUPPORT + sol->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT object->tqt_emit( c->member(), o ); +#ifdef QT_THREAD_SUPPORT + sol->listMutex->lock(); +#endif // QT_THREAD_SUPPORT } else { if (object->d->ownThread && !object->d->ownThread->finished()) { @@ -2667,7 +2805,13 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) } else { if ((d->disableThreadPostedEvents) || (object->d->ownThread == currentThread)) { +#ifdef QT_THREAD_SUPPORT + sol->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT object->tqt_invoke( c->member(), o ); +#ifdef QT_THREAD_SUPPORT + sol->listMutex->lock(); +#endif // QT_THREAD_SUPPORT } else { if (object->d->ownThread && !object->d->ownThread->finished()) { @@ -2677,9 +2821,15 @@ void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o ) } if (sol ) { sol->currentSender = oldSender; - if ( sol->deref() ) + if ( sol->deref() ) { + sol->listMutex->unlock(); delete sol; + sol = NULL; + } } +#ifdef QT_THREAD_SUPPORT + if (sol) sol->listMutex->unlock(); +#endif // QT_THREAD_SUPPORT } } } @@ -2818,6 +2968,10 @@ void TQObject::dumpObjectTree() void TQObject::dumpObjectInfo() { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( d->senderObjectListMutex ); +#endif // QT_THREAD_SUPPORT + #if defined(QT_DEBUG) tqDebug( "OBJECT %s::%s", className(), name( "unnamed" ) ); int n = 0; @@ -2852,8 +3006,9 @@ void TQObject::dumpObjectInfo() sender = senderObjects->next(); } } - if ( n == 0 ) + if ( n == 0 ) { tqDebug( "\t<None>" ); + } #endif } diff --git a/src/kernel/qstyle.cpp b/src/kernel/qstyle.cpp index 845c2f150..7f239d4b6 100644 --- a/src/kernel/qstyle.cpp +++ b/src/kernel/qstyle.cpp @@ -62,6 +62,194 @@ public: } }; +TQStyleOption::TQStyleOption(StyleOptionDefault) : + def(TRUE), + tb(NULL), + i1(-1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(int in1) : + def(FALSE), + tb(NULL), + i1(in1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(int in1, int in2) : + def(FALSE), + tb(NULL), + i1(in1), + i2(in2), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(int in1, int in2, int in3, int in4) : + def(FALSE), + tb(NULL), + i1(in1), + i2(in2), + i3(in3), + i4(in4), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(TQMenuItem* m) : + def(FALSE), + mi(m), + tb(NULL), + i1(-1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(TQMenuItem* m, int in1) : + def(FALSE), + mi(m), + tb(NULL), + i1(in1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(TQMenuItem* m, int in1, int in2) : + def(FALSE), + mi(m), + tb(NULL), + i1(in1), + i2(in2), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(const TQColor& c) : + def(FALSE), + tb(NULL), + cl(&c), + i1(-1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(TQTab* t) : + def(FALSE), + tb(t), + i1(-1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(TQListViewItem* i) : + def(FALSE), + tb(NULL), + li(i), + i1(-1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(TQCheckListItem* i) : + def(FALSE), + tb(NULL), + i1(-1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(i), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(TQt::ArrowType a) : + def(FALSE), + tb(NULL), + i1((int)a), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(const TQRect& r) : + def(FALSE), + tb(NULL), + i1(r.x()), + i2(r.y()), + i3(r.width()), + i4(r.height()), + i5(-1), + cli(NULL), + tbh(NULL) { + // +} + +TQStyleOption::TQStyleOption(TQWidget *w) : + def(FALSE), + tb(NULL), + i1(-1), + i2(-1), + i3(-1), + i4(-1), + i5(-1), + cli(NULL), + p1((void*)w), + tbh(NULL) { + // +} + /*! \class TQStyleOption ntqstyle.h \brief The TQStyleOption class specifies optional parameters for TQStyle functions. diff --git a/src/kernel/qthread.cpp b/src/kernel/qthread.cpp index fe03ce066..7c8820087 100644 --- a/src/kernel/qthread.cpp +++ b/src/kernel/qthread.cpp @@ -132,6 +132,10 @@ TQThread::TQThread() { +#ifdef QT_THREAD_SUPPORT + TQMutexLocker locker( TQApplication::tqt_mutex ); +#endif // QT_THREAD_SUPPORT + d = new TQThreadInstance; d->init(0); } diff --git a/src/kernel/qthread_unix.cpp b/src/kernel/qthread_unix.cpp index 0d7c657f3..13c820e23 100644 --- a/src/kernel/qthread_unix.cpp +++ b/src/kernel/qthread_unix.cpp @@ -47,6 +47,7 @@ typedef pthread_mutex_t Q_MUTEX_T; #include <private/qmutex_p.h> #include <private/qmutexpool_p.h> #include <ntqthreadstorage.h> +#include <ntqapplication.h> #include <errno.h> #include <sched.h> @@ -109,6 +110,7 @@ void TQThreadInstance::init(unsigned int stackSize) thread_id = 0; eventLoop = 0; + cleanupType = TQThread::CleanupMergeObjects; // threads have not been initialized yet, do it now if (! qt_thread_mutexpool) TQThread::initialize(); @@ -150,6 +152,8 @@ void TQThreadInstance::finish( void * ) return; } + TQApplication::threadTerminationHandler((TQThread*)d->args[0]); + TQMutexLocker locker( d->mutex() ); d->running = FALSE; d->finished = TRUE; @@ -179,7 +183,6 @@ void TQThreadInstance::terminate() pthread_cancel( thread_id ); } - /************************************************************************** ** TQThread *************************************************************************/ @@ -398,6 +401,9 @@ void TQThread::start(Priority priority) d->args[0] = this; d->args[1] = d; #if defined(QT_USE_GLIBMAINLOOP) + // The correct thread_id is set in TQThreadInstance::start using the value of d->args[1] + d->thread_id = NULL; + // Legacy glib versions require this threading system initialization call g_thread_init(NULL); @@ -408,8 +414,6 @@ void TQThread::start(Priority priority) else { ret = -1; } - // The correct thread_id is set in TQThreadInstance::start using the value of d->args[1] - d->thread_id = NULL; #else // QT_USE_GLIBMAINLOOP ret = pthread_create( &d->thread_id, &attr, (TQtThreadCallback)TQThreadInstance::start, d->args ); #if defined (Q_OS_HPUX) @@ -496,6 +500,36 @@ bool TQThread::wait( unsigned long time ) } /*! + Returns the current cleanup behaviour of the thread. + + \sa setCleanupType + \sa CleanupType +*/ + +TQThread::CleanupType TQThread::cleanupType() { + return (TQThread::CleanupType)d->cleanupType; +} + +/*! + Sets the current cleanup behaviour of the thread. The default, + TQThread::CleanupMergeObjects, will merge any objects owned by this thread + with the main GUI thread when this thread is terminated. + + If faster thread termination performance is desired, TQThread::CleanupNone + may be specified instead. However, this is not recommended as any objects + owned by this thread on termination can then cause events to become "stuck" + in the global event queue, leading to high CPU usage and other undesirable + behavior. You have been warned! + + \sa cleanupType + \sa CleanupType +*/ + +void TQThread::setCleanupType(CleanupType type) { + d->cleanupType = type; +} + +/*! Returns a pointer to the currently executing TQThread. If the current thread was not started using the TQThread API, this function returns zero. diff --git a/src/moc/moc.y b/src/moc/moc.y index faa4c5243..4540262be 100644 --- a/src/moc/moc.y +++ b/src/moc/moc.y @@ -2986,7 +2986,9 @@ void generateClass() // generate C++ source code for a class // Generate staticMetaObject member function // fprintf( out, "TQMetaObject* %s::staticMetaObject()\n{\n", (const char*)qualifiedClassName() ); - fprintf( out, " if ( metaObj )\n\treturn metaObj;\n" ); + fprintf( out, " if ( metaObj ) {\n\treturn metaObj;\n}\n" ); + fprintf( out, "#ifdef QT_THREAD_SUPPORT\n if (tqt_sharedMetaObjectMutex) tqt_sharedMetaObjectMutex->lock();\n" ); + fprintf( out, " if ( metaObj ) {\n\tif (tqt_sharedMetaObjectMutex) tqt_sharedMetaObjectMutex->unlock();\n\treturn metaObj;\n }\n#endif // QT_THREAD_SUPPORT\n" ); if ( isTQObject ) fprintf( out, " TQMetaObject* parentObject = staticTQtMetaObject();\n" ); else if ( !g->superClassName.isEmpty() ) @@ -3056,6 +3058,7 @@ void generateClass() // generate C++ source code for a class // Setup cleanup handler and return meta object // fprintf( out, " cleanUp_%s.setMetaObject( metaObj );\n", cleanup.data() ); + fprintf( out, "#ifdef QT_THREAD_SUPPORT\n if (tqt_sharedMetaObjectMutex) tqt_sharedMetaObjectMutex->unlock();\n#endif // QT_THREAD_SUPPORT\n" ); fprintf( out, " return metaObj;\n}\n" ); // diff --git a/src/moc/moc_yacc.cpp b/src/moc/moc_yacc.cpp index 8f655dade..13c38b654 100644 --- a/src/moc/moc_yacc.cpp +++ b/src/moc/moc_yacc.cpp @@ -5812,7 +5812,9 @@ void generateClass() // generate C++ source code for a class // Generate staticMetaObject member function // fprintf( out, "TQMetaObject* %s::staticMetaObject()\n{\n", (const char*)qualifiedClassName() ); - fprintf( out, " if ( metaObj )\n\treturn metaObj;\n" ); + fprintf( out, " if ( metaObj ) {\n\treturn metaObj;\n}\n" ); + fprintf( out, "#ifdef QT_THREAD_SUPPORT\n if (tqt_sharedMetaObjectMutex) tqt_sharedMetaObjectMutex->lock();\n" ); + fprintf( out, " if ( metaObj ) {\n\tif (tqt_sharedMetaObjectMutex) tqt_sharedMetaObjectMutex->unlock();\n\treturn metaObj;\n }\n#endif // QT_THREAD_SUPPORT\n" ); if ( isTQObject ) fprintf( out, " TQMetaObject* parentObject = staticTQtMetaObject();\n" ); else if ( !g->superClassName.isEmpty() ) @@ -5882,6 +5884,7 @@ void generateClass() // generate C++ source code for a class // Setup cleanup handler and return meta object // fprintf( out, " cleanUp_%s.setMetaObject( metaObj );\n", cleanup.data() ); + fprintf( out, "#ifdef QT_THREAD_SUPPORT\n if (tqt_sharedMetaObjectMutex) tqt_sharedMetaObjectMutex->unlock();\n#endif // QT_THREAD_SUPPORT\n" ); fprintf( out, " return metaObj;\n}\n" ); // diff --git a/src/styles/qcommonstyle.cpp b/src/styles/qcommonstyle.cpp index ad8669827..bf8507786 100644 --- a/src/styles/qcommonstyle.cpp +++ b/src/styles/qcommonstyle.cpp @@ -42,6 +42,7 @@ #ifndef QT_NO_STYLE +#include "ntqmutex.h" #include "ntqmenubar.h" #include "ntqapplication.h" #include "ntqpainter.h" @@ -2782,6 +2783,9 @@ int TQCommonStyle::pixelMetric(PixelMetric m, const TQStyleControlElementData &c ret = TQMAX( TQFontMetrics(ceData.font).lineSpacing(), 18 ); } } + else { + ret = 0; + } break; } case PM_ScrollBarSliderMin: ret = 9; @@ -2853,12 +2857,15 @@ int TQCommonStyle::pixelMetric(PixelMetric m, const TQStyleControlElementData &c int thickness = pixelMetric( PM_SliderControlThickness, ceData, elementFlags, widget ); int ticks = ceData.tickMarkSetting; - if ( ticks == TQSlider::Both ) + if ( ticks == TQSlider::Both ) { ret = (space - thickness) / 2; - else if ( ticks == TQSlider::Above ) + } + else if ( ticks == TQSlider::Above ) { ret = space - thickness; - else + } + else { ret = 0; + } break; } diff --git a/src/tools/ntqshared.h b/src/tools/ntqshared.h index 7f02c772a..a556ac200 100644 --- a/src/tools/ntqshared.h +++ b/src/tools/ntqshared.h @@ -45,7 +45,6 @@ #include "ntqglobal.h" #endif // QT_H - struct Q_EXPORT TQShared { TQShared() : count( 1 ) { } diff --git a/src/tools/ntqstring.h b/src/tools/ntqstring.h index b91caf83c..4d473e016 100644 --- a/src/tools/ntqstring.h +++ b/src/tools/ntqstring.h @@ -71,6 +71,7 @@ class TQRegExp; class TQString; class TQCharRef; +class TQMutex; template <class T> class TQDeepCopy; class Q_EXPORT TQChar { @@ -359,22 +360,14 @@ inline bool operator>( TQChar c1, TQChar c2 ) { return !(c2>=c1); } // internal struct Q_EXPORT TQStringData : public TQShared { - TQStringData() : - TQShared(), unicode(0), ascii(0), len(0), issimpletext(TRUE), maxl(0), islatin1(FALSE), security_unpaged(FALSE) { ref(); } - TQStringData(TQChar *u, uint l, uint m) : - TQShared(), unicode(u), ascii(0), len(l), issimpletext(FALSE), maxl(m), islatin1(FALSE), security_unpaged(FALSE) { } + TQStringData(); + TQStringData(TQChar *u, uint l, uint m); ~TQStringData(); void deleteSelf(); TQChar *unicode; char *ascii; - void setDirty() { - if ( ascii ) { - delete [] ascii; - ascii = 0; - } - issimpletext = FALSE; - } + void setDirty(); #ifdef Q_OS_MAC9 uint len; #else @@ -390,6 +383,8 @@ struct Q_EXPORT TQStringData : public TQShared { bool security_unpaged : 1; + TQMutex* mutex; + private: #if defined(TQ_DISABLE_COPY) TQStringData( const TQStringData& ); @@ -646,13 +641,7 @@ public: TQChar constref(uint i) const { return at(i); } - TQChar& ref(uint i) - { // Optimized for easy-inlining by simple compilers. - if ( d->count != 1 || i >= d->len ) - subat( i ); - d->setDirty(); - return d->unicode[i]; - } + TQChar& ref(uint i); const TQChar* unicode() const { return d->unicode; } const char* ascii() const; @@ -747,7 +736,7 @@ private: friend class TQConstString; friend class TQTextStream; - TQString( TQStringData* dd, bool /* dummy */ ) : d(dd) { } + TQString( TQStringData* dd, bool /* dummy */ ); // needed for TQDeepCopy void detach(); @@ -839,25 +828,6 @@ Q_EXPORT TQDataStream &operator>>( TQDataStream &, TQString & ); TQString inline functions *****************************************************************************/ -// These two move code into makeSharedNull() and deletesData() -// to improve cache-coherence (and reduce code bloat), while -// keeping the common cases fast. -// -// No safe way to pre-init shared_null on ALL compilers/linkers. -inline TQString::TQString() : - d(shared_null ? shared_null : makeSharedNull()) -{ - d->ref(); -} -// -inline TQString::~TQString() -{ - if ( d->deref() ) { - if ( d != shared_null ) - d->deleteSelf(); - } -} - // needed for TQDeepCopy inline void TQString::detach() { real_detach(); } diff --git a/src/tools/qstring.cpp b/src/tools/qstring.cpp index a5408cac5..1ea356933 100644 --- a/src/tools/qstring.cpp +++ b/src/tools/qstring.cpp @@ -87,6 +87,12 @@ #define ULLONG_MAX TQ_UINT64_C(18446744073709551615) #endif +#ifdef QT_THREAD_SUPPORT +#include "ntqmutex.h" +#endif // QT_THREAD_SUPPORT + +extern TQMutex *tqt_sharedStringMutex; + static int ucstrcmp( const TQString &as, const TQString &bs ) { const TQChar *a = as.unicode(); @@ -1033,12 +1039,54 @@ static inline bool format(TQChar::Decomposition tag, TQString & str, } // format() #endif +TQStringData::TQStringData() : TQShared(), + unicode(0), + ascii(0), + len(0), + issimpletext(TRUE), + maxl(0), + islatin1(FALSE), + security_unpaged(FALSE) { +#ifdef QT_THREAD_SUPPORT + mutex = new TQMutex( TRUE ); + mutex->lock(); +#endif // QT_THREAD_SUPPORT + ref(); +#ifdef QT_THREAD_SUPPORT + mutex->unlock(); +#endif // QT_THREAD_SUPPORT +} + +TQStringData::TQStringData(TQChar *u, uint l, uint m) : TQShared(), + unicode(u), + ascii(0), + len(l), + issimpletext(FALSE), + maxl(m), + islatin1(FALSE), + security_unpaged(FALSE) { +#ifdef QT_THREAD_SUPPORT + mutex = new TQMutex( TRUE ); +#endif // QT_THREAD_SUPPORT +} + TQStringData::~TQStringData() { - if ( unicode ) delete[] ((char*)unicode); - if ( ascii && security_unpaged ) { - munlock(ascii, LINUX_MEMLOCK_LIMIT_BYTES); - } - if ( ascii ) delete[] ascii; + if ( unicode ) delete[] ((char*)unicode); + if ( ascii && security_unpaged ) { + munlock(ascii, LINUX_MEMLOCK_LIMIT_BYTES); + } + if ( ascii ) delete[] ascii; +#ifdef QT_THREAD_SUPPORT + if ( mutex ) delete mutex; +#endif // QT_THREAD_SUPPORT +} + +void TQStringData::setDirty() { + if ( ascii ) { + delete [] ascii; + ascii = 0; + } + issimpletext = FALSE; } /* @@ -1194,27 +1242,30 @@ TQChar* TQString::latin1ToUnicode( const char *str, uint* len, uint maxlen ) return result; } -static TQChar* internalLatin1ToUnicode( const char *str, uint* len, - uint maxlen = (uint)-1 ) +static TQChar* internalLatin1ToUnicode( const char *str, uint* len, uint maxlen = (uint)-1 ) { TQChar* result = 0; uint l = 0; if ( str ) { if ( maxlen != (uint)-1 ) { - while ( l < maxlen && str[l] ) + while ( l < maxlen && str[l] ) { l++; - } else { + } + } + else { // Faster? l = int(strlen( str )); } TQChar *uc = QT_ALLOC_QCHAR_VEC( l ); result = uc; uint i = l; - while ( i-- ) + while ( i-- ) { *uc++ = *str++; + } } - if ( len ) + if ( len ) { *len = l; + } return result; } @@ -1395,11 +1446,26 @@ QT_STATIC_CONST_IMPL TQChar TQChar::nbsp((ushort)0x00a0); TQStringData* TQString::makeSharedNull() { +#ifdef QT_THREAD_SUPPORT + if (tqt_sharedStringMutex) tqt_sharedStringMutex->lock(); +#endif // QT_THREAD_SUPPORT + + if (TQString::shared_null) { +#ifdef QT_THREAD_SUPPORT + if (tqt_sharedStringMutex) tqt_sharedStringMutex->unlock(); +#endif // QT_THREAD_SUPPORT + return TQString::shared_null; + } + TQString::shared_null = new TQStringData; #if defined( Q_OS_MAC ) || defined(Q_OS_SOLARIS) || defined(Q_OS_HPUX) || defined(Q_OS_AIX) TQString *that = const_cast<TQString *>(&TQString::null); that->d = TQString::shared_null; #endif + +#ifdef QT_THREAD_SUPPORT + if (tqt_sharedStringMutex) tqt_sharedStringMutex->unlock(); +#endif // QT_THREAD_SUPPORT return TQString::shared_null; } @@ -1412,6 +1478,24 @@ TQStringData* TQString::makeSharedNull() \sa isNull() */ +// FIXME +// Original Qt3 code stated that there is +// "No safe way to pre-init shared_null on ALL compilers/linkers" +// Is this still true? + +TQString::TQString() : + d(0) +{ + d = shared_null ? shared_null : makeSharedNull(); +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + d->ref(); +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT +} + /*! Constructs a string of length one, containing the character \a ch. */ @@ -1428,7 +1512,15 @@ TQString::TQString( TQChar ch ) TQString::TQString( const TQString &s ) : d(s.d) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + d->ref(); + +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT } /*! @@ -1451,7 +1543,13 @@ TQString::TQString( int size, bool /*dummy*/ ) d = new TQStringData( uc, 0, l ); } else { d = shared_null ? shared_null : (shared_null=new TQStringData); +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT d->ref(); +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT } } @@ -1493,11 +1591,19 @@ TQString::TQString( const TQChar* unicode, uint length ) { if ( !unicode && !length ) { d = shared_null ? shared_null : makeSharedNull(); +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT d->ref(); - } else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + else { TQChar* uc = QT_ALLOC_QCHAR_VEC( length ); - if ( unicode ) + if ( unicode ) { memcpy(uc, unicode, length*sizeof(TQChar)); + } d = new TQStringData(uc,unicode ? length : 0,length); } } @@ -1556,6 +1662,10 @@ TQString::TQString( const std::string &str ) } #endif +TQString::TQString( TQStringData* dd, bool /* dummy */ ) { + d = dd; +} + /*! \fn TQString::~TQString() @@ -1563,6 +1673,31 @@ TQString::TQString( const std::string &str ) last reference to the string. */ +TQString::~TQString() +{ +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->deref() ) { + if ( d != shared_null ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + d->deleteSelf(); + } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } +} + /*! Deallocates any space reserved solely by this TQString. @@ -1580,11 +1715,25 @@ void TQString::real_detach() void TQString::deref() { - if ( d && d->deref() ) { - if ( d != shared_null ) - delete d; - d = 0; - } + if ( d ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->deref() ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + if ( d != shared_null ) { + delete d; + } + d = 0; + } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + } } void TQStringData::deleteSelf() @@ -1624,9 +1773,16 @@ void TQStringData::deleteSelf() */ TQString &TQString::operator=( const TQString &s ) { +#ifdef QT_THREAD_SUPPORT + s.d->mutex->lock(); +#endif // QT_THREAD_SUPPORT s.d->ref(); +#ifdef QT_THREAD_SUPPORT + s.d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT deref(); d = s.d; + return *this; } @@ -1730,6 +1886,10 @@ void TQString::truncate( uint newLen ) */ void TQString::setLength( uint newLen ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->count != 1 || newLen > d->maxl || ( newLen * 4 < d->maxl && d->maxl > 4 ) ) { // detach, grow or shrink @@ -1739,12 +1899,24 @@ void TQString::setLength( uint newLen ) uint len = TQMIN( d->len, newLen ); memcpy( nd, d->unicode, sizeof(TQChar) * len ); bool unpaged = d->security_unpaged; +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT deref(); d = new TQStringData( nd, newLen, newMax ); setSecurityUnPaged(unpaged); } - } else { + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + } + else { d->len = newLen; +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT d->setDirty(); } } @@ -1830,10 +2002,21 @@ void TQString::squeeze() */ void TQString::grow( uint newLen ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->count != 1 || newLen > d->maxl ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT setLength( newLen ); - } else { + } + else { d->len = newLen; +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT d->setDirty(); } } @@ -5868,13 +6051,15 @@ static TQChar *addOne(TQChar *qch, TQString &str) */ TQString TQString::fromUtf8( const char* utf8, int len ) { - if ( !utf8 ) + if ( !utf8 ) { return TQString::null; + } int slen = 0; if (len >= 0) { - while (slen < len && utf8[slen]) + while (slen < len && utf8[slen]) { slen++; + } } else { slen = int(strlen(utf8)); } @@ -6012,10 +6197,13 @@ TQString TQString::fromLatin1( const char* chars, int len ) { uint l; TQChar *uc; - if ( len < 0 ) + if ( len < 0 ) { len = -1; + } uc = internalLatin1ToUnicode( chars, &l, len ); - return TQString( new TQStringData(uc, l, l), TRUE ); + TQString ret( new TQStringData(uc, l, l), TRUE ); + + return ret; } /*! @@ -6178,7 +6366,8 @@ TQString TQString::fromUcs2( const unsigned short *str ) length++; TQChar* uc = QT_ALLOC_QCHAR_VEC( length ); memcpy( uc, str, length*sizeof(TQChar) ); - return TQString( new TQStringData( uc, length, length ), TRUE ); + TQString ret( new TQStringData( uc, length, length ), TRUE ); + return ret; } } @@ -6225,6 +6414,25 @@ TQString TQString::fromUcs2( const unsigned short *str ) \sa constref() */ +TQChar& TQString::ref(uint i) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( (d->count != 1) || (i >= d->len) ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + subat( i ); + } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + d->setDirty(); + return d->unicode[i]; +} + /*! \fn TQChar TQString::operator[]( int ) const @@ -6300,27 +6508,48 @@ void TQString::subat( uint i ) TQString& TQString::setUnicode( const TQChar *unicode, uint len ) { - if ( len == 0 ) { // set to null string - if ( d != shared_null ) { // beware of nullstring being set to nullstring - deref(); - d = shared_null ? shared_null : makeSharedNull(); - d->ref(); + if ( len == 0 ) { // set to null string + if ( d != shared_null ) { // beware of nullstring being set to nullstring + deref(); + d = shared_null ? shared_null : makeSharedNull(); +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + d->ref(); +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } } - } else if ( d->count != 1 || len > d->maxl || - ( len * 4 < d->maxl && d->maxl > 4 ) ) { - // detach, grown or shrink - uint newMax = computeNewMax( len ); - TQChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); - if ( unicode ) - memcpy( nd, unicode, sizeof(TQChar)*len ); - deref(); - d = new TQStringData( nd, len, newMax ); - } else { - d->len = len; - d->setDirty(); - if ( unicode ) - memcpy( d->unicode, unicode, sizeof(TQChar)*len ); - } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->count != 1 || len > d->maxl || ( len * 4 < d->maxl && d->maxl > 4 ) ) { + // detach, grown or shrink + uint newMax = computeNewMax( len ); + TQChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); + if ( unicode ) { + memcpy( nd, unicode, sizeof(TQChar)*len ); + } +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + deref(); + d = new TQStringData( nd, len, newMax ); + } + else { + d->len = len; +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + d->setDirty(); + if ( unicode ) { + memcpy( d->unicode, unicode, sizeof(TQChar)*len ); + } + } + } + return *this; } @@ -7024,15 +7253,23 @@ TQConstString::TQConstString( const TQChar* unicode, uint length ) : */ TQConstString::~TQConstString() { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->count > 1 ) { TQChar* cp = QT_ALLOC_QCHAR_VEC( d->len ); memcpy( cp, d->unicode, d->len*sizeof(TQChar) ); d->unicode = cp; - } else { + } + else { d->unicode = 0; } // The original d->unicode is now unlinked. +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT } /*! diff --git a/src/tools/qthreadinstance_p.h b/src/tools/qthreadinstance_p.h index 98ef3d95b..4d5bff993 100644 --- a/src/tools/qthreadinstance_p.h +++ b/src/tools/qthreadinstance_p.h @@ -101,6 +101,7 @@ public: #endif // Q_OS_WIN32 TQEventLoop* eventLoop; + int cleanupType; }; #endif // QT_THREAD_SUPPORT diff --git a/tutorial/t15/main.cpp b/tutorial/t15/main.cpp index b20262bff..a5381e607 100644 --- a/tutorial/t15/main.cpp +++ b/tutorial/t15/main.cpp @@ -33,6 +33,8 @@ void WorkerObject::run() eventLoop->processEvents(TQEventLoop::AllEvents); } + delete t; + eventLoop->exit(0); } |