Rewrite QDBusConnection::unregisterObject to be recursive
The current implementation is a loop. We need it to be recursive so that we can execute more operations when unwinding. This will be necessary in the next commit. Change-Id: Ia3c98fed0719cede0a0d92d3e343cf016ec7baf2 Reviewed-by: David Faure (KDE) <faure@kde.org>
This commit is contained in:
parent
f8b681deed
commit
18c7ce5994
@ -883,35 +883,8 @@ void QDBusConnection::unregisterObject(const QString &path, UnregisterMode mode)
|
||||
if (!d || !d->connection || !QDBusUtil::isValidObjectPath(path))
|
||||
return;
|
||||
|
||||
QStringList pathComponents = path.split(QLatin1Char('/'));
|
||||
QDBusWriteLocker locker(UnregisterObjectAction, d);
|
||||
QDBusConnectionPrivate::ObjectTreeNode *node = &d->rootNode;
|
||||
int i = 1;
|
||||
|
||||
// find the object
|
||||
while (node) {
|
||||
if (pathComponents.count() == i || !path.compare(QLatin1String("/"))) {
|
||||
// found it
|
||||
node->obj = 0;
|
||||
node->flags = 0;
|
||||
|
||||
if (mode == UnregisterTree) {
|
||||
// clear the sub-tree as well
|
||||
node->children.clear(); // can't disconnect the objects because we really don't know if they can
|
||||
// be found somewhere else in the path too
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it =
|
||||
std::lower_bound(node->children.begin(), node->children.end(), pathComponents.at(i));
|
||||
if (it == node->children.end() || it->name != pathComponents.at(i))
|
||||
break; // node not found
|
||||
|
||||
node = it;
|
||||
++i;
|
||||
}
|
||||
d->unregisterObject(path, mode);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -208,6 +208,7 @@ public:
|
||||
const QString &name, const QStringList &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot);
|
||||
void registerObject(const ObjectTreeNode *node);
|
||||
void unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode);
|
||||
void connectRelay(const QString &service,
|
||||
const QString &path, const QString &interface,
|
||||
QDBusAbstractInterface *receiver, const QMetaMethod &signal);
|
||||
|
@ -600,6 +600,31 @@ static void huntAndDestroy(QObject *needle, QDBusConnectionPrivate::ObjectTreeNo
|
||||
}
|
||||
}
|
||||
|
||||
static void huntAndUnregister(const QStringList &pathComponents, int i, QDBusConnection::UnregisterMode mode,
|
||||
QDBusConnectionPrivate::ObjectTreeNode *node)
|
||||
{
|
||||
if (pathComponents.count() == i) {
|
||||
// found it
|
||||
node->obj = 0;
|
||||
node->flags = 0;
|
||||
|
||||
if (mode == QDBusConnection::UnregisterTree) {
|
||||
// clear the sub-tree as well
|
||||
node->children.clear(); // can't disconnect the objects because we really don't know if they can
|
||||
// be found somewhere else in the path too
|
||||
}
|
||||
} else {
|
||||
// keep going
|
||||
QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = node->children.end();
|
||||
QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it =
|
||||
std::lower_bound(node->children.begin(), end, pathComponents.at(i));
|
||||
if (it == end || it->name != pathComponents.at(i))
|
||||
return; // node not found
|
||||
|
||||
huntAndUnregister(pathComponents, i + 1, mode, it);
|
||||
}
|
||||
}
|
||||
|
||||
static void huntAndEmit(DBusConnection *connection, DBusMessage *msg,
|
||||
QObject *needle, const QDBusConnectionPrivate::ObjectTreeNode &haystack,
|
||||
bool isScriptable, bool isAdaptor, const QString &path = QString())
|
||||
@ -2266,6 +2291,21 @@ void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node)
|
||||
cleanupDeletedNodes(rootNode);
|
||||
}
|
||||
|
||||
void QDBusConnectionPrivate::unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode)
|
||||
{
|
||||
QDBusConnectionPrivate::ObjectTreeNode *node = &rootNode;
|
||||
QStringList pathComponents;
|
||||
int i;
|
||||
if (path == QLatin1String("/")) {
|
||||
i = 0;
|
||||
} else {
|
||||
pathComponents = path.split(QLatin1Char('/'));
|
||||
i = 1;
|
||||
}
|
||||
|
||||
huntAndUnregister(pathComponents, i, mode, node);
|
||||
}
|
||||
|
||||
void QDBusConnectionPrivate::connectRelay(const QString &service,
|
||||
const QString &path, const QString &interface,
|
||||
QDBusAbstractInterface *receiver,
|
||||
|
Loading…
Reference in New Issue
Block a user