Commit a283882e authored by chriadam's avatar chriadam

[qtcontacts-sqlite] Properly emit changes to display label groups. Contributes to JB#45836

Previously we emitted asynchronously before the transaction was
committed.  This commit ensures that we emit only if the transaction
is committed successfully by the writer thread, ensuring that there
is no race between readers attempting to access the updated
display label groups list, and the completion of the write.
parent 737cd106
......@@ -160,6 +160,12 @@ void ContactNotifier::relationshipsRemoved(const QSet<QContactId> &contactIds)
}
}
void ContactNotifier::displayLabelGroupsChanged()
{
QDBusMessage message = createSignal("displayLabelGroupsChanged", m_nonprivileged);
QDBusConnection::sessionBus().send(message);
}
bool ContactNotifier::connect(const char *name, const char *signature, QObject *receiver, const char *slot)
{
static QDBusConnection connection(QDBusConnection::sessionBus());
......
......@@ -55,6 +55,7 @@ public:
void selfContactIdChanged(QContactId oldId, QContactId newId);
void relationshipsAdded(const QSet<QContactId> &contactIds);
void relationshipsRemoved(const QSet<QContactId> &contactIds);
void displayLabelGroupsChanged();
bool connect(const char *name, const char *signature, QObject *receiver, const char *slot);
};
......
......@@ -1924,6 +1924,7 @@ static bool executeDisplayLabelGroupLocalizationStatements(QSqlDatabase &databas
}
// for every single contact in our database, read the data required to generate the display label group data.
bool emitDisplayLabelGroupChange = false;
QVariantList contactIds;
QVariantList displayLabelGroups;
QVariantList displayLabelGroupSortOrders;
......@@ -1959,7 +1960,7 @@ static bool executeDisplayLabelGroupLocalizationStatements(QSqlDatabase &databas
c.saveDetail(&n);
c.saveDetail(&dl);
const QString dlg = cdb->determineDisplayLabelGroup(c);
const QString dlg = cdb->determineDisplayLabelGroup(c, &emitDisplayLabelGroupChange);
displayLabelGroups.append(dlg);
displayLabelGroupSortOrders.append(cdb->displayLabelGroupSortValue(dlg));
}
......@@ -3473,7 +3474,7 @@ QString ContactsDatabase::displayLabelGroupPreferredProperty() const
return retn;
}
QString ContactsDatabase::determineDisplayLabelGroup(const QContact &c)
QString ContactsDatabase::determineDisplayLabelGroup(const QContact &c, bool *emitDisplayLabelGroupChange)
{
// Read system setting to determine whether display label group
// should be generated from last name, first name, or display label.
......@@ -3532,19 +3533,17 @@ QString ContactsDatabase::determineDisplayLabelGroup(const QContact &c)
}
}
if (!group.isEmpty() && !m_knownDisplayLabelGroupsSortValues.contains(group)) {
if (emitDisplayLabelGroupChange && !group.isEmpty() && !m_knownDisplayLabelGroupsSortValues.contains(group)) {
// We are about to write a contact to the database which has a
// display label group which previously was not known / observed.
// Calculate the sort value for the display label group,
// and add it to our map of displayLabelGroup->sortValue.
// Note: this should be thread-safe since we only call this method within writes.
*emitDisplayLabelGroupChange = true;
m_knownDisplayLabelGroupsSortValues.insert(
group, ::displayLabelGroupSortValue(
group,
m_knownDisplayLabelGroupsSortValues));
// and invoke engine->_q_displayLabelGroupsChanged() asynchronously.
QMetaObject::invokeMethod(m_engine, "_q_displayLabelGroupsChanged", Qt::QueuedConnection);
}
return group;
......
......@@ -159,7 +159,7 @@ public:
void regenerateDisplayLabelGroups();
QString displayLabelGroupPreferredProperty() const;
QString determineDisplayLabelGroup(const QContact &c);
QString determineDisplayLabelGroup(const QContact &c, bool *emitDisplayLabelGroupChange = Q_NULLPTR);
QStringList displayLabelGroups() const;
int displayLabelGroupSortValue(const QString &group) const;
......
......@@ -898,6 +898,7 @@ QContactManager::Error ContactsEngine::open()
m_notifier->connect("selfContactIdChanged", "uu", this, SLOT(_q_selfContactIdChanged(quint32,quint32)));
m_notifier->connect("relationshipsAdded", "au", this, SLOT(_q_relationshipsAdded(QVector<quint32>)));
m_notifier->connect("relationshipsRemoved", "au", this, SLOT(_q_relationshipsRemoved(QVector<quint32>)));
m_notifier->connect("displayLabelGroupsChanged", "", this, SLOT(_q_displayLabelGroupsChanged()));
}
} else {
QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Unable to open asynchronous engine database connection"));
......
......@@ -139,6 +139,7 @@ ContactWriter::ContactWriter(ContactsEngine &engine, ContactsDatabase &database,
, m_database(database)
, m_notifier(notifier)
, m_reader(reader)
, m_displayLabelGroupsChanged(false)
{
Q_ASSERT(notifier);
Q_ASSERT(reader);
......@@ -177,6 +178,10 @@ bool ContactWriter::commitTransaction()
return false;
}
if (m_displayLabelGroupsChanged) {
m_notifier->displayLabelGroupsChanged();
m_displayLabelGroupsChanged = false;
}
if (!m_addedIds.isEmpty()) {
m_notifier->contactsAdded(m_addedIds.toList());
m_addedIds.clear();
......@@ -218,6 +223,7 @@ void ContactWriter::rollbackTransaction()
m_presenceChangedIds.clear();
m_changedIds.clear();
m_addedIds.clear();
m_displayLabelGroupsChanged = false;
}
QContactManager::Error ContactWriter::setIdentity(ContactsDatabase::Identity identity, QContactId contactId)
......@@ -5591,7 +5597,7 @@ ContactsDatabase::Query ContactWriter::bindContactDetails(const QContact &contac
QContactDisplayLabel label = contact.detail<QContactDisplayLabel>();
const QString displayLabel = label.label().trimmed();
query.bindValue(0, displayLabel);
const QString displayLabelGroup = m_database.determineDisplayLabelGroup(contact);
const QString displayLabelGroup = m_database.determineDisplayLabelGroup(contact, &m_displayLabelGroupsChanged);
query.bindValue(1, displayLabelGroup);
const int displayLabelGroupSortOrder = m_database.displayLabelGroupSortValue(displayLabelGroup);
query.bindValue(2, displayLabelGroupSortOrder);
......
......@@ -172,6 +172,7 @@ private:
ContactNotifier *m_notifier;
ContactReader *m_reader;
bool m_displayLabelGroupsChanged;
QSet<QContactId> m_addedIds;
QSet<QContactId> m_removedIds;
QSet<QContactId> m_changedIds;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment