FdoSecrets: cleanup all connections when database is replaced due to locking, fix #4004

This commit is contained in:
Aetf 2019-12-11 16:17:39 -05:00 committed by Jonathan White
parent 1ae7e72aa8
commit 98ff9f1e77
2 changed files with 30 additions and 9 deletions

View File

@ -469,14 +469,19 @@ namespace FdoSecrets
// Attach signal to update exposed group settings if the group was removed. // Attach signal to update exposed group settings if the group was removed.
// //
// The lifetime of the connection is bound to the database object, because // When the group object is normally deleted due to ~Database, the databaseReplaced
// in Database::~Database, groups are also deleted as children, but we don't // signal should be first emitted, and we will clean up connection in reloadDatabase,
// want to trigger this. // so this handler won't be triggered.
// This works because the fact that QObject disconnects signals BEFORE deleting
// children.
QPointer<Database> db = m_backend->database().data(); QPointer<Database> db = m_backend->database().data();
connect(m_exposedGroup.data(), &Group::groupAboutToRemove, db, [db](Group* toBeRemoved) { connect(m_exposedGroup.data(), &Group::groupAboutToRemove, this, [this](Group* toBeRemoved) {
if (!db) { if (backendLocked()) {
return;
}
auto db = m_backend->database();
if (toBeRemoved->database() != db) {
// should not happen, but anyway.
// somehow our current database has been changed, and the old group is being deleted
// possibly logic changes in replaceDatabase.
return; return;
} }
auto uuid = FdoSecrets::settings()->exposedGroup(db); auto uuid = FdoSecrets::settings()->exposedGroup(db);
@ -496,7 +501,7 @@ namespace FdoSecrets
// Monitor exposed group settings // Monitor exposed group settings
connect(m_backend->database()->metadata()->customData(), &CustomData::customDataModified, this, [this]() { connect(m_backend->database()->metadata()->customData(), &CustomData::customDataModified, this, [this]() {
if (!m_exposedGroup || !m_backend) { if (!m_exposedGroup || backendLocked()) {
return; return;
} }
if (m_exposedGroup->uuid() == FdoSecrets::settings()->exposedGroup(m_backend->database())) { if (m_exposedGroup->uuid() == FdoSecrets::settings()->exposedGroup(m_backend->database())) {
@ -615,9 +620,13 @@ namespace FdoSecrets
void Collection::cleanupConnections() void Collection::cleanupConnections()
{ {
m_backend->database()->metadata()->customData()->disconnect(this);
if (m_exposedGroup) { if (m_exposedGroup) {
m_exposedGroup->disconnect(this); for (const auto group : m_exposedGroup->groupsRecursive(true)) {
group->disconnect(this);
} }
}
m_items.clear(); m_items.clear();
} }

View File

@ -158,6 +158,12 @@ namespace FdoSecrets
return std::move(m_value); return std::move(m_value);
} }
/**
* Get value or handle the error by the passed in dbus object
* @tparam P
* @param p
* @return
*/
template <typename P> T valueOrHandle(P* p) const& template <typename P> T valueOrHandle(P* p) const&
{ {
if (isError()) { if (isError()) {
@ -169,6 +175,12 @@ namespace FdoSecrets
return m_value; return m_value;
} }
/**
* Get value or handle the error by the passed in dbus object
* @tparam P
* @param p
* @return
*/
template <typename P> T&& valueOrHandle(P* p) && template <typename P> T&& valueOrHandle(P* p) &&
{ {
if (isError()) { if (isError()) {