fix the config updates

This commit is contained in:
PancakeTAS 2025-07-17 01:09:32 +02:00 committed by Pancake
parent 9f528a688a
commit f8bdfd90de

View file

@ -3,10 +3,12 @@
#include <linux/limits.h> #include <linux/limits.h>
#include <sys/inotify.h> #include <sys/inotify.h>
#include <sys/poll.h>
#include <toml11/find.hpp> #include <toml11/find.hpp>
#include <toml11/parser.hpp> #include <toml11/parser.hpp>
#include <toml.hpp> #include <toml.hpp>
#include <unistd.h> #include <unistd.h>
#include <poll.h>
#include <unordered_map> #include <unordered_map>
#include <string_view> #include <string_view>
@ -35,22 +37,17 @@ namespace {
Configuration Config::activeConf{}; Configuration Config::activeConf{};
bool Config::loadAndWatchConfig(const std::string& file) { namespace {
globalConf.valid = std::make_shared<std::atomic_bool>(true); [[noreturn]] void thread(
const std::string& file,
auto res = updateConfig(file); const std::shared_ptr<std::atomic_bool>& valid) {
if (!res)
return false;
// prepare config watcher
std::thread([file = file, valid = globalConf.valid]() {
try {
const int fd = inotify_init(); const int fd = inotify_init();
if (fd < 0) if (fd < 0)
throw std::runtime_error("Failed to initialize inotify:\n" throw std::runtime_error("Failed to initialize inotify:\n"
"- " + std::string(strerror(errno))); "- " + std::string(strerror(errno)));
const int wd = inotify_add_watch(fd, file.c_str(), IN_MODIFY | IN_CLOSE_WRITE); const int wd = inotify_add_watch(fd, file.c_str(),
IN_MODIFY | IN_CLOSE_WRITE | IN_MOVE_SELF);
if (wd < 0) { if (wd < 0) {
close(fd); close(fd);
@ -63,12 +60,26 @@ bool Config::loadAndWatchConfig(const std::string& file) {
std::array<char, (sizeof(inotify_event) + NAME_MAX + 1) * 20> buffer{}; std::array<char, (sizeof(inotify_event) + NAME_MAX + 1) * 20> buffer{};
while (true) { while (true) {
const ssize_t len = read(fd, buffer.data(), buffer.size()); // poll fd
if (len <= 0 && errno != EINTR) { struct pollfd pfd{};
pfd.fd = fd;
pfd.events = POLLIN;
const int pollRes = poll(&pfd, 1, 100);
if (pollRes < 0 && errno != EINTR) {
inotify_rm_watch(fd, wd); inotify_rm_watch(fd, wd);
close(fd); close(fd);
throw std::runtime_error("Error reading inotify event:\n" throw std::runtime_error("Error polling inotify events:\n"
"- " + std::string(strerror(errno)));
}
// read fd if there are events
const ssize_t len = pollRes == 0 ? 0 : read(fd, buffer.data(), buffer.size());
if (len <= 0 && errno != EINTR && pollRes > 0) {
inotify_rm_watch(fd, wd);
close(fd);
throw std::runtime_error("Error reading inotify events:\n"
"- " + std::string(strerror(errno))); "- " + std::string(strerror(errno)));
} }
@ -76,10 +87,9 @@ bool Config::loadAndWatchConfig(const std::string& file) {
while (std::cmp_less(i, len)) { while (std::cmp_less(i, len)) {
auto* event = reinterpret_cast<inotify_event*>(&buffer.at(i)); auto* event = reinterpret_cast<inotify_event*>(&buffer.at(i));
i += sizeof(inotify_event) + event->len; i += sizeof(inotify_event) + event->len;
if (event->len <= 0)
continue;
// stall a bit, then mark as invalid // stall a bit, then mark as invalid
if (!discard_until.has_value())
std::cerr << "lsfg-vk: Configuration file changed, invalidating config...\n"; std::cerr << "lsfg-vk: Configuration file changed, invalidating config...\n";
discard_until.emplace(std::chrono::steady_clock::now() discard_until.emplace(std::chrono::steady_clock::now()
+ std::chrono::milliseconds(500)); + std::chrono::milliseconds(500));
@ -97,6 +107,20 @@ bool Config::loadAndWatchConfig(const std::string& file) {
std::this_thread::sleep_for(std::chrono::milliseconds(50)); std::this_thread::sleep_for(std::chrono::milliseconds(50));
} }
} }
}
}
bool Config::loadAndWatchConfig(const std::string& file) {
globalConf.valid = std::make_shared<std::atomic_bool>(true);
auto res = updateConfig(file);
if (!res)
return false;
// prepare config watcher
std::thread([file = file, valid = globalConf.valid]() {
try {
thread(file, valid);
} catch (const std::exception& e) { } catch (const std::exception& e) {
std::cerr << "lsfg-vk: Error in config watcher thread:\n"; std::cerr << "lsfg-vk: Error in config watcher thread:\n";
std::cerr << "- " << e.what() << '\n'; std::cerr << "- " << e.what() << '\n';