summaryrefslogtreecommitdiffstats
path: root/src/dbus
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-08-14 09:05:42 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-08-14 09:06:31 +0200
commit5c23199d4e8ff21661dfa5aacc13149178e78cab (patch)
tree322aee61581d7c85f1ccb65e47d1e79eba1ba6c9 /src/dbus
parent252bad7c589e03d3e12df02354b00a84d8e3159a (diff)
parentc8d9b17367cfdcb034d11f8a168ca4ae3993e7c3 (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: configure mkspecs/macx-xcode/Info.plist.app mkspecs/macx-xcode/Info.plist.lib qmake/doc/qmake.qdocconf src/corelib/global/qglobal.h tests/auto/other/exceptionsafety/exceptionsafety.pro tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp Change-Id: I3c769a4a82dc2e99a12c69123fbf17613fd2ac2a
Diffstat (limited to 'src/dbus')
-rw-r--r--src/dbus/qdbusconnection.cpp3
-rw-r--r--src/dbus/qdbusconnection_p.h5
-rw-r--r--src/dbus/qdbusintegrator.cpp108
-rw-r--r--src/dbus/qdbusmetaobject.cpp12
-rw-r--r--src/dbus/qdbuspendingcall.cpp6
-rw-r--r--src/dbus/qdbuspendingcall_p.h3
6 files changed, 76 insertions, 61 deletions
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 74a3a752a5..a29ba4cb0f 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -54,6 +54,7 @@
#include "qdbusinterface_p.h"
#include "qdbusutil_p.h"
#include "qdbusconnectionmanager_p.h"
+#include "qdbuspendingcall_p.h"
#include "qdbusthreaddebug_p.h"
@@ -611,7 +612,7 @@ QDBusPendingCall QDBusConnection::asyncCall(const QDBusMessage &message, int tim
return QDBusPendingCall(0); // null pointer -> disconnected
}
- QDBusPendingCallPrivate *priv = d->sendWithReplyAsync(message, timeout);
+ QDBusPendingCallPrivate *priv = d->sendWithReplyAsync(message, 0, 0, 0, timeout);
return QDBusPendingCall(priv);
}
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index 48026e15bd..013896bd32 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -199,9 +199,8 @@ public:
int send(const QDBusMessage &message);
QDBusMessage sendWithReply(const QDBusMessage &message, int mode, int timeout = -1);
QDBusMessage sendWithReplyLocal(const QDBusMessage &message);
- QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, int timeout = -1);
- int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
- const char *returnMethod, const char *errorMethod, int timeout = -1);
+ QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
+ const char *returnMethod, const char *errorMethod,int timeout = -1);
bool connectSignal(const QString &service, const QString &path, const QString& interface,
const QString &name, const QStringList &argumentMatch, const QString &signature,
QObject *receiver, const char *slot);
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 010c076b7f..e5f3fbdc53 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1830,7 +1830,6 @@ static void qDBusResultReceived(DBusPendingCall *pending, void *user_data)
void QDBusConnectionPrivate::waitForFinished(QDBusPendingCallPrivate *pcall)
{
Q_ASSERT(pcall->pending);
- Q_ASSERT(!pcall->autoDelete);
//Q_ASSERT(pcall->mutex.isLocked()); // there's no such function
if (pcall->waitingForFinished) {
@@ -1846,17 +1845,16 @@ void QDBusConnectionPrivate::waitForFinished(QDBusPendingCallPrivate *pcall)
// QDBusConnectionPrivate::processFinishedCall() is called automatically
}
pcall->mutex.lock();
+
+ if (pcall->pending) {
+ q_dbus_pending_call_unref(pcall->pending);
+ pcall->pending = 0;
+ }
+
pcall->waitForFinishedCondition.wakeAll();
}
}
-// this function is called only in a Q_ASSERT
-static inline Q_DECL_UNUSED bool waitingForFinishedIsSet(QDBusPendingCallPrivate *call)
-{
- const QMutexLocker locker(&call->mutex);
- return call->waitingForFinished;
-}
-
void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
{
QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection);
@@ -1892,9 +1890,10 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
qDBusDebug() << "Deliver failed!";
}
- if (call->pending)
+ if (call->pending && !call->waitingForFinished) {
q_dbus_pending_call_unref(call->pending);
- call->pending = 0;
+ call->pending = 0;
+ }
locker.unlock();
@@ -1905,10 +1904,8 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
if (msg.type() == QDBusMessage::ErrorMessage)
emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage);
- if (call->autoDelete) {
- Q_ASSERT(!waitingForFinishedIsSet(call)); // can't wait on a call with autoDelete!
+ if (!call->ref.deref())
delete call;
- }
}
int QDBusConnectionPrivate::send(const QDBusMessage& message)
@@ -1991,7 +1988,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
return amsg;
} else { // use the event loop
- QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, timeout);
+ QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, 0, 0, 0, timeout);
Q_ASSERT(pcall);
if (pcall->replyMessage.type() == QDBusMessage::InvalidMessage) {
@@ -2007,6 +2004,10 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
QDBusMessage reply = pcall->replyMessage;
lastError = QDBusError(reply); // set or clear error
+ bool r = pcall->ref.deref();
+ Q_ASSERT(!r);
+ Q_UNUSED(r);
+
delete pcall;
return reply;
}
@@ -2046,19 +2047,55 @@ QDBusMessage QDBusConnectionPrivate::sendWithReplyLocal(const QDBusMessage &mess
}
QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message,
- int timeout)
+ QObject *receiver, const char *returnMethod,
+ const char *errorMethod, int timeout)
{
if (isServiceRegisteredByThread(message.service())) {
// special case for local calls
QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this);
pcall->replyMessage = sendWithReplyLocal(message);
+ if (receiver && returnMethod)
+ pcall->setReplyCallback(receiver, returnMethod);
+
+ if (errorMethod) {
+ pcall->watcherHelper = new QDBusPendingCallWatcherHelper;
+ connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod,
+ Qt::QueuedConnection);
+ pcall->watcherHelper->moveToThread(thread());
+ }
+ if ((receiver && returnMethod) || errorMethod) {
+ // no one waiting, will delete pcall in processFinishedCall()
+ pcall->ref.store(1);
+ } else {
+ // set double ref to prevent race between processFinishedCall() and ref counting
+ // by QDBusPendingCall::QExplicitlySharedDataPointer<QDBusPendingCallPrivate>
+ pcall->ref.store(2);
+ }
+ processFinishedCall(pcall);
return pcall;
}
checkThread();
QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this);
- pcall->ref.store(0);
+ if (receiver && returnMethod)
+ pcall->setReplyCallback(receiver, returnMethod);
+
+ if (errorMethod) {
+ pcall->watcherHelper = new QDBusPendingCallWatcherHelper;
+ connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod,
+ Qt::QueuedConnection);
+ pcall->watcherHelper->moveToThread(thread());
+ }
+
+ if ((receiver && returnMethod) || errorMethod) {
+ // no one waiting, will delete pcall in processFinishedCall()
+ pcall->ref.store(1);
+ } else {
+ // set double ref to prevent race between processFinishedCall() and ref counting
+ // by QDBusPendingCall::QExplicitlySharedDataPointer<QDBusPendingCallPrivate>
+ pcall->ref.store(2);
+ }
QDBusError error;
DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, capabilities, &error);
@@ -2069,6 +2106,7 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM
qPrintable(error.message()));
pcall->replyMessage = QDBusMessage::createError(error);
lastError = error;
+ processFinishedCall(pcall);
return pcall;
}
@@ -2094,46 +2132,10 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM
q_dbus_message_unref(msg);
pcall->replyMessage = QDBusMessage::createError(error);
+ processFinishedCall(pcall);
return pcall;
}
-int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
- const char *returnMethod, const char *errorMethod,
- int timeout)
-{
- QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, timeout);
- Q_ASSERT(pcall);
-
- // has it already finished with success (dispatched locally)?
- if (pcall->replyMessage.type() == QDBusMessage::ReplyMessage) {
- pcall->setReplyCallback(receiver, returnMethod);
- processFinishedCall(pcall);
- delete pcall;
- return 1;
- }
-
- // either it hasn't finished or it has finished with error
- if (errorMethod) {
- pcall->watcherHelper = new QDBusPendingCallWatcherHelper;
- connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod,
- Qt::QueuedConnection);
- pcall->watcherHelper->moveToThread(thread());
- }
-
- // has it already finished and is an error reply message?
- if (pcall->replyMessage.type() == QDBusMessage::ErrorMessage) {
- processFinishedCall(pcall);
- delete pcall;
- return 1;
- }
-
- pcall->autoDelete = true;
- pcall->ref.ref();
- pcall->setReplyCallback(receiver, returnMethod);
-
- return 1;
-}
-
bool QDBusConnectionPrivate::connectSignal(const QString &service,
const QString &path, const QString &interface, const QString &name,
const QStringList &argumentMatch, const QString &signature,
diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index 799c66f6f9..127cf6658c 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -75,6 +75,7 @@ private:
QByteArray name;
QVarLengthArray<int, 4> inputTypes;
QVarLengthArray<int, 4> outputTypes;
+ QByteArray rawReturnType;
int flags;
};
@@ -276,6 +277,9 @@ void QDBusMetaObjectGenerator::parseMethods()
mm.outputTypes.append(type.id);
+ if (i == 0 && type.id == -1) {
+ mm.rawReturnType = type.name;
+ }
if (i != 0) {
// non-const ref parameter
mm.parameterNames.append(arg.name.toLatin1());
@@ -471,10 +475,14 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
int type;
QByteArray typeName;
if (i < 0) { // Return type
- if (!mm.outputTypes.isEmpty())
+ if (!mm.outputTypes.isEmpty()) {
type = mm.outputTypes.first();
- else
+ if (type == -1) {
+ type = IsUnresolvedType | strings.enter(mm.rawReturnType);
+ }
+ } else {
type = QMetaType::Void;
+ }
} else if (i < mm.inputTypes.size()) {
type = mm.inputTypes.at(i);
} else {
diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp
index 0b4ff3a397..49f9fc0cd8 100644
--- a/src/dbus/qdbuspendingcall.cpp
+++ b/src/dbus/qdbuspendingcall.cpp
@@ -256,6 +256,11 @@ QDBusPendingCall::QDBusPendingCall(const QDBusPendingCall &other)
QDBusPendingCall::QDBusPendingCall(QDBusPendingCallPrivate *dd)
: d(dd)
{
+ if (dd) {
+ bool r = dd->ref.deref();
+ Q_ASSERT(r);
+ Q_UNUSED(r);
+ }
}
/*!
@@ -469,6 +474,7 @@ QDBusPendingCall QDBusPendingCall::fromCompletedCall(const QDBusMessage &msg)
msg.type() == QDBusMessage::ReplyMessage) {
d = new QDBusPendingCallPrivate(QDBusMessage(), 0);
d->replyMessage = msg;
+ d->ref.store(1);
}
return QDBusPendingCall(d);
diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h
index 36d0b9023a..d0b28b3c0e 100644
--- a/src/dbus/qdbuspendingcall_p.h
+++ b/src/dbus/qdbuspendingcall_p.h
@@ -85,7 +85,6 @@ public:
QVector<int> metaTypes;
int methodIdx;
- bool autoDelete;
// }
mutable QMutex mutex;
@@ -102,7 +101,7 @@ public:
// }
QDBusPendingCallPrivate(const QDBusMessage &sent, QDBusConnectionPrivate *connection)
- : sentMessage(sent), connection(connection), autoDelete(false), watcherHelper(0), pending(0), waitingForFinished(false)
+ : sentMessage(sent), connection(connection), watcherHelper(0), pending(0), waitingForFinished(false)
{ }
~QDBusPendingCallPrivate();
bool setReplyCallback(QObject *target, const char *member);