fix(modules): Warmup in runner thread to avoid block

This commit is contained in:
Michael Carlberg 2017-01-27 13:29:10 +01:00
parent b241018786
commit eb5c82a5c3
8 changed files with 47 additions and 43 deletions

View File

@ -94,14 +94,18 @@ namespace modules {
template <typename Impl> template <typename Impl>
void module<Impl>::idle() { void module<Impl>::idle() {
if (running()) {
CAST_MOD(Impl)->sleep(25ms); CAST_MOD(Impl)->sleep(25ms);
} }
}
template <typename Impl> template <typename Impl>
void module<Impl>::sleep(chrono::duration<double> sleep_duration) { void module<Impl>::sleep(chrono::duration<double> sleep_duration) {
if (running()) {
std::unique_lock<std::mutex> lck(m_sleeplock); std::unique_lock<std::mutex> lck(m_sleeplock);
m_sleephandler.wait_for(lck, sleep_duration); m_sleephandler.wait_for(lck, sleep_duration);
} }
}
template <typename Impl> template <typename Impl>
void module<Impl>::wakeup() { void module<Impl>::wakeup() {

View File

@ -11,33 +11,29 @@ namespace modules {
using module<Impl>::module; using module<Impl>::module;
void start() { void start() {
CAST_MOD(Impl)->update();
CAST_MOD(Impl)->broadcast();
this->m_mainthread = thread(&event_module::runner, this); this->m_mainthread = thread(&event_module::runner, this);
} }
protected: protected:
void runner() { void runner() {
this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id()));
try { try {
while (this->running()) { // warm up module output before entering the loop
CAST_MOD(Impl)->idle(); std::unique_lock<std::mutex> guard(this->m_updatelock);
CAST_MOD(Impl)->update();
if (!this->running()) {
break;
}
std::lock_guard<std::mutex> guard(this->m_updatelock);
if (!CAST_MOD(Impl)->has_event()) {
continue;
} else if (!this->running()) {
break;
} else if (!CAST_MOD(Impl)->update()) {
continue;
}
CAST_MOD(Impl)->broadcast(); CAST_MOD(Impl)->broadcast();
guard.unlock();
const auto check = [&]() -> bool {
std::lock_guard<std::mutex> guard(this->m_updatelock);
return CAST_MOD(Impl)->has_event() && CAST_MOD(Impl)->update();
};
while (this->running()) {
if (check()) {
CAST_MOD(Impl)->broadcast();
}
CAST_MOD(Impl)->idle();
} }
} catch (const exception& err) { } catch (const exception& err) {
CAST_MOD(Impl)->halt(err.what()); CAST_MOD(Impl)->halt(err.what());

View File

@ -17,10 +17,13 @@ namespace modules {
protected: protected:
void runner() { void runner() {
this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id()));
try { try {
// Warm up module output before entering the loop // Warm up module output before entering the loop
std::unique_lock<std::mutex> guard(this->m_updatelock);
CAST_MOD(Impl)->on_event(nullptr); CAST_MOD(Impl)->on_event(nullptr);
CAST_MOD(Impl)->broadcast(); CAST_MOD(Impl)->broadcast();
guard.unlock();
while (this->running()) { while (this->running()) {
std::lock_guard<std::mutex> guard(this->m_updatelock); std::lock_guard<std::mutex> guard(this->m_updatelock);

View File

@ -11,8 +11,12 @@ namespace modules {
using module<Impl>::module; using module<Impl>::module;
void start() { void start() {
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<std::mutex> guard(this->m_updatelock);
CAST_MOD(Impl)->update(); CAST_MOD(Impl)->update();
CAST_MOD(Impl)->broadcast(); CAST_MOD(Impl)->broadcast();
});
} }
bool build(builder*, string) const { bool build(builder*, string) const {

View File

@ -13,28 +13,31 @@ namespace modules {
using module<Impl>::module; using module<Impl>::module;
void start() { void start() {
CAST_MOD(Impl)->update();
this->m_mainthread = thread(&timer_module::runner, this); this->m_mainthread = thread(&timer_module::runner, this);
} }
protected: protected:
void runner() { 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<std::mutex> guard(this->m_updatelock);
return CAST_MOD(Impl)->update();
};
// warm up module output before entering the loop
check();
CAST_MOD(Impl)->broadcast();
try { try {
while (this->running()) { while (this->running()) {
this->sleep(m_interval); if (check()) {
CAST_MOD(Impl)->broadcast();
if (!this->running()) {
break;
}
std::unique_lock<std::mutex> guard(this->m_updatelock);
if (CAST_MOD(Impl)->update()) {
this->broadcast();
} }
CAST_MOD(Impl)->sleep(m_interval);
} }
} catch (const exception& err) { } catch (const exception& err) {
this->halt(err.what()); CAST_MOD(Impl)->halt(err.what());
} }
} }

View File

@ -157,6 +157,8 @@ controller::~controller() {
*/ */
bool controller::run(bool writeback, string snapshot_dst) { bool controller::run(bool writeback, string snapshot_dst) {
m_log.info("Starting application"); 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()); assert(!m_connection.connection_has_error());
m_writeback = writeback; m_writeback = writeback;

View File

@ -2,6 +2,7 @@
#include "drawtypes/label.hpp" #include "drawtypes/label.hpp"
#include "modules/github.hpp" #include "modules/github.hpp"
#include "utils/concurrency.hpp"
#include "modules/meta/base.inl" #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 = load_optional_label(m_conf, name(), TAG_LABEL, "Notifications: %notifications%");
m_label->replace_token("%notifications%", m_empty_notifications ? "0" : ""); m_label->replace_token("%notifications%", m_empty_notifications ? "0" : "");
} }
assert(static_cast<bool>(m_label));
} }
/** /**

View File

@ -96,13 +96,6 @@ namespace modules {
* Query the RandR extension for the new values * Query the RandR extension for the new values
*/ */
void xbacklight_module::update() { void xbacklight_module::update() {
if (!m_updatelock.try_lock()) {
return;
}
std::lock_guard<mutex> guard(m_updatelock, std::adopt_lock);
// Query for the new backlight value
auto& bl = m_output->backlight; auto& bl = m_output->backlight;
randr_util::get_backlight_value(m_connection, m_output, bl); randr_util::get_backlight_value(m_connection, m_output, bl);
m_percentage = math_util::nearest_5(math_util::percentage<double>(bl.val, bl.min, bl.max)); m_percentage = math_util::nearest_5(math_util::percentage<double>(bl.val, bl.min, bl.max));