polybar-dwm/include/modules/meta/inotify_module.hpp

94 lines
2.4 KiB
C++
Raw Normal View History

2016-11-20 22:04:31 +00: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->m_mainthread = thread(&inotify_module::runner, this);
}
2016-11-20 22:04:31 +00: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 14:54:06 +00:00
// Warm up module output before entering the loop
std::unique_lock<std::mutex> guard(this->m_updatelock);
2016-12-23 14:54:06 +00:00
CAST_MOD(Impl)->on_event(nullptr);
CAST_MOD(Impl)->broadcast();
guard.unlock();
2016-12-21 22:22:02 +00: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 22:22:02 +00: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() {
vector<unique_ptr<inotify_watch>> watches;
try {
for (auto&& w : m_watchlist) {
watches.emplace_back(inotify_util::make_watch(w.first));
watches.back()->attach(w.second);
}
} catch (const system_error& e) {
watches.clear();
2016-12-21 22:22:02 +00: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 22:22:02 +00:00
while (this->running()) {
for (auto&& w : watches) {
this->m_log.trace_x("%s: Poll inotify watch %s", this->name(), w->path());
2016-12-21 22:22:02 +00:00
if (w->poll(1000 / watches.size())) {
auto event = w->get_event();
2016-12-21 22:22:02 +00:00
for (auto&& w : watches) {
w->remove(true);
}
2016-12-21 22:22:02 +00:00
if (CAST_MOD(Impl)->on_event(event.get())) {
CAST_MOD(Impl)->broadcast();
}
CAST_MOD(Impl)->idle();
return;
}
2016-12-21 22:22:02 +00:00
if (!this->running())
break;
}
CAST_MOD(Impl)->idle();
}
}
2016-11-20 22:04:31 +00:00
private:
map<string, int> m_watchlist;
};
} // namespace modules
2016-11-20 22:04:31 +00:00
POLYBAR_NS_END