summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2020-11-25 23:43:31 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2020-11-25 23:54:25 +0100
commitc31b9e27939a2f756056a818d83c64c9e43b721d (patch)
treeae7b274ea984b419be0dc48cb585a4ea369243d3 /src
parent7cda502edd511c447790c02b787e0eb7748593b6 (diff)
Fix race when reading members from db
Diffstat (limited to 'src')
-rw-r--r--src/Cache.cpp27
-rw-r--r--src/ChatPage.cpp15
-rw-r--r--src/Utils.cpp30
-rw-r--r--src/Utils.h4
-rw-r--r--src/timeline/TimelineModel.cpp5
5 files changed, 52 insertions, 29 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp
index bd0f3733..be9af8ee 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -1162,10 +1162,10 @@ Cache::saveState(const mtx::responses::Sync &res)
saveTimelineMessages(txn, room.first, room.second.timeline);
RoomInfo updatedInfo;
- updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString();
- updatedInfo.topic = getRoomTopic(txn, statesdb).toStdString();
+ updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString();
+ updatedInfo.topic = getRoomTopic(txn, statesdb).toStdString();
updatedInfo.avatar_url = getRoomAvatarUrl(txn, statesdb, membersdb).toStdString();
- updatedInfo.version = getRoomVersion(txn, statesdb).toStdString();
+ updatedInfo.version = getRoomVersion(txn, statesdb).toStdString();
// Process the account_data associated with this room
if (!room.second.account_data.events.empty()) {
@@ -1808,6 +1808,17 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id)
e.what());
return {};
}
+ auto membersdb{0};
+
+ try {
+ membersdb = getMembersDb(txn, room_id);
+ } catch (lmdb::runtime_error &e) {
+ nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})",
+ room_id,
+ e.what());
+ return {};
+ }
+
if (orderDb.size(txn) == 0)
return DescInfo{};
@@ -1850,9 +1861,16 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id)
mtx::events::collections::TimelineEvent te;
mtx::events::collections::from_json(obj, te);
+ lmdb::val info;
+ MemberInfo m;
+ if (lmdb::dbi_get(
+ txn, membersdb, lmdb::val(obj["sender"].get<std::string>()), info)) {
+ m = json::parse(std::string_view(info.data(), info.size()));
+ }
+
cursor.close();
return utils::getMessageDescription(
- te.data, local_user, QString::fromStdString(room_id));
+ te.data, local_user, QString::fromStdString(m.name));
}
cursor.close();
@@ -1911,7 +1929,6 @@ Cache::getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersd
// Resolve avatar for 1-1 chats.
while (cursor.get(user_id, member_data, MDB_NEXT)) {
-
try {
MemberInfo m = json::parse(member_data);
if (user_id == localUserId_.toStdString()) {
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 1fd9b9bc..6dfa62ef 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -20,7 +20,6 @@
#include <QMessageBox>
#include <QSettings>
#include <QShortcut>
-#include <QtConcurrent>
#include <mtx/responses.hpp>
@@ -281,10 +280,12 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
&ChatPage::setGroupViewState);
connect(this, &ChatPage::initializeRoomList, room_list_, &RoomList::initialize);
- connect(this,
- &ChatPage::initializeViews,
- view_manager_,
- [this](const mtx::responses::Rooms &rooms) { view_manager_->sync(rooms); });
+ connect(
+ this,
+ &ChatPage::initializeViews,
+ view_manager_,
+ [this](const mtx::responses::Rooms &rooms) { view_manager_->sync(rooms); },
+ Qt::QueuedConnection);
connect(this,
&ChatPage::initializeEmptyViews,
view_manager_,
@@ -522,8 +523,6 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
void
ChatPage::loadStateFromCache()
{
- emit contentLoaded();
-
nhlog::db()->info("restoring state from cache");
try {
@@ -555,6 +554,8 @@ ChatPage::loadStateFromCache()
getProfileInfo();
+ emit contentLoaded();
+
// Start receiving events.
emit trySyncCb();
}
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 2896e773..743c393f 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -27,12 +27,12 @@ QHash<QString, QString> authorColors_;
template<class T, class Event>
static DescInfo
-createDescriptionInfo(const Event &event, const QString &localUser, const QString &room_id)
+createDescriptionInfo(const Event &event, const QString &localUser, const QString &displayName)
{
const auto msg = std::get<T>(event);
const auto sender = QString::fromStdString(msg.sender);
- const auto username = cache::displayName(room_id, sender);
+ const auto username = displayName;
const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts);
return DescInfo{QString::fromStdString(msg.event_id),
@@ -153,7 +153,7 @@ utils::descriptiveTime(const QDateTime &then)
DescInfo
utils::getMessageDescription(const TimelineEvent &event,
const QString &localUser,
- const QString &room_id)
+ const QString &displayName)
{
using Audio = mtx::events::RoomEvent<mtx::events::msg::Audio>;
using Emote = mtx::events::RoomEvent<mtx::events::msg::Emote>;
@@ -168,31 +168,31 @@ utils::getMessageDescription(const TimelineEvent &event,
using Encrypted = mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>;
if (std::holds_alternative<Audio>(event)) {
- return createDescriptionInfo<Audio>(event, localUser, room_id);
+ return createDescriptionInfo<Audio>(event, localUser, displayName);
} else if (std::holds_alternative<Emote>(event)) {
- return createDescriptionInfo<Emote>(event, localUser, room_id);
+ return createDescriptionInfo<Emote>(event, localUser, displayName);
} else if (std::holds_alternative<File>(event)) {
- return createDescriptionInfo<File>(event, localUser, room_id);
+ return createDescriptionInfo<File>(event, localUser, displayName);
} else if (std::holds_alternative<Image>(event)) {
- return createDescriptionInfo<Image>(event, localUser, room_id);
+ return createDescriptionInfo<Image>(event, localUser, displayName);
} else if (std::holds_alternative<Notice>(event)) {
- return createDescriptionInfo<Notice>(event, localUser, room_id);
+ return createDescriptionInfo<Notice>(event, localUser, displayName);
} else if (std::holds_alternative<Text>(event)) {
- return createDescriptionInfo<Text>(event, localUser, room_id);
+ return createDescriptionInfo<Text>(event, localUser, displayName);
} else if (std::holds_alternative<Video>(event)) {
- return createDescriptionInfo<Video>(event, localUser, room_id);
+ return createDescriptionInfo<Video>(event, localUser, displayName);
} else if (std::holds_alternative<CallInvite>(event)) {
- return createDescriptionInfo<CallInvite>(event, localUser, room_id);
+ return createDescriptionInfo<CallInvite>(event, localUser, displayName);
} else if (std::holds_alternative<CallAnswer>(event)) {
- return createDescriptionInfo<CallAnswer>(event, localUser, room_id);
+ return createDescriptionInfo<CallAnswer>(event, localUser, displayName);
} else if (std::holds_alternative<CallHangUp>(event)) {
- return createDescriptionInfo<CallHangUp>(event, localUser, room_id);
+ return createDescriptionInfo<CallHangUp>(event, localUser, displayName);
} else if (std::holds_alternative<mtx::events::Sticker>(event)) {
- return createDescriptionInfo<mtx::events::Sticker>(event, localUser, room_id);
+ return createDescriptionInfo<mtx::events::Sticker>(event, localUser, displayName);
} else if (auto msg = std::get_if<Encrypted>(&event); msg != nullptr) {
const auto sender = QString::fromStdString(msg->sender);
- const auto username = cache::displayName(room_id, sender);
+ const auto username = displayName;
const auto ts = QDateTime::fromMSecsSinceEpoch(msg->origin_server_ts);
DescInfo info;
diff --git a/src/Utils.h b/src/Utils.h
index f59e8673..6de3d458 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -67,7 +67,9 @@ descriptiveTime(const QDateTime &then);
//! Generate a message description from the event to be displayed
//! in the RoomList.
DescInfo
-getMessageDescription(const TimelineEvent &event, const QString &localUser, const QString &room_id);
+getMessageDescription(const TimelineEvent &event,
+ const QString &localUser,
+ const QString &displayName);
//! Get the first character of a string, taking into account that
//! surrogate pairs might be in use.
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 4cbd5777..53791c98 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -709,7 +709,10 @@ TimelineModel::updateLastMessage()
continue;
auto description = utils::getMessageDescription(
- *event, QString::fromStdString(http::client()->user_id().to_string()), room_id_);
+ *event,
+ QString::fromStdString(http::client()->user_id().to_string()),
+ cache::displayName(room_id_,
+ QString::fromStdString(mtx::accessors::sender(*event))));
emit manager_->updateRoomsLastMessage(room_id_, description);
return;
}