diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2010-05-18 13:58:24 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2010-05-24 19:09:31 (GMT) |
commit | fd256203708e79d64bad856e39bb5a43357bfd06 (patch) | |
tree | 7ec4edc7310b4a0724c3d6ffd3fce8a234f7c0c2 /src/dbus/qdbuspendingcall_p.h | |
parent | 314a36895e1a31dd2b62de265d9160238d96e512 (diff) | |
download | Qt-fd256203708e79d64bad856e39bb5a43357bfd06.zip Qt-fd256203708e79d64bad856e39bb5a43357bfd06.tar.gz Qt-fd256203708e79d64bad856e39bb5a43357bfd06.tar.bz2 |
Fix a race condition with QtDBus blocking for replies.
If an auxiliary thread tried to block on waiting for a reply, and at
the same time the main thread handled the reply, there's room for a
race condition. So ensure only one thread is stopped at
dbus_pending_call_block().
The other thread(s) will be waiting on the QWaitCondition.
It's not a race condition for the main thread to process (and finish
processing) the reply while the auxiliary thread hasn't even started
to wait. The code will ensure that the reply is properly seen.
Task-Id: https://projects.maemo.org/bugzilla/show_bug.cgi?id=155306
Reviewed-By: Trust Me
Diffstat (limited to 'src/dbus/qdbuspendingcall_p.h')
-rw-r--r-- | src/dbus/qdbuspendingcall_p.h | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h index 641c397..c3aed53 100644 --- a/src/dbus/qdbuspendingcall_p.h +++ b/src/dbus/qdbuspendingcall_p.h @@ -57,6 +57,8 @@ #include <qshareddata.h> #include <qpointer.h> #include <qlist.h> +#include <qmutex.h> +#include <qwaitcondition.h> #include "qdbusmessage.h" #include "qdbus_symbols_p.h" @@ -71,24 +73,35 @@ class QDBusConnectionPrivate; class QDBusPendingCallPrivate: public QSharedData { public: - QDBusMessage sentMessage; - QDBusMessage replyMessage; -// QDBusMessage pendingReplyMessage; // used in the local loop - QDBusPendingCallWatcherHelper *watcherHelper; - DBusPendingCall *pending; - QDBusConnectionPrivate *connection; + // { + // set only during construction: + const QDBusMessage sentMessage; + QDBusConnectionPrivate * const connection; - QString expectedReplySignature; - int expectedReplyCount; - - // for the callback + // for the callback mechanism (see setReplyCallback and QDBusConnectionPrivate::sendWithReplyAsync) QPointer<QObject> receiver; QList<int> metaTypes; int methodIdx; bool autoDelete; + // } + + mutable QMutex mutex; + QWaitCondition waitForFinishedCondition; + + // { + // protected by the mutex above: + QDBusPendingCallWatcherHelper *watcherHelper; + QDBusMessage replyMessage; + DBusPendingCall *pending; + volatile bool waitingForFinished; + + QString expectedReplySignature; + int expectedReplyCount; + // } - QDBusPendingCallPrivate() : watcherHelper(0), pending(0), autoDelete(false) + QDBusPendingCallPrivate(const QDBusMessage &sent, QDBusConnectionPrivate *connection) + : sentMessage(sent), connection(connection), autoDelete(false), watcherHelper(0), pending(0), waitingForFinished(false) { } ~QDBusPendingCallPrivate(); bool setReplyCallback(QObject *target, const char *member); |