From b9308d732586d78e55abe7ebb99ea85fcd8fe3de Mon Sep 17 00:00:00 2001 From: pajlada Date: Sat, 24 Dec 2022 11:32:08 +0100 Subject: [PATCH] Add Thread Guard for debugging simple threading issues (#4254) * Add ThreadGuard class * Use ThreadGuard when accessing a ChannelView's messageSnapshot --- src/CMakeLists.txt | 1 + src/util/ThreadGuard.hpp | 35 ++++++++++++++++++++++++++++++ src/widgets/helper/ChannelView.cpp | 1 + src/widgets/helper/ChannelView.hpp | 2 ++ 4 files changed, 39 insertions(+) create mode 100644 src/util/ThreadGuard.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f7912f44..ec157314 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -364,6 +364,7 @@ set(SOURCE_FILES util/StreamLink.hpp util/StreamerMode.cpp util/StreamerMode.hpp + util/ThreadGuard.hpp util/Twitch.cpp util/Twitch.hpp util/TypeName.hpp diff --git a/src/util/ThreadGuard.hpp b/src/util/ThreadGuard.hpp new file mode 100644 index 00000000..6f272ac4 --- /dev/null +++ b/src/util/ThreadGuard.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include +#include + +namespace chatterino { + +// Debug-class which asserts if guard of the same object has been called from different threads +struct ThreadGuard { +#ifndef NDEBUG + std::mutex mutex; + std::optional threadID; +#endif + + inline void guard() + { +#ifndef NDEBUG + std::unique_lock lock(this->mutex); + + auto currentThreadID = std::this_thread::get_id(); + + if (!this->threadID.has_value()) + { + this->threadID = currentThreadID; + return; + } + + assert(this->threadID == currentThreadID); +#endif + } +}; + +} // namespace chatterino diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index 14746c72..cfaf0d0d 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -628,6 +628,7 @@ const boost::optional &ChannelView::getOverrideFlags() LimitedQueueSnapshot &ChannelView::getMessagesSnapshot() { + this->snapshotGuard_.guard(); if (!this->paused() /*|| this->scrollBar_->isVisible()*/) { this->snapshot_ = this->messages_.getSnapshot(); diff --git a/src/widgets/helper/ChannelView.hpp b/src/widgets/helper/ChannelView.hpp index dc614118..afb1e836 100644 --- a/src/widgets/helper/ChannelView.hpp +++ b/src/widgets/helper/ChannelView.hpp @@ -6,6 +6,7 @@ #include "messages/LimitedQueue.hpp" #include "messages/LimitedQueueSnapshot.hpp" #include "messages/Selection.hpp" +#include "util/ThreadGuard.hpp" #include "widgets/BaseWidget.hpp" #include @@ -270,6 +271,7 @@ private: boost::optional overrideFlags_; MessageLayoutPtr lastReadMessage_; + ThreadGuard snapshotGuard_; LimitedQueueSnapshot snapshot_; ChannelPtr channel_ = nullptr;