src/dbus/qdbusintegrator.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
   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