[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdelibs/KDE/4.10] solid/solid/backends/udisks2: another roundup of speedups in the device enumerati
From:       Lukáš Tinkl <lukas () kde ! org>
Date:       2012-10-29 16:57:00
Message-ID: 20121029165700.9F7E2A60C4 () git ! kde ! org
[Download RAW message or body]

Git commit 0cc81d42ee16d9a8553e371e4c8cb496765c8dbd by Lukáš Tinkl.
Committed on 29/10/2012 at 17:55.
Pushed by lukas into branch 'KDE/4.10'.

another roundup of speedups in the device enumeration

using introspection instead of the specialized GetManagedObjects
DBUS method (aka dump everything) which is ~30% slower

M  +22   -18   solid/solid/backends/udisks2/udisksblock.cpp
M  +41   -0    solid/solid/backends/udisks2/udisksmanager.cpp
M  +1    -0    solid/solid/backends/udisks2/udisksmanager.h

http://commits.kde.org/kdelibs/0cc81d42ee16d9a8553e371e4c8cb496765c8dbd

diff --git a/solid/solid/backends/udisks2/udisksblock.cpp \
b/solid/solid/backends/udisks2/udisksblock.cpp index 474f3d6..f3cd1e8 100644
--- a/solid/solid/backends/udisks2/udisksblock.cpp
+++ b/solid/solid/backends/udisks2/udisksblock.cpp
@@ -23,9 +23,9 @@
 #include <QFile>
 #include <QtDBus/QDBusConnection>
 #include <QtDBus/QDBusPendingReply>
+#include <QtXml/QDomDocument>
 
 #include "udisksblock.h"
-#include "dbus/manager.h"
 
 using namespace Solid::Backends::UDisks2;
 
@@ -37,28 +37,32 @@ Block::Block(Device *dev)
 
     // we have a drive (non-block device for udisks), so let's find the \
