This commit is contained in:
Rex Dieter 2012-12-19 14:23:41 -06:00
parent e1df9fddb3
commit 75d16d2d7b
6 changed files with 7 additions and 897 deletions

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
/kdelibs-4.8.5.tar.xz
/kdelibs-4.9.4.tar.xz
/kdelibs-4.9.90.tar.xz
/kdelibs-4.9.95.tar.xz

View File

@ -1,744 +0,0 @@
From be5ca0c8406d82af0cfb8f8a250410399873b76d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Vr=C3=A1til?= <dvratil@redhat.com>
Date: Mon, 3 Dec 2012 15:42:32 +0100
Subject: [PATCH 03/26] Cache UDisks2 Device DBus connections
Cache the QDBusInterface connection for each UDI so that
it's not recreated every time Solid::Device is constructed.
This greatly reduces the number of DBus calls and makes
the UDisks2 backend much faster.
---
solid/solid/CMakeLists.txt | 1 +
solid/solid/backends/udisks2/udisksdevice.cpp | 212 +++++-------------
solid/solid/backends/udisks2/udisksdevice.h | 19 +-
.../solid/backends/udisks2/udisksdevicebackend.cpp | 239 +++++++++++++++++++++
solid/solid/backends/udisks2/udisksdevicebackend.h | 84 ++++++++
solid/solid/backends/udisks2/udisksmanager.cpp | 16 +-
.../solid/backends/udisks2/udisksopticaldrive.cpp | 6 +-
7 files changed, 405 insertions(+), 172 deletions(-)
create mode 100644 solid/solid/backends/udisks2/udisksdevicebackend.cpp
create mode 100644 solid/solid/backends/udisks2/udisksdevicebackend.h
diff --git a/solid/solid/CMakeLists.txt b/solid/solid/CMakeLists.txt
index 5cd1484..b7dcc97 100644
--- a/solid/solid/CMakeLists.txt
+++ b/solid/solid/CMakeLists.txt
@@ -272,6 +272,7 @@ if(NOT WIN32 AND NOT APPLE)
set(solid_LIB_SRCS ${solid_LIB_SRCS}
backends/udisks2/udisksmanager.cpp
backends/udisks2/udisksdevice.cpp
+ backends/udisks2/udisksdevicebackend.cpp
backends/udisks2/udisksblock.cpp
backends/udisks2/udisksstoragevolume.cpp
backends/udisks2/udisksdeviceinterface.cpp
diff --git a/solid/solid/backends/udisks2/udisksdevice.cpp b/solid/solid/backends/udisks2/udisksdevice.cpp
index 3508d57..2a4313a 100644
--- a/solid/solid/backends/udisks2/udisksdevice.cpp
+++ b/solid/solid/backends/udisks2/udisksdevice.cpp
@@ -20,6 +20,7 @@
*/
#include "udisksdevice.h"
+#include "udisksdevicebackend.h"
#include "udisksblock.h"
#include "udisksdeviceinterface.h"
#include "udisksstoragevolume.h"
@@ -91,29 +92,72 @@ static QString formatByteSize(double size)
Device::Device(const QString &udi)
: Solid::Ifaces::Device()
- , m_udi(udi)
- , m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, "Solid::Udisks2::Device::" + udi))
+ , m_backend(DeviceBackend::backendForUDI(udi))
{
- m_device = new QDBusInterface(UD2_DBUS_SERVICE, m_udi,
- QString(), // no interface, we aggregate them
- m_connection);
+ if (m_backend) {
+ connect(m_backend, SIGNAL(changed()), this, SIGNAL(changed()));
+ connect(m_backend, SIGNAL(propertyChanged(QMap<QString,int>)), this, SIGNAL(propertyChanged(QMap<QString,int>)));
+ } else {
+ qDebug() << "Created invalid Device for udi" << udi;
+ }
+}
+
+Device::~Device()
+{
+}
+
+QString Device::udi() const
+{
+ if (m_backend) {
+ return m_backend->udi();
+ }
+
+ return QString();
+}
- if (m_device->isValid()) {
- m_connection.connect(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
- SLOT(slotPropertiesChanged(QString,QVariantMap,QStringList)));
+QVariant Device::prop(const QString &key) const
+{
+ if (m_backend) {
+ return m_backend->prop(key);
+ }
- m_connection.connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesAdded",
- this, SLOT(slotInterfacesAdded(QDBusObjectPath,QVariantMapMap)));
- m_connection.connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesRemoved",
- this, SLOT(slotInterfacesRemoved(QDBusObjectPath,QStringList)));
+ return QVariant();
+}
- initInterfaces();
+bool Device::propertyExists(const QString &key) const
+{
+ if (m_backend) {
+ return m_backend->propertyExists(key);
}
+
+ return false;
}
-Device::~Device()
+QVariantMap Device::allProperties() const
{
- delete m_device;
+ if (m_backend) {
+ return m_backend->allProperties();
+ }
+
+ return QVariantMap();
+}
+
+bool Device::hasInterface(const QString &name) const
+{
+ if (m_backend) {
+ return m_backend->interfaces().contains(name);
+ }
+
+ return false;
+}
+
+QStringList Device::interfaces() const
+{
+ if (m_backend) {
+ return m_backend->interfaces();
+ }
+
+ return QStringList();
}
QObject* Device::createDeviceInterface(const Solid::DeviceInterface::Type& type)
@@ -637,11 +681,6 @@ QString Device::vendor() const
return prop("Vendor").toString();
}
-QString Device::udi() const
-{
- return m_udi;
-}
-
QString Device::parentUdi() const
{
QString parent;
@@ -656,139 +695,6 @@ QString Device::parentUdi() const
return parent;
}
-void Device::checkCache(const QString &key) const
-{
- if (m_cache.isEmpty()) // recreate the cache
- allProperties();
-
- if (m_cache.contains(key))
- return;
-
- QVariant reply = m_device->property(key.toUtf8());
-
- if (reply.isValid()) {
- m_cache.insert(key, reply);
- } else {
- //qDebug() << "got invalid reply for cache:" << key;
- }
-}
-
-QString Device::introspect() const
-{
- QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi,
- DBUS_INTERFACE_INTROSPECT, "Introspect");
- QDBusPendingReply<QString> reply = m_connection.asyncCall(call);
- reply.waitForFinished();
-
- if (reply.isValid())
- return reply.value();
- else {
- return QString();
- }
-}
-
-QVariant Device::prop(const QString &key) const
-{
- checkCache(key);
- return m_cache.value(key);
-}
-
-bool Device::propertyExists(const QString &key) const
-{
- checkCache(key);
- return m_cache.contains(key);
-}
-
-QVariantMap Device::allProperties() const
-{
- QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "GetAll");
-
- Q_FOREACH (const QString & iface, m_interfaces) {
- if (iface.startsWith("org.freedesktop.DBus"))
- continue;
- call.setArguments(QVariantList() << iface);
- QDBusPendingReply<QVariantMap> reply = m_connection.asyncCall(call);
- reply.waitForFinished();
-
- if (reply.isValid())
- m_cache.unite(reply.value());
- else
- qWarning() << "Error getting props:" << reply.error().name() << reply.error().message();
- //qDebug() << "After iface" << iface << ", cache now contains" << m_cache.size() << "items";
- }
-
- return m_cache;
-}
-
-bool Device::hasInterface(const QString &name) const
-{
- return m_interfaces.contains(name);
-}
-
-QStringList Device::interfaces() const
-{
- return m_interfaces;
-}
-
-void Device::initInterfaces()
-{
- m_interfaces.clear();
- const QString xmlData = introspect();
- QDomDocument dom;
- dom.setContent(xmlData);
- QDomNodeList ifaceNodeList = dom.elementsByTagName("interface");
- for (int i = 0; i < ifaceNodeList.count(); i++) {
- QDomElement ifaceElem = ifaceNodeList.item(i).toElement();
- if (!ifaceElem.isNull())
- m_interfaces.append(ifaceElem.attribute("name"));
- }
- //qDebug() << "Device" << m_udi << "has interfaces:" << m_interfaces;
-}
-
-void Device::slotPropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps)
-{
- //Q_UNUSED(ifaceName);
-
- qDebug() << m_udi << "'s interface" << ifaceName << "changed props:";
-
- QMap<QString, int> changeMap;
-
- Q_FOREACH(const QString & key, invalidatedProps) {
- m_cache.remove(key);
- changeMap.insert(key, Solid::GenericInterface::PropertyRemoved);
- qDebug() << "\t invalidated:" << key;
- }
-
- QMapIterator<QString, QVariant> i(changedProps);
- while (i.hasNext()) {
- i.next();
- const QString key = i.key();
- m_cache.insert(key, i.value()); // replace the value
- changeMap.insert(key, Solid::GenericInterface::PropertyModified);
- qDebug() << "\t modified:" << key << ":" << m_cache.value(key);
- }
-
- Q_EMIT propertyChanged(changeMap);
- Q_EMIT changed();
-}
-
-void Device::slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties)
-{
- if (object_path.path() == m_udi) {
- m_interfaces.append(interfaces_and_properties.keys());
- }
-}
-
-void Device::slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces)
-{
- if (object_path.path() == m_udi) {
- Q_FOREACH(const QString & iface, interfaces) {
- m_interfaces.removeAll(iface);
- }
- }
-}
-
-
QString Device::errorToString(const QString & error) const
{
if (error == UD2_ERROR_UNAUTHORIZED || error == UD2_ERROR_NOT_AUTHORIZED)
diff --git a/solid/solid/backends/udisks2/udisksdevice.h b/solid/solid/backends/udisks2/udisksdevice.h
index ee6bc1b..6038178 100644
--- a/solid/solid/backends/udisks2/udisksdevice.h
+++ b/solid/solid/backends/udisks2/udisksdevice.h
@@ -39,6 +39,8 @@ namespace Backends
namespace UDisks2
{
+class DeviceBackend;
+
class Device: public Solid::Ifaces::Device
{
Q_OBJECT
@@ -87,25 +89,12 @@ Q_SIGNALS:
void changed();
void propertyChanged(const QMap<QString,int> &changes);
-private Q_SLOTS:
- void slotPropertiesChanged(const QString & ifaceName, const QVariantMap & changedProps, const QStringList & invalidatedProps);
- void slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties);
- void slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces);
+protected:
+ QPointer<DeviceBackend> m_backend;
private:
QString storageDescription() const;
QString volumeDescription() const;
- mutable QDBusInterface *m_device;
- QString m_udi;
- mutable QVariantMap m_cache;
-
- void initInterfaces();
- QStringList m_interfaces;
-
- void checkCache(const QString &key) const;
- QString introspect() const;
-
- QDBusConnection m_connection;
};
}
diff --git a/solid/solid/backends/udisks2/udisksdevicebackend.cpp b/solid/solid/backends/udisks2/udisksdevicebackend.cpp
new file mode 100644
index 0000000..74d202c
--- /dev/null
+++ b/solid/solid/backends/udisks2/udisksdevicebackend.cpp
@@ -0,0 +1,239 @@
+/*
+ Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+ Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+ Copyright 2012 Dan Vrátil <dvratil@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "udisksdevicebackend.h"
+
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusInterface>
+#include <QtXml/QDomDocument>
+
+#include "solid/deviceinterface.h"
+#include "solid/genericinterface.h"
+
+using namespace Solid::Backends::UDisks2;
+
+/* Static cache for DeviceBackends for all UDIs */
+QMap<QString /* UDI */, DeviceBackend*> DeviceBackend::s_backends;
+
+DeviceBackend* DeviceBackend::backendForUDI(const QString& udi)
+{
+ DeviceBackend *backend = 0;
+ if (udi.isEmpty()) {
+ return backend;
+ }
+
+ if (s_backends.contains(udi)) {
+ backend = s_backends.value(udi);
+ } else {
+ backend = new DeviceBackend(udi);
+ s_backends.insert(udi, backend);
+ }
+
+ return backend;
+}
+
+void DeviceBackend::destroyBackend(const QString& udi)
+{
+ if (s_backends.contains(udi)) {
+ DeviceBackend *backend = s_backends.value(udi);
+ s_backends.remove(udi);
+ delete backend;
+ }
+}
+
+DeviceBackend::DeviceBackend(const QString& udi)
+ : m_udi(udi)
+{
+ qDebug() << "Creating backend for device" << m_udi;
+ m_device = new QDBusInterface(UD2_DBUS_SERVICE, m_udi,
+ QString(), // no interface, we aggregate them
+ QDBusConnection::systemBus(), this);
+
+ if (m_device->isValid()) {
+ QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
+ SLOT(slotPropertiesChanged(QString,QVariantMap,QStringList)));
+ QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesAdded",
+ this, SLOT(slotInterfacesAdded(QDBusObjectPath,QVariantMapMap)));
+ QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesRemoved",
+ this, SLOT(slotInterfacesRemoved(QDBusObjectPath,QStringList)));
+
+ initInterfaces();
+ }
+}
+
+DeviceBackend::~DeviceBackend()
+{
+ qDebug() << "Destroying backend for device" << m_udi;
+}
+
+void DeviceBackend::initInterfaces()
+{
+ m_interfaces.clear();
+
+ const QString xmlData = introspect();
+ if (xmlData.isEmpty()) {
+ qDebug() << m_udi << "has no interfaces!";
+ return;
+ }
+
+ QDomDocument dom;
+ dom.setContent(xmlData);
+
+ QDomNodeList ifaceNodeList = dom.elementsByTagName("interface");
+ for (int i = 0; i < ifaceNodeList.count(); i++) {
+ QDomElement ifaceElem = ifaceNodeList.item(i).toElement();
+ /* Accept only org.freedesktop.UDisks2.* interfaces so that when the device is unplugged,
+ * m_interfaces goes empty and we can easily verify that the device is gone. */
+ if (!ifaceElem.isNull() && ifaceElem.attribute("name").startsWith(UD2_DBUS_SERVICE)) {
+ m_interfaces.append(ifaceElem.attribute("name"));
+ }
+ }
+
+ qDebug() << m_udi << "has interfaces:" << m_interfaces;
+}
+
+QStringList DeviceBackend::interfaces() const
+{
+ return m_interfaces;
+}
+
+const QString& DeviceBackend::udi() const
+{
+ return m_udi;
+}
+
+QVariant DeviceBackend::prop(const QString& key) const
+{
+ checkCache(key);
+ return m_propertyCache.value(key);
+}
+
+bool DeviceBackend::propertyExists(const QString& key) const
+{
+ checkCache(key);
+ /* checkCache() will put an invalid QVariant in cache when the property
+ * does not exist, so check for validity, not for an actual presence. */
+ return m_propertyCache.value(key).isValid();
+}
+
+QVariantMap DeviceBackend::allProperties() const
+{
+ QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "GetAll");
+
+ Q_FOREACH (const QString & iface, m_interfaces) {
+ call.setArguments(QVariantList() << iface);
+ QDBusPendingReply<QVariantMap> reply = QDBusConnection::systemBus().call(call);
+
+ if (reply.isValid()) {
+ m_propertyCache.unite(reply.value());
+ } else {
+ qWarning() << "Error getting props:" << reply.error().name() << reply.error().message();
+ }
+ //qDebug() << "After iface" << iface << ", cache now contains" << m_cache.size() << "items";
+ }
+
+ return m_propertyCache;
+}
+
+QString DeviceBackend::introspect() const
+{
+ QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi,
+ DBUS_INTERFACE_INTROSPECT, "Introspect");
+ QDBusPendingReply<QString> reply = QDBusConnection::systemBus().call(call);
+
+ if (reply.isValid())
+ return reply.value();
+ else {
+ return QString();
+ }
+}
+
+void DeviceBackend::checkCache(const QString& key) const
+{
+ if (m_propertyCache.isEmpty()) { // recreate the cache
+ allProperties();
+ }
+
+ if (m_propertyCache.contains(key)) {
+ return;
+ }
+
+ QVariant reply = m_device->property(key.toUtf8());
+ m_propertyCache.insert(key, reply);
+
+ if (!reply.isValid()) {
+ /* Store the item in the cache anyway so next time we don't have to
+ * do the DBus call to find out it does not exist but just check whether
+ * prop(key).isValid() */
+ qDebug() << m_udi << ": property" << key << "does not exist";
+ }
+}
+
+void DeviceBackend::slotPropertiesChanged(const QString& ifaceName, const QVariantMap& changedProps, const QStringList& invalidatedProps)
+{
+ qDebug() << m_udi << "'s interface" << ifaceName << "changed props:";
+
+ QMap<QString, int> changeMap;
+
+ Q_FOREACH(const QString & key, invalidatedProps) {
+ m_propertyCache.remove(key);
+ changeMap.insert(key, Solid::GenericInterface::PropertyRemoved);
+ qDebug() << "\t invalidated:" << key;
+ }
+
+ QMapIterator<QString, QVariant> i(changedProps);
+ while (i.hasNext()) {
+ i.next();
+ const QString key = i.key();
+ m_propertyCache.insert(key, i.value()); // replace the value
+ changeMap.insert(key, Solid::GenericInterface::PropertyModified);
+ qDebug() << "\t modified:" << key << ":" << m_propertyCache.value(key);
+ }
+
+ Q_EMIT propertyChanged(changeMap);
+ Q_EMIT changed();
+}
+
+void DeviceBackend::slotInterfacesAdded(const QDBusObjectPath& object_path, const QVariantMapMap& interfaces_and_properties)
+{
+ if (object_path.path() != m_udi) {
+ return;
+ }
+
+ Q_FOREACH(const QString & iface, interfaces_and_properties.keys()) {
+ /* Don't store generic DBus interfaces */
+ if (iface.startsWith(UD2_DBUS_SERVICE)) {
+ m_interfaces.append(interfaces_and_properties.keys());
+ }
+ }
+}
+
+void DeviceBackend::slotInterfacesRemoved(const QDBusObjectPath& object_path, const QStringList& interfaces)
+{
+ if (object_path.path() == m_udi) {
+ return;
+ }
+
+ Q_FOREACH(const QString & iface, interfaces) {
+ m_interfaces.removeAll(iface);
+ }
+}
diff --git a/solid/solid/backends/udisks2/udisksdevicebackend.h b/solid/solid/backends/udisks2/udisksdevicebackend.h
new file mode 100644
index 0000000..829fa41
--- /dev/null
+++ b/solid/solid/backends/udisks2/udisksdevicebackend.h
@@ -0,0 +1,84 @@
+/*
+ Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+ Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+ Copyright 2012 Dan Vrátil <dvratil@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKSDEVICEBACKEND_H
+#define UDISKSDEVICEBACKEND_H
+
+#include <QObject>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusInterface>
+#include <QStringList>
+
+#include "udisks2.h"
+
+namespace Solid {
+namespace Backends {
+namespace UDisks2 {
+
+class DeviceBackend: public QObject {
+
+ Q_OBJECT
+
+ public:
+ static DeviceBackend* backendForUDI(const QString &udi);
+ static void destroyBackend(const QString &udi);
+
+ DeviceBackend(const QString &udi);
+ ~DeviceBackend();
+
+ QVariant prop(const QString &key) const;
+ bool propertyExists(const QString &key) const;
+ QVariantMap allProperties() const;
+
+ QStringList interfaces() const;
+ const QString & udi() const;
+
+ Q_SIGNALS:
+ void propertyChanged(const QMap<QString, int> &changeMap);
+ void changed();
+
+ private Q_SLOTS:
+ void slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties);
+ void slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces);
+ void slotPropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps);
+
+ private:
+ void initInterfaces();
+ QString introspect() const;
+ void checkCache(const QString &key) const;
+
+ QDBusInterface *m_device;
+
+ mutable QVariantMap m_propertyCache;
+ QStringList m_interfaces;
+ QString m_udi;
+
+ static QMap<QString, DeviceBackend*> s_backends;
+
+};
+
+} /* namespace UDisks2 */
+} /* namespace Backends */
+} /* namespace Solid */
+
+#endif /* UDISKSDEVICEBACKEND_H */
\ No newline at end of file
diff --git a/solid/solid/backends/udisks2/udisksmanager.cpp b/solid/solid/backends/udisks2/udisksmanager.cpp
index e781abb..1cc150c 100644
--- a/solid/solid/backends/udisks2/udisksmanager.cpp
+++ b/solid/solid/backends/udisks2/udisksmanager.cpp
@@ -19,6 +19,7 @@
*/
#include "udisksmanager.h"
+#include "udisksdevicebackend.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
@@ -77,6 +78,10 @@ Manager::Manager(QObject *parent)
Manager::~Manager()
{
+ while (!m_deviceCache.isEmpty()) {
+ QString udi = m_deviceCache.takeFirst();
+ DeviceBackend::destroyBackend(udi);
+ }
}
QObject* Manager::createDevice(const QString& udi)
@@ -128,7 +133,11 @@ QStringList Manager::devicesFromQuery(const QString& parentUdi, Solid::DeviceInt
QStringList Manager::allDevices()
{
- m_deviceCache.clear();
+ /* Clear the cache, destroy all backends */
+ while (!m_deviceCache.isEmpty()) {
+ QString udi= m_deviceCache.takeFirst();
+ DeviceBackend::destroyBackend(udi);
+ }
introspect("/org/freedesktop/UDisks2/block_devices", true /*checkOptical*/);
introspect("/org/freedesktop/UDisks2/drives");
@@ -140,8 +149,7 @@ 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();
+ QDBusPendingReply<QString> reply = QDBusConnection::systemBus().call(call);
if (reply.isValid()) {
QDomDocument dom;
@@ -204,6 +212,7 @@ void Manager::slotInterfacesRemoved(const QDBusObjectPath &object_path, const QS
if (!udi.isEmpty() && (interfaces.isEmpty() || device.interfaces().isEmpty() || device.interfaces().contains(UD2_DBUS_INTERFACE_FILESYSTEM))) {
Q_EMIT deviceRemoved(udi);
m_deviceCache.removeAll(udi);
+ DeviceBackend::destroyBackend(udi);
}
}
@@ -226,6 +235,7 @@ void Manager::slotMediaChanged(const QDBusMessage & msg)
if (m_deviceCache.contains(udi) && size == 0) { // we know the optdisc, got removed
Q_EMIT deviceRemoved(udi);
m_deviceCache.removeAll(udi);
+ DeviceBackend::destroyBackend(udi);
}
}
diff --git a/solid/solid/backends/udisks2/udisksopticaldrive.cpp b/solid/solid/backends/udisks2/udisksopticaldrive.cpp
index 8ad3df0..4df18b1 100644
--- a/solid/solid/backends/udisks2/udisksopticaldrive.cpp
+++ b/solid/solid/backends/udisks2/udisksopticaldrive.cpp
@@ -38,7 +38,11 @@
using namespace Solid::Backends::UDisks2;
OpticalDrive::OpticalDrive(Device *device)
- : StorageDrive(device), m_ejectInProgress(false), m_readSpeed(0), m_writeSpeed(0), m_speedsInit(false)
+ : StorageDrive(device)
+ , m_ejectInProgress(false)
+ , m_readSpeed(0)
+ , m_writeSpeed(0)
+ , m_speedsInit(false)
{
m_device->registerAction("eject", this,
SLOT(slotEjectRequested()),
--
1.8.0.2

View File

@ -1,101 +0,0 @@
From 098fe7e322ad6d0c2af1a9ec0dd3131a0e69aaf8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Vr=C3=A1til?= <dvratil@redhat.com>
Date: Mon, 3 Dec 2012 16:40:37 +0100
Subject: [PATCH 06/26] Use QDBusConnection::systemBus() instead of custom
connection
Leftover from previous patch for Solid's UDisks2 backend.
---
solid/solid/backends/udisks2/udisksblock.cpp | 5 ++---
solid/solid/backends/udisks2/udisksblock.h | 1 -
solid/solid/backends/udisks2/udisksmanager.cpp | 9 ++++-----
solid/solid/backends/udisks2/udisksmanager.h | 1 -
4 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/solid/solid/backends/udisks2/udisksblock.cpp b/solid/solid/backends/udisks2/udisksblock.cpp
index 027ea03..f3cd1e8 100644
--- a/solid/solid/backends/udisks2/udisksblock.cpp
+++ b/solid/solid/backends/udisks2/udisksblock.cpp
@@ -30,8 +30,7 @@
using namespace Solid::Backends::UDisks2;
Block::Block(Device *dev)
- : DeviceInterface(dev),
- m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, "Solid::Udisks2::Block::" + dev->udi()))
+ : DeviceInterface(dev)
{
m_devNum = m_device->prop("DeviceNumber").toULongLong();
m_devFile = QFile::decodeName(m_device->prop("Device").toByteArray());
@@ -41,7 +40,7 @@ Block::Block(Device *dev)
const QString path = "/org/freedesktop/UDisks2/block_devices";
QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path,
DBUS_INTERFACE_INTROSPECT, "Introspect");
- QDBusPendingReply<QString> reply = m_connection.asyncCall(call);
+ QDBusPendingReply<QString> reply = QDBusConnection::systemBus().asyncCall(call);
reply.waitForFinished();
if (reply.isValid()) {
diff --git a/solid/solid/backends/udisks2/udisksblock.h b/solid/solid/backends/udisks2/udisksblock.h
index 65ef2b8..19cb70a 100644
--- a/solid/solid/backends/udisks2/udisksblock.h
+++ b/solid/solid/backends/udisks2/udisksblock.h
@@ -45,7 +45,6 @@ public:
virtual int deviceMinor() const;
virtual int deviceMajor() const;
private:
- QDBusConnection m_connection;
dev_t m_devNum;
QString m_devFile;
};
diff --git a/solid/solid/backends/udisks2/udisksmanager.cpp b/solid/solid/backends/udisks2/udisksmanager.cpp
index 1cc150c..35b0d23 100644
--- a/solid/solid/backends/udisks2/udisksmanager.cpp
+++ b/solid/solid/backends/udisks2/udisksmanager.cpp
@@ -33,10 +33,9 @@ using namespace Solid::Backends::Shared;
Manager::Manager(QObject *parent)
: Solid::Ifaces::DeviceManager(parent),
- m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, "Solid::Udisks2")),
m_manager(UD2_DBUS_SERVICE,
UD2_DBUS_PATH,
- m_connection)
+ QDBusConnection::systemBus())
{
m_supportedInterfaces
<< Solid::DeviceInterface::GenericInterface
@@ -61,9 +60,9 @@ Manager::Manager(QObject *parent)
"org.freedesktop.DBus",
"ListActivatableNames");
- QDBusReply<QStringList> reply = m_connection.call(message);
+ QDBusReply<QStringList> reply = QDBusConnection::systemBus().call(message);
if (reply.isValid() && reply.value().contains(UD2_DBUS_SERVICE)) {
- m_connection.interface()->startService(UD2_DBUS_SERVICE);
+ QDBusConnection::systemBus().interface()->startService(UD2_DBUS_SERVICE);
serviceFound = true;
}
}
@@ -163,7 +162,7 @@ void Manager::introspect(const QString & path, bool checkOptical)
if (checkOptical) {
Device device(udi);
if (device.mightBeOpticalDisc()) {
- m_connection.connect(UD2_DBUS_SERVICE, udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
+ QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
SLOT(slotMediaChanged(QDBusMessage)));
if (!device.isOpticalDisc()) // skip empty CD disc
continue;
diff --git a/solid/solid/backends/udisks2/udisksmanager.h b/solid/solid/backends/udisks2/udisksmanager.h
index bf74703..fb929ce 100644
--- a/solid/solid/backends/udisks2/udisksmanager.h
+++ b/solid/solid/backends/udisks2/udisksmanager.h
@@ -60,7 +60,6 @@ private:
const QStringList &deviceCache();
void introspect(const QString & path, bool checkOptical = false);
QSet<Solid::DeviceInterface::Type> m_supportedInterfaces;
- QDBusConnection m_connection;
org::freedesktop::DBus::ObjectManager m_manager;
QStringList m_deviceCache;
};
--
1.8.0.2

View File

@ -1,41 +0,0 @@
From f883796dff6956c51d2b2494a600a935bd910a5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Vr=C3=A1til?= <dvratil@redhat.com>
Date: Mon, 3 Dec 2012 16:57:05 +0100
Subject: [PATCH 07/26] Ignore UDisks2 jobs
Jobs don't represent any devices, so we can just ignore them.
---
solid/solid/backends/udisks2/udisksmanager.cpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/solid/solid/backends/udisks2/udisksmanager.cpp b/solid/solid/backends/udisks2/udisksmanager.cpp
index 35b0d23..ecb9add 100644
--- a/solid/solid/backends/udisks2/udisksmanager.cpp
+++ b/solid/solid/backends/udisks2/udisksmanager.cpp
@@ -191,6 +191,11 @@ void Manager::slotInterfacesAdded(const QDBusObjectPath &object_path, const QVar
{
const QString udi = object_path.path();
+ /* Ignore jobs */
+ if (udi.startsWith(UD2_DBUS_PATH_JOBS)) {
+ return;
+ }
+
qDebug() << udi << "has new interfaces:" << interfaces_and_properties.keys();
// new device, we don't know it yet
@@ -204,6 +209,11 @@ void Manager::slotInterfacesRemoved(const QDBusObjectPath &object_path, const QS
{
const QString udi = object_path.path();
+ /* Ignore jobs */
+ if (udi.startsWith(UD2_DBUS_PATH_JOBS)) {
+ return;
+ }
+
qDebug() << udi << "lost interfaces:" << interfaces;
Device device(udi);
--
1.8.0.2

View File

@ -22,8 +22,8 @@
%global dbusmenu_qt_version %(pkg-config --modversion dbusmenu-qt 2>/dev/null || echo %{dbusmenu_qt_ver})
Summary: KDE Libraries
Version: 4.9.90
Release: 4%{?dist}
Version: 4.9.95
Release: 1%{?dist}
Name: kdelibs
Epoch: 6
@ -145,10 +145,6 @@ Patch56: kdelibs-4.9.1-FindKipi-libkipi2.patch
Patch59: kdelibs-4.9.3-kcm_ssl.patch
## upstream
# since 4.9.90, solid/udisk2 related fixes
Patch103: 0003-Cache-UDisks2-Device-DBus-connections.patch
Patch106: 0006-Use-QDBusConnection-systemBus-instead-of-custom-conn.patch
Patch107: 0007-Ignore-UDisks2-jobs.patch
## security fix
# Not Upstreamed? why not ? -- Rex
@ -319,9 +315,6 @@ sed -i -e "s|@@VERSION_RELEASE@@|%{version}-%{release}|" kio/kio/kprotocolmanage
%patch59 -p1 -b .filter
# upstream patches
%patch103 -p1 -b .0003
%patch106 -p1 -b .0006
%patch107 -p1 -b .0007
# security fixes
%patch200 -p1 -b .CVE-2009-2702
@ -568,6 +561,9 @@ gtk-update-icon-cache %{_kde4_iconsdir}/hicolor &> /dev/null || :
%changelog
* Wed Dec 19 2012 Rex Dieter <rdieter@fedoraproject.org> - 6:4.9.95-1
- 4.9.95
* Thu Dec 13 2012 Rex Dieter <rdieter@fedoraproject.org> 6:4.9.90-4
- prune/fix changelog

View File

@ -1 +1 @@
94c892cbe5eaf180ad18cba7c6d225be kdelibs-4.9.90.tar.xz
2d7e329a1f6a110a7ddbc207dc3dc10f kdelibs-4.9.95.tar.xz