src/dbus/qdbusintegrator.cpp
changeset 30 5dc02b23752f
parent 29 b72c6db6890b
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    62 #include "qdbuspendingcall_p.h"
    62 #include "qdbuspendingcall_p.h"
    63 #include "qdbusintegrator_p.h"
    63 #include "qdbusintegrator_p.h"
    64 
    64 
    65 #include "qdbusthreaddebug_p.h"
    65 #include "qdbusthreaddebug_p.h"
    66 
    66 
       
    67 #ifndef QT_NO_DBUS
       
    68 
    67 QT_BEGIN_NAMESPACE
    69 QT_BEGIN_NAMESPACE
    68 
    70 
    69 static bool isDebugging;
    71 static bool isDebugging;
    70 #define qDBusDebug              if (!::isDebugging); else qDebug
    72 #define qDBusDebug              if (!::isDebugging); else qDebug
    71 
    73 
   521     QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
   523     QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
   522     if (d->mode == QDBusConnectionPrivate::InvalidMode)
   524     if (d->mode == QDBusConnectionPrivate::InvalidMode)
   523         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
   525         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
   524 
   526 
   525     QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message);
   527     QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message);
   526     qDBusDebug() << d << "got message (signal):" << amsg;
   528     qDBusDebug() << d << "got message:" << amsg;
   527 
   529 
   528     return d->handleMessage(amsg) ?
   530     return d->handleMessage(amsg) ?
   529         DBUS_HANDLER_RESULT_HANDLED :
   531         DBUS_HANDLER_RESULT_HANDLED :
   530         DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
   532         DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
   531 }
   533 }
   756     static const char cachePropertyName[] = "_qdbus_slotCache";
   758     static const char cachePropertyName[] = "_qdbus_slotCache";
   757 
   759 
   758     if (!object)
   760     if (!object)
   759         return false;
   761         return false;
   760 
   762 
       
   763 #ifndef QT_NO_PROPERTIES
   761     Q_ASSERT_X(QThread::currentThread() == object->thread(),
   764     Q_ASSERT_X(QThread::currentThread() == object->thread(),
   762                "QDBusConnection: internal threading error",
   765                "QDBusConnection: internal threading error",
   763                "function called for an object that is in another thread!!");
   766                "function called for an object that is in another thread!!");
   764 
   767 
   765     QDBusSlotCache slotCache =
   768     QDBusSlotCache slotCache =
   814     } else {
   817     } else {
   815         // use the cache
   818         // use the cache
   816         deliverCall(object, flags, msg, cacheIt->metaTypes, cacheIt->slotIdx);
   819         deliverCall(object, flags, msg, cacheIt->metaTypes, cacheIt->slotIdx);
   817         return true;
   820         return true;
   818     }
   821     }
       
   822 #endif // QT_NO_PROPERTIES
       
   823     return false;
   819 }
   824 }
   820 
   825 
   821 void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const QDBusMessage &msg,
   826 void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const QDBusMessage &msg,
   822                                          const QList<int> &metaTypes, int slotIdx)
   827                                          const QList<int> &metaTypes, int slotIdx)
   823 {
   828 {
  1685 }
  1690 }
  1686 
  1691 
  1687 void QDBusConnectionPrivate::waitForFinished(QDBusPendingCallPrivate *pcall)
  1692 void QDBusConnectionPrivate::waitForFinished(QDBusPendingCallPrivate *pcall)
  1688 {
  1693 {
  1689     Q_ASSERT(pcall->pending);
  1694     Q_ASSERT(pcall->pending);
  1690     Q_ASSERT(!pcall->autoDelete);
  1695     QDBusDispatchLocker locker(PendingCallBlockAction, this);
  1691     //Q_ASSERT(pcall->mutex.isLocked()); // there's no such function
  1696     q_dbus_pending_call_block(pcall->pending);
  1692 
  1697     // QDBusConnectionPrivate::processFinishedCall() is called automatically
  1693     if (pcall->waitingForFinished) {
       
  1694         // another thread is already waiting
       
  1695         pcall->waitForFinishedCondition.wait(&pcall->mutex);
       
  1696     } else {
       
  1697         pcall->waitingForFinished = true;
       
  1698         pcall->mutex.unlock();
       
  1699 
       
  1700         {
       
  1701             QDBusDispatchLocker locker(PendingCallBlockAction, this);
       
  1702             q_dbus_pending_call_block(pcall->pending);
       
  1703             // QDBusConnectionPrivate::processFinishedCall() is called automatically
       
  1704         }
       
  1705         pcall->mutex.lock();
       
  1706     }
       
  1707 }
  1698 }
  1708 
  1699 
  1709 void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
  1700 void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
  1710 {
  1701 {
  1711     QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection);
  1702     QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection);
  1712 
       
  1713     QMutexLocker locker(&call->mutex);
       
  1714 
  1703 
  1715     QDBusMessage &msg = call->replyMessage;
  1704     QDBusMessage &msg = call->replyMessage;
  1716     if (call->pending) {
  1705     if (call->pending) {
  1717         // decode the message
  1706         // decode the message
  1718         DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
  1707         DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
  1739             connection->postEventToThread(MessageResultReceivedAction, call->receiver, e);
  1728             connection->postEventToThread(MessageResultReceivedAction, call->receiver, e);
  1740         else
  1729         else
  1741             qDBusDebug() << "Deliver failed!";
  1730             qDBusDebug() << "Deliver failed!";
  1742     }
  1731     }
  1743 
  1732 
       
  1733     // Are there any watchers?
       
  1734     if (call->watcherHelper)
       
  1735         call->watcherHelper->emitSignals(msg, call->sentMessage);
       
  1736 
       
  1737     if (msg.type() == QDBusMessage::ErrorMessage)
       
  1738         emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage);
       
  1739 
  1744     if (call->pending)
  1740     if (call->pending)
  1745         q_dbus_pending_call_unref(call->pending);
  1741         q_dbus_pending_call_unref(call->pending);
  1746     call->pending = 0;
  1742     call->pending = 0;
  1747 
  1743 
  1748     locker.unlock();
  1744     if (call->autoDelete)
  1749 
       
  1750     // Are there any watchers?
       
  1751     if (call->watcherHelper)
       
  1752         call->watcherHelper->emitSignals(msg, call->sentMessage);
       
  1753 
       
  1754     if (msg.type() == QDBusMessage::ErrorMessage)
       
  1755         emit connection->callWithCallbackFailed(QDBusError(msg), call->sentMessage);
       
  1756 
       
  1757     if (call->autoDelete) {
       
  1758         Q_ASSERT(!call->waitingForFinished); // can't wait on a call with autoDelete!
       
  1759         delete call;
  1745         delete call;
  1760     }
       
  1761 }
  1746 }
  1762 
  1747 
  1763 int QDBusConnectionPrivate::send(const QDBusMessage& message)
  1748 int QDBusConnectionPrivate::send(const QDBusMessage& message)
  1764 {
  1749 {
  1765     if (QDBusMessagePrivate::isLocal(message))
  1750     if (QDBusMessagePrivate::isLocal(message))
  1897 QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message,
  1882 QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message,
  1898                                                                     int timeout)
  1883                                                                     int timeout)
  1899 {
  1884 {
  1900     if (isServiceRegisteredByThread(message.service())) {
  1885     if (isServiceRegisteredByThread(message.service())) {
  1901         // special case for local calls
  1886         // special case for local calls
  1902         QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this);
  1887         QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate;
       
  1888         pcall->sentMessage = message;
  1903         pcall->replyMessage = sendWithReplyLocal(message);
  1889         pcall->replyMessage = sendWithReplyLocal(message);
       
  1890         pcall->connection = this;
  1904 
  1891 
  1905         return pcall;
  1892         return pcall;
  1906     }
  1893     }
  1907 
  1894 
  1908     checkThread();
  1895     checkThread();
  1909     QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate(message, this);
  1896     QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate;
       
  1897     pcall->sentMessage = message;
  1910     pcall->ref = 0;
  1898     pcall->ref = 0;
  1911 
  1899 
  1912     QDBusError error;
  1900     QDBusError error;
  1913     DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error);
  1901     DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error);
  1914     if (!msg) {
  1902     if (!msg) {
  1928     if (q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) {
  1916     if (q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) {
  1929         if (pending) {
  1917         if (pending) {
  1930             q_dbus_message_unref(msg);
  1918             q_dbus_message_unref(msg);
  1931 
  1919 
  1932             pcall->pending = pending;
  1920             pcall->pending = pending;
       
  1921             pcall->connection = this;
  1933             q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);
  1922             q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);
  1934 
  1923 
  1935             return pcall;
  1924             return pcall;
  1936         } else {
  1925         } else {
  1937             // we're probably disconnected at this point
  1926             // we're probably disconnected at this point
  2341     QCoreApplication::postEvent(object, ev);
  2330     QCoreApplication::postEvent(object, ev);
  2342     QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterPost, this);
  2331     QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterPost, this);
  2343 }
  2332 }
  2344 
  2333 
  2345 QT_END_NAMESPACE
  2334 QT_END_NAMESPACE
       
  2335 
       
  2336 #endif // QT_NO_DBUS