summaryrefslogtreecommitdiffstats
path: root/src/dbus/qdbuspendingcall_p.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2010-05-18 13:58:24 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2010-05-24 19:09:31 (GMT)
commitfd256203708e79d64bad856e39bb5a43357bfd06 (patch)
tree7ec4edc7310b4a0724c3d6ffd3fce8a234f7c0c2 /src/dbus/qdbuspendingcall_p.h
parent314a36895e1a31dd2b62de265d9160238d96e512 (diff)
downloadQt-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.h35
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);