From eb5c82a5c37649ddbd866f08226d4bb91472bdd1 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Fri, 27 Jan 2017 13:29:10 +0100 Subject: [PATCH] fix(modules): Warmup in runner thread to avoid block --- include/modules/meta/base.inl | 10 ++++++--- include/modules/meta/event_module.hpp | 30 +++++++++++-------------- include/modules/meta/inotify_module.hpp | 3 +++ include/modules/meta/static_module.hpp | 8 +++++-- include/modules/meta/timer_module.hpp | 27 ++++++++++++---------- src/components/controller.cpp | 2 ++ src/modules/github.cpp | 3 +-- src/modules/xbacklight.cpp | 7 ------ 8 files changed, 47 insertions(+), 43 deletions(-) diff --git a/include/modules/meta/base.inl b/include/modules/meta/base.inl index 949d4f6f..efc35b19 100644 --- a/include/modules/meta/base.inl +++ b/include/modules/meta/base.inl @@ -94,13 +94,17 @@ namespace modules { template void module::idle() { - CAST_MOD(Impl)->sleep(25ms); + if (running()) { + CAST_MOD(Impl)->sleep(25ms); + } } template void module::sleep(chrono::duration sleep_duration) { - std::unique_lock lck(m_sleeplock); - m_sleephandler.wait_for(lck, sleep_duration); + if (running()) { + std::unique_lock lck(m_sleeplock); + m_sleephandler.wait_for(lck, sleep_duration); + } } template diff --git a/include/modules/meta/event_module.hpp b/include/modules/meta/event_module.hpp index 692dbf52..417ca3a4 100644 --- a/include/modules/meta/event_module.hpp +++ b/include/modules/meta/event_module.hpp @@ -11,33 +11,29 @@ namespace modules { using module::module; void start() { - CAST_MOD(Impl)->update(); - CAST_MOD(Impl)->broadcast(); - this->m_mainthread = thread(&event_module::runner, this); } protected: void runner() { + this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id())); try { - while (this->running()) { - CAST_MOD(Impl)->idle(); - - if (!this->running()) { - break; - } + // warm up module output before entering the loop + std::unique_lock guard(this->m_updatelock); + CAST_MOD(Impl)->update(); + CAST_MOD(Impl)->broadcast(); + guard.unlock(); + const auto check = [&]() -> bool { std::lock_guard guard(this->m_updatelock); + return CAST_MOD(Impl)->has_event() && CAST_MOD(Impl)->update(); + }; - if (!CAST_MOD(Impl)->has_event()) { - continue; - } else if (!this->running()) { - break; - } else if (!CAST_MOD(Impl)->update()) { - continue; + while (this->running()) { + if (check()) { + CAST_MOD(Impl)->broadcast(); } - - CAST_MOD(Impl)->broadcast(); + CAST_MOD(Impl)->idle(); } } catch (const exception& err) { CAST_MOD(Impl)->halt(err.what()); diff --git a/include/modules/meta/inotify_module.hpp b/include/modules/meta/inotify_module.hpp index dfd3bbac..0b174d3c 100644 --- a/include/modules/meta/inotify_module.hpp +++ b/include/modules/meta/inotify_module.hpp @@ -17,10 +17,13 @@ namespace modules { protected: void runner() { + this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id())); try { // Warm up module output before entering the loop + std::unique_lock guard(this->m_updatelock); CAST_MOD(Impl)->on_event(nullptr); CAST_MOD(Impl)->broadcast(); + guard.unlock(); while (this->running()) { std::lock_guard guard(this->m_updatelock); diff --git a/include/modules/meta/static_module.hpp b/include/modules/meta/static_module.hpp index f22da3b1..9b95ae7e 100644 --- a/include/modules/meta/static_module.hpp +++ b/include/modules/meta/static_module.hpp @@ -11,8 +11,12 @@ namespace modules { using module::module; void start() { - CAST_MOD(Impl)->update(); - CAST_MOD(Impl)->broadcast(); + this->m_mainthread = thread([&] { + this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id())); + std::unique_lock guard(this->m_updatelock); + CAST_MOD(Impl)->update(); + CAST_MOD(Impl)->broadcast(); + }); } bool build(builder*, string) const { diff --git a/include/modules/meta/timer_module.hpp b/include/modules/meta/timer_module.hpp index 32395da6..9d8f52fc 100644 --- a/include/modules/meta/timer_module.hpp +++ b/include/modules/meta/timer_module.hpp @@ -13,28 +13,31 @@ namespace modules { using module::module; void start() { - CAST_MOD(Impl)->update(); this->m_mainthread = thread(&timer_module::runner, this); } protected: void runner() { + this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id())); + + const auto check = [&]() -> bool { + std::unique_lock guard(this->m_updatelock); + return CAST_MOD(Impl)->update(); + }; + + // warm up module output before entering the loop + check(); + CAST_MOD(Impl)->broadcast(); + try { while (this->running()) { - this->sleep(m_interval); - - if (!this->running()) { - break; - } - - std::unique_lock guard(this->m_updatelock); - - if (CAST_MOD(Impl)->update()) { - this->broadcast(); + if (check()) { + CAST_MOD(Impl)->broadcast(); } + CAST_MOD(Impl)->sleep(m_interval); } } catch (const exception& err) { - this->halt(err.what()); + CAST_MOD(Impl)->halt(err.what()); } } diff --git a/src/components/controller.cpp b/src/components/controller.cpp index 175da627..b2574668 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -157,6 +157,8 @@ controller::~controller() { */ bool controller::run(bool writeback, string snapshot_dst) { m_log.info("Starting application"); + m_log.trace("controller: Main thread id = %i", concurrency_util::thread_id(this_thread::get_id())); + assert(!m_connection.connection_has_error()); m_writeback = writeback; diff --git a/src/modules/github.cpp b/src/modules/github.cpp index ce4d968f..4a69d33b 100644 --- a/src/modules/github.cpp +++ b/src/modules/github.cpp @@ -2,6 +2,7 @@ #include "drawtypes/label.hpp" #include "modules/github.hpp" +#include "utils/concurrency.hpp" #include "modules/meta/base.inl" @@ -25,8 +26,6 @@ namespace modules { m_label = load_optional_label(m_conf, name(), TAG_LABEL, "Notifications: %notifications%"); m_label->replace_token("%notifications%", m_empty_notifications ? "0" : ""); } - - assert(static_cast(m_label)); } /** diff --git a/src/modules/xbacklight.cpp b/src/modules/xbacklight.cpp index d1b5393b..8d819a87 100644 --- a/src/modules/xbacklight.cpp +++ b/src/modules/xbacklight.cpp @@ -96,13 +96,6 @@ namespace modules { * Query the RandR extension for the new values */ void xbacklight_module::update() { - if (!m_updatelock.try_lock()) { - return; - } - - std::lock_guard guard(m_updatelock, std::adopt_lock); - - // Query for the new backlight value auto& bl = m_output->backlight; randr_util::get_backlight_value(m_connection, m_output, bl); m_percentage = math_util::nearest_5(math_util::percentage(bl.val, bl.min, bl.max));