1
0
Fork 0
mirror of https://github.com/polybar/polybar.git synced 2024-10-27 05:23:39 -04:00
polybar/include/modules/meta/inotify_module.hpp

90 lines
2.3 KiB
C++
Raw Normal View History

2016-11-20 17:04:31 -05:00
#pragma once
#include "components/builder.hpp"
#include "modules/meta/base.hpp"
POLYBAR_NS
namespace modules {
template <class Impl>
class inotify_module : public module<Impl> {
public:
using module<Impl>::module;
void start() override {
this->module<Impl>::start();
this->m_mainthread = thread(&inotify_module::runner, this);
}
2016-11-20 17:04:31 -05:00
protected:
void runner() {
this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id()));
try {
2016-12-23 09:54:06 -05:00
// Warm up module output before entering the loop
std::unique_lock<std::mutex> guard(this->m_updatelock);
2022-03-06 11:44:48 -05:00
CAST_MOD(Impl)->on_event({});
2016-12-23 09:54:06 -05:00
CAST_MOD(Impl)->broadcast();
guard.unlock();
2016-12-21 17:22:02 -05:00
while (this->running()) {
std::lock_guard<std::mutex> guard(this->m_updatelock);
CAST_MOD(Impl)->poll_events();
}
} catch (const module_error& err) {
CAST_MOD(Impl)->halt(err.what());
} catch (const std::exception& err) {
CAST_MOD(Impl)->halt(err.what());
}
}
void watch(string path, int mask = IN_ALL_EVENTS) {
2016-12-21 17:22:02 -05:00
this->m_log.trace("%s: Attach inotify at %s", this->name(), path);
m_watchlist.insert(make_pair(path, mask));
}
void idle() {
this->sleep(200ms);
}
void poll_events() {
2022-03-06 11:44:48 -05:00
vector<inotify_watch> watches;
try {
for (auto&& w : m_watchlist) {
2022-03-06 11:44:48 -05:00
watches.emplace_back(w.first);
watches.back().attach(w.second);
}
} catch (const system_error& e) {
2016-12-21 17:22:02 -05:00
this->m_log.err("%s: Error while creating inotify watch (what: %s)", this->name(), e.what());
CAST_MOD(Impl)->sleep(0.1s);
return;
}
2016-12-21 17:22:02 -05:00
while (this->running()) {
for (auto&& w : watches) {
2022-03-06 11:44:48 -05:00
this->m_log.trace_x("%s: Poll inotify watch %s", this->name(), w.path());
2022-03-06 11:44:48 -05:00
if (w.poll(1000 / watches.size())) {
auto event = w.get_event();
if (CAST_MOD(Impl)->on_event(event)) {
2016-12-21 17:22:02 -05:00
CAST_MOD(Impl)->broadcast();
}
CAST_MOD(Impl)->idle();
return;
}
2016-12-21 17:22:02 -05:00
if (!this->running()) {
2016-12-21 17:22:02 -05:00
break;
}
}
CAST_MOD(Impl)->idle();
}
}
2016-11-20 17:04:31 -05:00
private:
map<string, int> m_watchlist;
};
2022-03-06 11:44:48 -05:00
} // namespace modules
2016-11-20 17:04:31 -05:00
POLYBAR_NS_END