Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/dbus/qdbusintegrator.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    6565#include "qdbusthreaddebug_p.h"
    6666
     67#ifndef QT_NO_DBUS
     68
    6769QT_BEGIN_NAMESPACE
    6870
    6971static bool isDebugging;
    7072#define qDBusDebug              if (!::isDebugging); else qDebug
     73
     74Q_GLOBAL_STATIC_WITH_ARGS(const QString, orgFreedesktopDBusString, (QLatin1String(DBUS_SERVICE_DBUS)))
     75
     76static inline QString dbusServiceString()
     77{ return *orgFreedesktopDBusString(); }
     78static inline QString dbusInterfaceString()
     79{
     80    // it's the same string, but just be sure
     81    Q_ASSERT(*orgFreedesktopDBusString() == QLatin1String(DBUS_INTERFACE_DBUS));
     82    return *orgFreedesktopDBusString();
     83}
    7184
    7285static inline QDebug operator<<(QDebug dbg, const QThread *th)
     
    507520}
    508521
    509 extern QDBUS_EXPORT void qDBusAddSpyHook(QDBusSpyHook);
     522extern Q_DBUS_EXPORT void qDBusAddSpyHook(QDBusSpyHook);
    510523void qDBusAddSpyHook(QDBusSpyHook hook)
    511524{
     
    539552        (*(*list)[i])(amsg);
    540553    }
     554
     555    if (!ref)
     556        return false;
    541557
    542558    switch (amsg.type()) {
     
    550566    case QDBusMessage::ReplyMessage:
    551567    case QDBusMessage::ErrorMessage:
     568    case QDBusMessage::InvalidMessage:
    552569        return false;           // we don't handle those here
    553     case QDBusMessage::InvalidMessage:
    554         Q_ASSERT_X(false, "QDBusConnection", "Invalid message found when processing");
    555         break;
    556570    }
    557571
     
    617631
    618632        // check type:
    619         if (mm.methodType() != QMetaMethod::Slot)
     633        if (mm.methodType() != QMetaMethod::Slot && mm.methodType() != QMetaMethod::Method)
    620634            continue;
    621635
     
    681695            continue;
    682696
    683         if (isScriptable && (flags & QDBusConnection::ExportScriptableSlots) == 0)
    684             continue;           // not exported
    685         if (!isScriptable && (flags & QDBusConnection::ExportNonScriptableSlots) == 0)
    686             continue;           // not exported
     697        if (mm.methodType() == QMetaMethod::Slot) {
     698            if (isScriptable && (flags & QDBusConnection::ExportScriptableSlots) == 0)
     699                continue;           // scriptable slots not exported
     700            if (!isScriptable && (flags & QDBusConnection::ExportNonScriptableSlots) == 0)
     701                continue;           // non-scriptable slots not exported
     702        } else {
     703            if (isScriptable && (flags & QDBusConnection::ExportScriptableInvokables) == 0)
     704                continue;           // scriptable invokables not exported
     705            if (!isScriptable && (flags & QDBusConnection::ExportNonScriptableInvokables) == 0)
     706                continue;           // non-scriptable invokables not exported
     707        }
    687708
    688709        // if we got here, this slot matched
     
    693714    return -1;
    694715}
     716
     717static QDBusCallDeliveryEvent * const DIRECT_DELIVERY = (QDBusCallDeliveryEvent *)1;
    695718
    696719QDBusCallDeliveryEvent* QDBusConnectionPrivate::prepareReply(QDBusConnectionPrivate *target,
     
    705728    if (metaTypes[n] == QDBusMetaTypeId::message)
    706729        --n;
     730
     731    if (msg.arguments().count() < n)
     732        return 0;               // too few arguments
    707733
    708734    // check that types match
     
    714740    // we can deliver
    715741    // prepare for the call
     742    if (target == object)
     743        return DIRECT_DELIVERY;
    716744    return new QDBusCallDeliveryEvent(QDBusConnection(target), idx, target, msg, metaTypes);
    717745}
     
    728756    // Slots receive read-only copies of the message (i.e., pass by value or by const-ref)
    729757    QDBusCallDeliveryEvent *call = prepareReply(this, hook.obj, hook.midx, hook.params, msg);
     758    if (call == DIRECT_DELIVERY) {
     759        // short-circuit delivery
     760        Q_ASSERT(this == hook.obj);
     761        deliverCall(this, 0, msg, hook.params, hook.midx);
     762        return;
     763    }
    730764    if (call)
    731765        postEventToThread(ActivateSignalAction, hook.obj, call);
     
    759793        return false;
    760794
     795#ifndef QT_NO_PROPERTIES
    761796    Q_ASSERT_X(QThread::currentThread() == object->thread(),
    762797               "QDBusConnection: internal threading error",
     
    778813    if (cacheIt == slotCache.hash.constEnd() || cacheIt.key() != cacheKey)
    779814    {
    780         // not cached, analyse the meta object
     815        // not cached, analyze the meta object
    781816        const QMetaObject *mo = object->metaObject();
    782817        QByteArray memberName = msg.member().toUtf8();
     
    817852        return true;
    818853    }
     854#endif // QT_NO_PROPERTIES
     855    return false;
    819856}
    820857
     
    948985
    949986    rootNode.flags = 0;
     987
     988    // prepopulate watchedServices:
     989    // we know that the owner of org.freedesktop.DBus is itself
     990    watchedServices.insert(dbusServiceString(), WatchedServiceData(dbusServiceString(), 1));
     991
     992    // prepopulate matchRefCounts:
     993    // we know that org.freedesktop.DBus will never change owners
     994    matchRefCounts.insert("type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='org.freedesktop.DBus'", 1);
    950995}
    951996
     
    11741219}
    11751220
    1176 void QDBusConnectionPrivate::_q_serviceOwnerChanged(const QString &name,
    1177                                                     const QString &oldOwner, const QString &newOwner)
     1221void QDBusConnectionPrivate::serviceOwnerChangedNoLock(const QString &name,
     1222                                                       const QString &oldOwner, const QString &newOwner)
    11781223{
    11791224    Q_UNUSED(oldOwner);
    1180     QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this);
     1225//    QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this);
    11811226    WatchedServicesHash::Iterator it = watchedServices.find(name);
    11821227    if (it == watchedServices.end())
     
    13751420
    13761421    // try the object itself:
    1377     if (node.flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots)) {
     1422    if (node.flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots) ||
     1423        node.flags & (QDBusConnection::ExportScriptableInvokables|QDBusConnection::ExportNonScriptableInvokables)) {
    13781424        bool interfaceFound = true;
    13791425        if (!msg.interface().isEmpty())
     
    16311677    mode = ClientMode;
    16321678
     1679    const char *service = q_dbus_bus_get_unique_name(connection);
     1680    Q_ASSERT(service);
     1681    baseService = QString::fromUtf8(service);
     1682
    16331683    q_dbus_connection_set_exit_on_disconnect(connection, false);
    16341684    q_dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch,
     
    16371687                                            qDBusToggleTimeout, this, 0);
    16381688    q_dbus_connection_set_dispatch_status_function(connection, qDBusUpdateDispatchStatus, this, 0);
    1639 
    1640     // Initialize the match rules
    1641     // We want all messages that have us as destination
    1642     // signals don't have destinations, but connectSignal() takes care of them
    1643     const char *service = q_dbus_bus_get_unique_name(connection);
    1644     if (service) {
    1645         QVarLengthArray<char, 56> filter;
    1646         filter.append("destination='", 13);
    1647         filter.append(service, qstrlen(service));
    1648         filter.append("\'\0", 2);
    1649 
    1650         QDBusErrorInternal error;
    1651         q_dbus_bus_add_match(connection, filter.constData(), error);
    1652         if (handleError(error)) {
    1653             closeConnection();
    1654             return;
    1655         }
    1656 
    1657         baseService = QString::fromUtf8(service);
    1658     } else {
    1659         qWarning("QDBusConnectionPrivate::setConnection: Unable to get base service");
    1660     }
    1661 
    1662     QString busService = QLatin1String(DBUS_SERVICE_DBUS);
    1663     connectSignal(busService, QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(),
    1664                   this, SLOT(registerService(QString)));
    1665     connectSignal(busService, QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(),
    1666                   this, SLOT(unregisterService(QString)));
    1667 
    1668 
    16691689    q_dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0);
     1690
     1691    // Initialize the hooks for the NameAcquired and NameLost signals
     1692    // we don't use connectSignal here because we don't need the rules to be sent to the bus
     1693    // the bus will always send us these two signals
     1694    SignalHook hook;
     1695    hook.service = dbusServiceString();
     1696    hook.path.clear(); // no matching
     1697    hook.obj = this;
     1698    hook.params << QMetaType::Void << QVariant::String; // both functions take a QString as parameter and return void
     1699
     1700    hook.midx = staticMetaObject.indexOfSlot("registerServiceNoLock(QString)");
     1701    Q_ASSERT(hook.midx != -1);
     1702    signalHooks.insert(QLatin1String("NameAcquired:" DBUS_INTERFACE_DBUS), hook);
     1703
     1704    hook.midx = staticMetaObject.indexOfSlot("unregisterServiceNoLock(QString)");
     1705    Q_ASSERT(hook.midx != -1);
     1706    signalHooks.insert(QLatin1String("NameLost:" DBUS_INTERFACE_DBUS), hook);
    16701707
    16711708    qDBusDebug() << this << ": connected successfully";
     
    20542091                if (++data.refcount == 1) {
    20552092                    // we need to watch for this service changing
    2056                     QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
    2057                     connectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
     2093                    connectSignal(dbusServiceString(), QString(), dbusInterfaceString(),
    20582094                                  QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(),
    2059                                   this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
     2095                                  this, SLOT(serviceOwnerChangedNoLock(QString,QString,QString)));
    20602096                    data.owner = getNameOwnerNoCache(hook.service);
    20612097                    qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:"
     
    21342170            if (--sit.value().refcount == 0) {
    21352171                watchedServices.erase(sit);
    2136                 QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS);
    2137                 disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS),
     2172                disconnectSignal(dbusServiceString(), QString(), dbusInterfaceString(),
    21382173                              QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(),
    21392174                              this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
     
    22572292QString QDBusConnectionPrivate::getNameOwnerNoCache(const QString &serviceName)
    22582293{
    2259     QDBusMessage msg = QDBusMessage::createMethodCall(QLatin1String(DBUS_SERVICE_DBUS),
    2260             QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS),
     2294    QDBusMessage msg = QDBusMessage::createMethodCall(dbusServiceString(),
     2295            QLatin1String(DBUS_PATH_DBUS), dbusInterfaceString(),
    22612296            QLatin1String("GetNameOwner"));
    22622297    QDBusMessagePrivate::setParametersValidated(msg, true);
     
    23192354{
    23202355    QDBusWriteLocker locker(RegisterServiceAction, this);
     2356    registerServiceNoLock(serviceName);
     2357}
     2358
     2359void QDBusConnectionPrivate::registerServiceNoLock(const QString &serviceName)
     2360{
    23212361    serviceNames.append(serviceName);
    23222362}
     
    23252365{
    23262366    QDBusWriteLocker locker(UnregisterServiceAction, this);
     2367    unregisterServiceNoLock(serviceName);
     2368}
     2369
     2370void QDBusConnectionPrivate::unregisterServiceNoLock(const QString &serviceName)
     2371{
    23272372    serviceNames.removeAll(serviceName);
    23282373}
     
    23442389
    23452390QT_END_NAMESPACE
     2391
     2392#endif // QT_NO_DBUS
Note: See TracChangeset for help on using the changeset viewer.