aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-02-05 05:18:31 +0100
committerdec05eba <dec05eba@protonmail.com>2021-02-05 05:18:31 +0100
commit0d4b8bacce933e34a41769b1051b25f82f922201 (patch)
treeef1894ccfd66c41351568937182f16abb6c754f4
parent1591c329889b0cd6eb3d579e60eeaf93df131a71 (diff)
Matrix: fix crash when a room is being removed in one thread and the room description is set in another, at the same time
-rw-r--r--plugins/Matrix.hpp2
-rw-r--r--src/QuickMedia.cpp15
-rw-r--r--src/plugins/Matrix.cpp16
3 files changed, 16 insertions, 17 deletions
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index be89adb..df8fa43 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -136,7 +136,7 @@ namespace QuickMedia {
bool last_message_read = true;
bool users_fetched = false;
time_t last_read_message_timestamp = 0;
- void *userdata = nullptr; // Pointer to BodyItem. Note: this has to be valid as long as the room is valid
+ std::shared_ptr<BodyItem> body_item;
// These are messages fetched with |Matrix::get_message_by_id|. Needed to show replies, when replying to old message not part of /sync.
// The value is nullptr if the message is fetched and cached but the event if referenced an invalid message.
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 719345d..76bd084 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3440,7 +3440,7 @@ namespace QuickMedia {
process_pinned_events(std::move(pinned_events));
tabs[PINNED_TAB_INDEX].body->select_last_item();
- room_name_text.setString(static_cast<BodyItem*>(current_room->userdata)->get_title());
+ room_name_text.setString(current_room->body_item->get_title());
room_avatar_thumbnail_data = std::make_shared<ThumbnailData>();
read_marker_timeout_ms = 0;
@@ -4429,8 +4429,8 @@ namespace QuickMedia {
typing_state_queue.push(false);
}
- if(current_room && current_room->userdata && room_avatar_thumbnail_data->loading_state == LoadingState::NOT_LOADED)
- AsyncImageLoader::get_instance().load_thumbnail(static_cast<BodyItem*>(current_room->userdata)->thumbnail_url, false, sf::Vector2i(32, 32), use_tor, room_avatar_thumbnail_data);
+ if(current_room && current_room->body_item && room_avatar_thumbnail_data->loading_state == LoadingState::NOT_LOADED)
+ AsyncImageLoader::get_instance().load_thumbnail(current_room->body_item->thumbnail_url, false, sf::Vector2i(32, 32), use_tor, room_avatar_thumbnail_data);
if(room_avatar_thumbnail_data->loading_state == LoadingState::FINISHED_LOADING && room_avatar_thumbnail_data->image->getSize().x > 0 && room_avatar_thumbnail_data->image->getSize().y > 0) {
if(!room_avatar_thumbnail_data->texture.loadFromImage(*room_avatar_thumbnail_data->image))
@@ -4686,10 +4686,9 @@ namespace QuickMedia {
tabs[MESSAGES_TAB_INDEX].body->draw_item(window, currently_operating_on_item.get(), body_item_pos, body_item_size);
}
- if(selected_tab == MESSAGES_TAB_INDEX && current_room && current_room->userdata && !current_room->last_message_read) {
+ if(selected_tab == MESSAGES_TAB_INDEX && current_room && current_room->body_item && !current_room->last_message_read) {
if(tabs[selected_tab].body->is_last_item_fully_visible()) {
- BodyItem *current_room_body_item = static_cast<BodyItem*>(current_room->userdata);
- std::string room_desc = current_room_body_item->get_description();
+ std::string room_desc = current_room->body_item->get_description();
if(strncmp(room_desc.c_str(), "Unread: ", 8) == 0)
room_desc = room_desc.substr(8);
size_t last_line_start = room_desc.rfind('\n');
@@ -4699,9 +4698,9 @@ namespace QuickMedia {
if(last_line_size >= 23 && memcmp(&room_desc[last_line_start], "** ", 3) == 0 && memcmp(&room_desc[room_desc.size() - 20], "unread mention(s) **", 20) == 0)
room_desc.erase(room_desc.begin() + last_line_start - 1, room_desc.end());
}
- current_room_body_item->set_description(std::move(room_desc));
+ current_room->body_item->set_description(std::move(room_desc));
// TODO: Show a line like nheko instead for unread messages, or something else
- current_room_body_item->set_title_color(sf::Color::White);
+ current_room->body_item->set_title_color(sf::Color::White);
current_room->last_message_read = true;
// TODO: Maybe set this instead when the mention is visible on the screen?
current_room->unread_notification_count = 0;
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index ba8533b..3a2c02c 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -296,6 +296,8 @@ namespace QuickMedia {
//message_by_event_id.clear();
pinned_events.clear();
tags.clear();
+ // TODO: Do this? what if its being used in another thread?
+ //body_item.reset();
}
MatrixQuickMedia::MatrixQuickMedia(Program *program, Matrix *matrix, MatrixRoomsPage *rooms_page, MatrixRoomTagsPage *room_tags_page, MatrixInvitesPage *invites_page) :
@@ -317,7 +319,7 @@ namespace QuickMedia {
body_item->userdata = room; // Note: this has to be valid as long as the room list is valid!
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
body_item->thumbnail_size = sf::Vector2i(32, 32);
- room->userdata = body_item.get();
+ room->body_item = body_item;
rooms_page->add_body_item(body_item);
room_body_item_by_room[room] = body_item;
}
@@ -484,9 +486,8 @@ namespace QuickMedia {
if(last_new_message->timestamp > read_marker_message_timestamp)
last_unread_message = last_new_message.get();
- BodyItem *room_body_item = static_cast<BodyItem*>(room->userdata);
//assert(room_body_item);
- if(!room_body_item)
+ if(!room->body_item)
return;
if(last_unread_message && !sync_is_cache) {
@@ -494,14 +495,14 @@ namespace QuickMedia {
int unread_notification_count = room->unread_notification_count;
if(unread_notification_count > 0)
room_desc += "\n** " + std::to_string(unread_notification_count) + " unread mention(s) **"; // TODO: Better notification?
- room_body_item->set_description(std::move(room_desc));
- room_body_item->set_title_color(sf::Color(255, 100, 100));
+ room->body_item->set_description(std::move(room_desc));
+ room->body_item->set_title_color(sf::Color(255, 100, 100));
room->last_message_read = false;
rooms_page->move_room_to_top(room);
room_tags_page->move_room_to_top(room);
} else if(is_initial_sync) {
- room_body_item->set_description(matrix->message_get_author_displayname(last_new_message.get()) + ": " + message_to_room_description_text(last_new_message.get()));
+ room->body_item->set_description(matrix->message_get_author_displayname(last_new_message.get()) + ": " + message_to_room_description_text(last_new_message.get()));
}
}
@@ -608,8 +609,7 @@ namespace QuickMedia {
// TODO: Optimize with hash map instead of linear search? or cache the index
std::lock_guard<std::mutex> lock(mutex);
#if 1
- BodyItem *room_body_item = static_cast<BodyItem*>(room->userdata);
- int room_body_index = body->get_index_by_body_item(room_body_item);
+ int room_body_index = body->get_index_by_body_item(room->body_item.get());
if(room_body_index != -1) {
std::shared_ptr<BodyItem> body_item = body->items[room_body_index];
int body_swap_index = -1;