corresponding (real) block device  if (m_devNum == 0 || m_devFile.isEmpty()) {
-        org::freedesktop::DBus::ObjectManager manager(UD2_DBUS_SERVICE, \
                UD2_DBUS_PATH, QDBusConnection::systemBus());
-        QDBusPendingReply<DBUSManagerStruct> reply = manager.GetManagedObjects();
+        const QString path = "/org/freedesktop/UDisks2/block_devices";
+        QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path,
+                                                           \
DBUS_INTERFACE_INTROSPECT, "Introspect"); +        QDBusPendingReply<QString> reply = \
QDBusConnection::systemBus().asyncCall(call);  reply.waitForFinished();
-        if (!reply.isError()) {  // enum devices
-            Q_FOREACH(const QDBusObjectPath &path, reply.value().keys()) {
-                const QString udi = path.path();
-
-                if (udi == UD2_DBUS_PATH_MANAGER || udi == UD2_UDI_DISKS_PREFIX || \
                udi.startsWith(UD2_DBUS_PATH_JOBS))
-                    continue;
-
-                Device device(udi);
-                if (device.drivePath() == dev->udi()) {
-                    m_devNum = device.prop("DeviceNumber").toULongLong();
-                    m_devFile = \
                QFile::decodeName(device.prop("Device").toByteArray());
-                    break;
+
+        if (reply.isValid()) {
+            QDomDocument dom;
+            dom.setContent(reply.value());
+            QDomNodeList nodeList = dom.documentElement().elementsByTagName("node");
+            for (int i = 0; i < nodeList.count(); i++) {
+                QDomElement nodeElem = nodeList.item(i).toElement();
+                if (!nodeElem.isNull() && nodeElem.hasAttribute("name")) {
+                    const QString udi = path + "/" + nodeElem.attribute("name");
+
+                    Device device(udi);
+                    if (device.drivePath() == dev->udi()) {
+                        m_devNum = device.prop("DeviceNumber").toULongLong();
+                        m_devFile = \
QFile::decodeName(device.prop("Device").toByteArray()); +                        \
break; +                    }
                 }
             }
         }
-        else  // show error
-        {
+        else
             qWarning() << "Failed enumerating UDisks2 objects:" << \
                reply.error().name() << "\n" << reply.error().message();
-        }
     }
 
     //qDebug() << "devnum:" << m_devNum << "dev file:" << m_devFile;
diff --git a/solid/solid/backends/udisks2/udisksmanager.cpp \
b/solid/solid/backends/udisks2/udisksmanager.cpp index 46d934e..fab5208 100644
--- a/solid/solid/backends/udisks2/udisksmanager.cpp
+++ b/solid/solid/backends/udisks2/udisksmanager.cpp
@@ -23,6 +23,7 @@
 #include <QtCore/QCoreApplication>
 #include <QtCore/QDebug>
 #include <QtDBus>
+#include <QtXml/QDomDocument>
 
 #include "../shared/rootdevice.h"
 
@@ -128,6 +129,7 @@ QStringList Manager::allDevices()
 {
     m_deviceCache.clear();
 
+#if 0
     QDBusPendingReply<DBUSManagerStruct> reply = m_manager.GetManagedObjects();
     reply.waitForFinished();
     if (!reply.isError()) {  // enum devices
@@ -156,9 +158,47 @@ QStringList Manager::allDevices()
         qWarning() << "Failed enumerating UDisks2 objects:" << reply.error().name() \
<< "\n" << reply.error().message();  }
 
+#endif
+
+    introspect("/org/freedesktop/UDisks2/block_devices", true /*checkOptical*/);
+    introspect("/org/freedesktop/UDisks2/drives");
+
     return m_deviceCache;
 }
 
+void Manager::introspect(const QString & path, bool checkOptical)
+{
+    QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path,
+                                                       DBUS_INTERFACE_INTROSPECT, \
"Introspect"); +    QDBusPendingReply<QString> reply = \
QDBusConnection::systemBus().asyncCall(call); +    reply.waitForFinished();
+
+    if (reply.isValid()) {
+        QDomDocument dom;
+        dom.setContent(reply.value());
+        QDomNodeList nodeList = dom.documentElement().elementsByTagName("node");
+        for (int i = 0; i < nodeList.count(); i++) {
+            QDomElement nodeElem = nodeList.item(i).toElement();
+            if (!nodeElem.isNull() && nodeElem.hasAttribute("name")) {
+                const QString udi = path + "/" + nodeElem.attribute("name");
+
+                if (checkOptical) {
+                    Device device(udi);
+                    if (device.mightBeOpticalDisc()) {
+                        QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, udi, \
DBUS_INTERFACE_PROPS, "PropertiesChanged", this, +                                    \
SLOT(slotMediaChanged(QDBusMessage))); +                        if \
(!device.isOpticalDisc())  // skip empty CD disc +                            \
continue; +                    }
+                }
+
+                m_deviceCache.append(udi);
+            }
+        }
+    }
+    else
+        qWarning() << "Failed enumerating UDisks2 objects:" << reply.error().name() \
<< "\n" << reply.error().message(); +}
 
 QSet< Solid::DeviceInterface::Type > Manager::supportedInterfaces() const
 {
@@ -226,3 +266,4 @@ const QStringList & Manager::deviceCache()
 
     return m_deviceCache;
 }
+
diff --git a/solid/solid/backends/udisks2/udisksmanager.h \
b/solid/solid/backends/udisks2/udisksmanager.h index 7cf0a72..fb929ce 100644
--- a/solid/solid/backends/udisks2/udisksmanager.h
+++ b/solid/solid/backends/udisks2/udisksmanager.h
@@ -58,6 +58,7 @@ private Q_SLOTS:
 
 private:
     const QStringList &deviceCache();
+    void introspect(const QString & path, bool checkOptical = false);
     QSet<Solid::DeviceInterface::Type> m_supportedInterfaces;
     org::freedesktop::DBus::ObjectManager m_manager;
     QStringList m_deviceCache;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic