Add level method to recursive mutex

Enhance thread safety when making event calls
Minor cleanup of whitespace in glib event loop
pull/2/head
Timothy Pearson 12 years ago
parent 85b3c5d0ec
commit 9bff9eeefc

3
configure vendored

@ -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

@ -2767,18 +2767,21 @@ bool QApplication::internalNotify( QObject *receiver, QEvent * e)
if (!handled) {
#if defined(QT_THREAD_SUPPORT)
bool locked = false;
int locklevel = 0;
int llcount;
if (QApplication::qt_mutex) {
locked = QApplication::qt_mutex->locked();
}
if (locked) {
QApplication::qt_mutex->unlock();
QApplication::qt_mutex->lock(); // 1 of 2
locklevel = qt_mutex->level() - 1;
for (llcount=0; llcount<locklevel; llcount++) {
QApplication::qt_mutex->unlock();
}
QApplication::qt_mutex->unlock(); // 2 of 2
}
#endif
consumed = receiver->event( e );
#if defined(QT_THREAD_SUPPORT)
if (locked) {
if (QApplication::qt_mutex) {
if (QApplication::qt_mutex) {
for (llcount=0; llcount<locklevel; llcount++) {
QApplication::qt_mutex->lock();
}
}

@ -370,9 +370,9 @@ void QEventLoop::registerSocketNotifier( QSocketNotifier *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
QPtrList<QSockNotGPollFD> *list = &d->sn_list;
QSockNotGPollFD *sn;
@ -425,9 +425,9 @@ void QEventLoop::unregisterSocketNotifier( QSocketNotifier *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
QPtrList<QSockNotGPollFD> *list = &d->sn_list;
QSockNotGPollFD *sn;
@ -458,9 +458,9 @@ void QEventLoop::setSocketNotifierPending( QSocketNotifier *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
QPtrList<QSockNotGPollFD> *list = &d->sn_list;
QSockNotGPollFD *sn;

@ -54,6 +54,8 @@
#include <glib.h>
// #define DEBUG_QT_GLIBMAINLOOP 1
// Qt-GSource Structure and Callbacks
typedef struct {
@ -249,7 +251,7 @@ bool QEventLoop::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 QEventLoop::processX11Events()
XNextEvent( QPaintDevice::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 qt_wm_protocols;
extern Atom qt_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 == qt_wm_protocols ||
(Atom) event.xclient.data.l[0] == qt_wm_take_focus )
break;
if ( event.xclient.message_type == qt_qt_scrolldone )
break;
case ClientMessage:
{
// from qapplication_x11.cpp
extern Atom qt_wm_protocols;
extern Atom qt_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 == qt_wm_protocols ||
(Atom) event.xclient.data.l[0] == qt_wm_take_focus )
break;
if ( event.xclient.message_type == qt_qt_scrolldone )
break;
}
default: break;
}
default: break;
}
}
nevents++;
@ -333,7 +335,7 @@ bool QEventLoop::processX11Events()
if ( d->shortcut ) {
return FALSE;
}
QApplication::sendPostedEvents();
const uint exclude_all = ExcludeSocketNotifiers | 0x08;
@ -595,12 +597,16 @@ bool QEventLoop::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

@ -74,6 +74,9 @@ private:
QMutex( const QMutex & );
QMutex &operator=( const QMutex & );
#endif
public:
int level();
};
class Q_EXPORT QMutexLocker

@ -67,6 +67,7 @@ public:
virtual bool locked() = 0;
virtual bool trylock() = 0;
virtual int type() const = 0;
virtual int level() = 0;
};

@ -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 QRealMutexPrivate::type() const
return recursive ? Q_MUTEX_RECURSIVE : Q_MUTEX_NORMAL;
}
int QRealMutexPrivate::level()
{
return locked();
}
#ifndef Q_RECURSIVE_MUTEX_TYPE
QRecursiveMutexPrivate::QRecursiveMutexPrivate()
@ -329,6 +336,11 @@ int QRecursiveMutexPrivate::type() const
return Q_MUTEX_RECURSIVE;
}
int QRecursiveMutexPrivate::level()
{
return count;
}
#endif // !Q_RECURSIVE_MUTEX_TYPE
@ -510,6 +522,22 @@ bool QMutex::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 QMutex::level()
{
return d->level();
}
/*!
\class QMutexLocker qmutex.h
\brief The QMutexLocker class simplifies locking and unlocking QMutexes.

Loading…
Cancel
Save