From eeaf16e442bef8a80ed1e6a94d8c2d8e433f8deb Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 11 Jul 2022 15:14:30 +0200 Subject: [PATCH] Fix race condition in dbus API --- src/dbus/NhekoDBusBackend.cpp | 49 +++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/dbus/NhekoDBusBackend.cpp b/src/dbus/NhekoDBusBackend.cpp index d49ff2a5..ea7a8940 100644 --- a/src/dbus/NhekoDBusBackend.cpp +++ b/src/dbus/NhekoDBusBackend.cpp @@ -4,6 +4,9 @@ #include "NhekoDBusBackend.h" +#include + +#include "Cache.h" #include "Cache_p.h" #include "ChatPage.h" #include "Logging.h" @@ -18,17 +21,35 @@ NhekoDBusBackend::NhekoDBusBackend(RoomlistModel *parent) , m_parent{parent} {} +namespace { +struct RoomReplyState +{ + QVector model; + std::map roominfos; + std::recursive_mutex m; +}; +} + QVector NhekoDBusBackend::rooms(const QDBusMessage &message) { message.setDelayedReply(true); + nhlog::ui()->debug("Rooms requested over D-Bus."); const auto roomListModel = m_parent->models; - QSharedPointer> model{ - new QVector}; + auto state = QSharedPointer::create(); + + std::vector roomids; + roomids.reserve(roomids.size()); for (const auto &room : roomListModel) { - auto addRoom = [room, roomListModelSize = roomListModel.size(), message, model]( + roomids.push_back(room->roomId().toStdString()); + } + state->roominfos = cache::getRoomInfo(roomids); + + std::lock_guard parentLock(state->m); + for (const auto &room : roomListModel) { + auto addRoom = [room, roomListModelSize = roomListModel.size(), message, state]( const QImage &image) { const auto aliases = cache::client()->getStateEvent( room->roomId().toStdString()); @@ -41,24 +62,30 @@ NhekoDBusBackend::rooms(const QDBusMessage &message) alias = QString::fromStdString(val.alt_aliases.front()); } - model->push_back(nheko::dbus::RoomInfoItem{ - room->roomId(), alias, room->roomName(), image, room->notificationCount()}); + state->model.push_back(nheko::dbus::RoomInfoItem{ + room->roomId(), + alias, + QString::fromStdString(state->roominfos[room->roomId()].name), + image, + room->notificationCount()}); - if (model->length() == roomListModelSize) { - nhlog::ui()->debug("Sending {} rooms over D-Bus...", model->size()); + std::lock_guard childLock(state->m); + if (state->model.size() == roomListModelSize) { + nhlog::ui()->debug("Sending {} rooms over D-Bus...", state->model.size()); auto reply = message.createReply(); - reply << QVariant::fromValue(*model); + reply << QVariant::fromValue(state->model); QDBusConnection::sessionBus().send(reply); nhlog::ui()->debug("Rooms successfully sent to D-Bus."); + } else { + // nhlog::ui()->debug("DBUS: {}/{}", state->model.size(), roomListModelSize); } }; - auto avatarUrl = room->roomAvatarUrl(); - if (avatarUrl.isEmpty()) + if (state->roominfos[room->roomId()].avatar_url.empty()) addRoom(QImage()); else MainWindow::instance()->imageProvider()->download( - avatarUrl.remove("mxc://"), + QString::fromStdString(state->roominfos[room->roomId()].avatar_url).remove("mxc://"), {96, 96}, [addRoom](const QString &, const QSize &, const QImage &image, const QString &) { addRoom(image);