diff --git a/configure b/configure index b3aeebe5..469b920d 100755 --- a/configure +++ b/configure @@ -734,6 +734,9 @@ while [ "$#" -gt 0 ]; do glibmainloop) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_GLIBMAINLOOP="$VAL" + if [ "$VAL" = "yes" ]; then + echo "WARNING: glib main loop support is ***incomplete*** and will cause problems with threaded applications and/or those using non-standard event loops!" + fi else UNKNOWN_OPT=yes fi diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp index 6fade022..7aefd35b 100644 --- a/src/kernel/qapplication.cpp +++ b/src/kernel/qapplication.cpp @@ -2767,18 +2767,21 @@ bool TQApplication::internalNotify( TQObject *receiver, TQEvent * e) if (!handled) { #if defined(QT_THREAD_SUPPORT) - bool locked = false; + int locklevel = 0; + int llcount; if (TQApplication::tqt_mutex) { - locked = TQApplication::tqt_mutex->locked(); - } - if (locked) { - TQApplication::tqt_mutex->unlock(); + TQApplication::tqt_mutex->lock(); // 1 of 2 + locklevel = tqt_mutex->level() - 1; + for (llcount=0; llcountunlock(); + } + TQApplication::tqt_mutex->unlock(); // 2 of 2 } #endif consumed = receiver->event( e ); #if defined(QT_THREAD_SUPPORT) - if (locked) { - if (TQApplication::tqt_mutex) { + if (TQApplication::tqt_mutex) { + for (llcount=0; llcountlock(); } } diff --git a/src/kernel/qeventloop_unix_glib.cpp b/src/kernel/qeventloop_unix_glib.cpp index 9f89332e..7f1035fd 100644 --- a/src/kernel/qeventloop_unix_glib.cpp +++ b/src/kernel/qeventloop_unix_glib.cpp @@ -370,9 +370,9 @@ void TQEventLoop::registerSocketNotifier( TQSocketNotifier *notifier ) return; } - #ifdef DEBUG_QT_GLIBMAINLOOP - printf("register socket notifier %d\n", sockfd); - #endif +#ifdef DEBUG_QT_GLIBMAINLOOP + printf("register socket notifier %d\n", sockfd); +#endif TQPtrList *list = &d->sn_list; TQSockNotGPollFD *sn; @@ -425,9 +425,9 @@ void TQEventLoop::unregisterSocketNotifier( TQSocketNotifier *notifier ) return; } - #ifdef DEBUG_QT_GLIBMAINLOOP - printf("unregister socket notifier %d\n", sockfd); - #endif +#ifdef DEBUG_QT_GLIBMAINLOOP + printf("unregister socket notifier %d\n", sockfd); +#endif TQPtrList *list = &d->sn_list; TQSockNotGPollFD *sn; @@ -458,9 +458,9 @@ void TQEventLoop::setSocketNotifierPending( TQSocketNotifier *notifier ) return; } - #ifdef DEBUG_QT_GLIBMAINLOOP - printf("set socket notifier pending %d\n", sockfd); - #endif +#ifdef DEBUG_QT_GLIBMAINLOOP + printf("set socket notifier pending %d\n", sockfd); +#endif TQPtrList *list = &d->sn_list; TQSockNotGPollFD *sn; diff --git a/src/kernel/qeventloop_x11_glib.cpp b/src/kernel/qeventloop_x11_glib.cpp index bb702b82..1e457b51 100644 --- a/src/kernel/qeventloop_x11_glib.cpp +++ b/src/kernel/qeventloop_x11_glib.cpp @@ -54,6 +54,8 @@ #include +// #define DEBUG_QT_GLIBMAINLOOP 1 + // TQt-GSource Structure and Callbacks typedef struct { @@ -249,7 +251,7 @@ bool TQEventLoop::processEvents( ProcessEventsFlags flags ) d->pev_flags = flags; - rval = g_main_context_iteration(NULL, flags & WaitForMore ? TRUE : FALSE); + rval = g_main_context_iteration(NULL, flags & WaitForMore ? TRUE : FALSE); d->pev_flags = save_flags; @@ -288,38 +290,38 @@ bool TQEventLoop::processX11Events() XNextEvent( TQPaintDevice::x11AppDisplay(), &event ); if ( flags & ExcludeUserInput ) { - switch ( event.type ) { - case ButtonPress: - case ButtonRelease: - case MotionNotify: - case XKeyPress: - case XKeyRelease: - case EnterNotify: - case LeaveNotify: - continue; - - case ClientMessage: - { - // from qapplication_x11.cpp - extern Atom tqt_wm_protocols; - extern Atom tqt_wm_take_focus; - extern Atom qt_qt_scrolldone; - - // only keep the wm_take_focus and - // qt_qt_scrolldone protocols, discard all - // other client messages - if ( event.xclient.format != 32 ) + switch ( event.type ) { + case ButtonPress: + case ButtonRelease: + case MotionNotify: + case XKeyPress: + case XKeyRelease: + case EnterNotify: + case LeaveNotify: continue; - - if ( event.xclient.message_type == tqt_wm_protocols || - (Atom) event.xclient.data.l[0] == tqt_wm_take_focus ) - break; - if ( event.xclient.message_type == qt_qt_scrolldone ) - break; + + case ClientMessage: + { + // from qapplication_x11.cpp + extern Atom tqt_wm_protocols; + extern Atom tqt_wm_take_focus; + extern Atom qt_qt_scrolldone; + + // only keep the wm_take_focus and + // qt_qt_scrolldone protocols, discard all + // other client messages + if ( event.xclient.format != 32 ) + continue; + + if ( event.xclient.message_type == tqt_wm_protocols || + (Atom) event.xclient.data.l[0] == tqt_wm_take_focus ) + break; + if ( event.xclient.message_type == qt_qt_scrolldone ) + break; + } + + default: break; } - - default: break; - } } nevents++; @@ -333,7 +335,7 @@ bool TQEventLoop::processX11Events() if ( d->shortcut ) { return FALSE; } - + TQApplication::sendPostedEvents(); const uint exclude_all = ExcludeSocketNotifiers | 0x08; @@ -595,12 +597,16 @@ bool TQEventLoop::gsourceDispatch(GSource *gs) { // color approx. optimization - only on X11 qt_reset_color_avail(); +#if defined(QT_THREAD_SUPPORT) + locker.mutex()->unlock(); +#endif processX11Events(); } - + else { #if defined(QT_THREAD_SUPPORT) - locker.mutex()->unlock(); + locker.mutex()->unlock(); #endif + } if (d->singletoolkit) { return TRUE; // Eat the event diff --git a/src/tools/ntqmutex.h b/src/tools/ntqmutex.h index 2a9afb1d..7b73514d 100644 --- a/src/tools/ntqmutex.h +++ b/src/tools/ntqmutex.h @@ -74,6 +74,9 @@ private: TQMutex( const TQMutex & ); TQMutex &operator=( const TQMutex & ); #endif + +public: + int level(); }; class Q_EXPORT TQMutexLocker diff --git a/src/tools/qmutex_p.h b/src/tools/qmutex_p.h index 7650cee8..3e9de8e5 100644 --- a/src/tools/qmutex_p.h +++ b/src/tools/qmutex_p.h @@ -67,6 +67,7 @@ public: virtual bool locked() = 0; virtual bool trylock() = 0; virtual int type() const = 0; + virtual int level() = 0; }; diff --git a/src/tools/qmutex_unix.cpp b/src/tools/qmutex_unix.cpp index 7d22798c..3fff8336 100644 --- a/src/tools/qmutex_unix.cpp +++ b/src/tools/qmutex_unix.cpp @@ -85,6 +85,7 @@ public: bool locked(); bool trylock(); int type() const; + int level(); bool recursive; }; @@ -101,6 +102,7 @@ public: bool locked(); bool trylock(); int type() const; + int level(); int count; unsigned long owner; @@ -196,6 +198,11 @@ int TQRealMutexPrivate::type() const return recursive ? Q_MUTEX_RECURSIVE : Q_MUTEX_NORMAL; } +int TQRealMutexPrivate::level() +{ + return locked(); +} + #ifndef Q_RECURSIVE_MUTEX_TYPE TQRecursiveMutexPrivate::TQRecursiveMutexPrivate() @@ -329,6 +336,11 @@ int TQRecursiveMutexPrivate::type() const return Q_MUTEX_RECURSIVE; } +int TQRecursiveMutexPrivate::level() +{ + return count; +} + #endif // !Q_RECURSIVE_MUTEX_TYPE @@ -510,6 +522,22 @@ bool TQMutex::tryLock() return d->trylock(); } +/*! + Returns the current lock level of the mutex. + 0 means the mutex is unlocked + This method should only be called when the mutex has already been locked + by lock(), otherwise the lock level could change before the next line + of code is executed. + + WARNING: Non-recursive mutexes will never exceed a lock level of 1! + + \sa lock(), unlock(), locked() +*/ +int TQMutex::level() +{ + return d->level(); +} + /*! \class TQMutexLocker ntqmutex.h \brief The TQMutexLocker class simplifies locking and unlocking TQMutexes.