From 79883dbce4caf5d8e66ff70af1d59a3a1950fc57 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Mon, 28 Dec 2020 17:31:23 -0800 Subject: [PATCH] feat(util): optimize SafeSignal for events from the main thread --- include/util/SafeSignal.hpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/include/util/SafeSignal.hpp b/include/util/SafeSignal.hpp index 15a8d2b..3b68653 100644 --- a/include/util/SafeSignal.hpp +++ b/include/util/SafeSignal.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -23,11 +24,22 @@ struct SafeSignal : sigc::signal...)> { template void emit(EmitArgs&&... args) { - { - std::unique_lock lock(mutex_); - queue_.emplace(std::forward(args)...); + if (main_tid_ == std::this_thread::get_id()) { + /* + * Bypass the queue if the method is called the main thread. + * Ensures that events emitted from the main thread are processed synchronously and saves a + * few CPU cycles on locking/queuing. + * As a downside, this makes main thread events prioritized over the other threads and + * disrupts chronological order. + */ + signal_t::emit(std::forward(args)...); + } else { + { + std::unique_lock lock(mutex_); + queue_.emplace(std::forward(args)...); + } + dp_.emit(); } - dp_.emit(); } template @@ -55,6 +67,7 @@ struct SafeSignal : sigc::signal...)> { Glib::Dispatcher dp_; std::mutex mutex_; std::queue queue_; + const std::thread::id main_tid_ = std::this_thread::get_id(); // cache functor for signal emission to avoid recreating it on each event const slot_t cached_fn_ = make_slot(); };