506 static bool shouldWatchService(const QString &service) |
506 static bool shouldWatchService(const QString &service) |
507 { |
507 { |
508 return !service.isEmpty() && !service.startsWith(QLatin1Char(':')); |
508 return !service.isEmpty() && !service.startsWith(QLatin1Char(':')); |
509 } |
509 } |
510 |
510 |
511 extern QDBUS_EXPORT void qDBusAddSpyHook(QDBusSpyHook); |
511 extern Q_DBUS_EXPORT void qDBusAddSpyHook(QDBusSpyHook); |
512 void qDBusAddSpyHook(QDBusSpyHook hook) |
512 void qDBusAddSpyHook(QDBusSpyHook hook) |
513 { |
513 { |
514 qDBusSpyHookList()->append(hook); |
514 qDBusSpyHookList()->append(hook); |
515 } |
515 } |
516 |
516 |
523 QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); |
523 QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); |
524 if (d->mode == QDBusConnectionPrivate::InvalidMode) |
524 if (d->mode == QDBusConnectionPrivate::InvalidMode) |
525 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
525 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
526 |
526 |
527 QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message); |
527 QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message); |
528 qDBusDebug() << d << "got message:" << amsg; |
528 qDBusDebug() << d << "got message (signal):" << amsg; |
529 |
529 |
530 return d->handleMessage(amsg) ? |
530 return d->handleMessage(amsg) ? |
531 DBUS_HANDLER_RESULT_HANDLED : |
531 DBUS_HANDLER_RESULT_HANDLED : |
532 DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
532 DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
533 } |
533 } |
1690 } |
1690 } |
1691 |
1691 |
1692 void QDBusConnectionPrivate::waitForFinished(QDBusPendingCallPrivate *pcall) |
1692 void QDBusConnectionPrivate::waitForFinished(QDBusPendingCallPrivate *pcall) |
1693 { |
1693 { |
1694 Q_ASSERT(pcall->pending); |
1694 Q_ASSERT(pcall->pending); |
1695 QDBusDispatchLocker locker(PendingCallBlockAction, this); |
1695 Q_ASSERT(!pcall->autoDelete); |
1696 q_dbus_pending_call_block(pcall->pending); |
1696 //Q_ASSERT(pcall->mutex.isLocked()); // there's no such function |
1697 // QDBusConnectionPrivate::processFinishedCall() is called automatically |
1697 |
|
1698 if (pcall->waitingForFinished) { |
|
1699 // another thread is already waiting |
|
1700 pcall->waitForFinishedCondition.wait(&pcall->mutex); |
|
1701 } else { |
|
1702 pcall->waitingForFinished = true; |
|
1703 pcall->mutex.unlock(); |
|
1704 |
|
1705 { |
|
1706 QDBusDispatchLocker locker(PendingCallBlockAction, this); |
|
1707 q_dbus_pending_call_block(pcall->pending); |
|
1708 // QDBusConnectionPrivate::processFinishedCall() is called automatically |
|
1709 } |
|
1710 pcall->mutex.lock(); |
|
1711 } |
1698 } |
1712 } |
1699 |
1713 |
1700 void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) |
1714 void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) |
1701 { |
1715 { |
1702 QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection); |
1716 QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection); |
|
1717 |
|
1718 QMutexLocker locker(&call->mutex); |
1703 |
1719 |
1704 QDBusMessage &msg = call->replyMessage; |
1720 QDBusMessage &msg = call->replyMessage; |
1705 if (call->pending) { |
1721 if (call->pending) { |
1706 // decode the message |
1722 // decode the message |
1707 DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending); |
1723 DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending); |
1728 connection->postEventToThread(MessageResultReceivedAction, call->receiver, e); |
1744 connection->postEventToThread(MessageResultReceivedAction, call->receiver, e); |
1729 else |
1745 else |
1730 qDBusDebug() << "Deliver failed!"; |
1746 qDBusDebug() << "Deliver failed!"; |
1731 } |
1747 } |
1732 |
1748 |
|
1749 if (call->pending) |
|
1750 q_dbus_pending_call_unref(call->pending); |
|
1751 call->pending = 0; |
|
1752 |
|
1753 locker.unlock(); |
|
1754 |
1733 // Are there any watchers? |
1755 // Are there any watchers? |
1734 if (call->watcherHelper) |
1756 if (call->watcherHelper) |
1735 call->watcherHelper->emitSignals(msg, call->sentMessage); |
1757 call->watcherHelper->emitSignals(msg, call->sentMessage); |
1736 |
1758 |
1737 if (msg.type() == QDBusMessage::ErrorMessage) |
1759 if (msg.type() == QDBusMessage::ErrorMessage) |
1738 emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage); |
1760 emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage); |
1739 |
1761 |
1740 if (call->pending) |
1762 if (call->autoDelete) { |
1741 q_dbus_pending_call_unref(call->pending); |
1763 Q_ASSERT(!call->waitingForFinished); // can't wait on a call with autoDelete! |
1742 call->pending = 0; |
|
1743 |
|
1744 if (call->autoDelete) |
|
1745 delete call; |
1764 delete call; |
|
1765 } |
1746 } |
1766 } |
1747 |
1767 |
1748 int QDBusConnectionPrivate::send(const QDBusMessage& message) |
1768 int QDBusConnectionPrivate::send(const QDBusMessage& message) |
1749 { |
1769 { |
1750 if (QDBusMessagePrivate::isLocal(message)) |
1770 if (QDBusMessagePrivate::isLocal(message)) |
1882 QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, |
1902 QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, |
1883 int timeout) |
1903 int timeout) |
1884 { |
1904 { |
1885 if (isServiceRegisteredByThread(message.service())) { |
1905 if (isServiceRegisteredByThread(message.service())) { |
1886 // special case for local calls |
1906 // special case for local calls |
1887 QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; |
1907 QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this); |
1888 pcall->sentMessage = message; |
|
1889 pcall->replyMessage = sendWithReplyLocal(message); |
1908 pcall->replyMessage = sendWithReplyLocal(message); |
1890 pcall->connection = this; |
|
1891 |
1909 |
1892 return pcall; |
1910 return pcall; |
1893 } |
1911 } |
1894 |
1912 |
1895 checkThread(); |
1913 checkThread(); |
1896 QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; |
1914 QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this); |
1897 pcall->sentMessage = message; |
|
1898 pcall->ref = 0; |
1915 pcall->ref = 0; |
1899 |
1916 |
1900 QDBusError error; |
1917 QDBusError error; |
1901 DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); |
1918 DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); |
1902 if (!msg) { |
1919 if (!msg) { |
1916 if (q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) { |
1933 if (q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) { |
1917 if (pending) { |
1934 if (pending) { |
1918 q_dbus_message_unref(msg); |
1935 q_dbus_message_unref(msg); |
1919 |
1936 |
1920 pcall->pending = pending; |
1937 pcall->pending = pending; |
1921 pcall->connection = this; |
|
1922 q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0); |
1938 q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0); |
1923 |
1939 |
1924 return pcall; |
1940 return pcall; |
1925 } else { |
1941 } else { |
1926 // we're probably disconnected at this point |
1942 // we're probably disconnected at this point |