introduced seperate class for waiting with timeout

This commit is contained in:
ItsMeSamey
2026-05-09 19:15:44 +10:00
parent 312592f01e
commit 2c631e4c8f
4 changed files with 94 additions and 12 deletions

View File

@@ -353,15 +353,14 @@ void init_config(bool low_color, std::optional<std::string>& filter) {
//* Manages secondary thread for collection and drawing of boxes
namespace Runner {
atomic<bool> active (false);
atomic_waiting_lock active;
atomic<bool> stopping (false);
atomic<bool> waiting (false);
atomic<bool> redraw (false);
atomic<bool> coreNum_reset (false);
static inline auto set_active(bool value) noexcept {
active.store(value, std::memory_order_release);
active.notify_all();
active.store(value);
}
//* Setup semaphore for triggering thread to do work
@@ -482,7 +481,7 @@ namespace Runner {
}
//? Atomic lock used for blocking non thread-safe actions in main thread
atomic_lock lck(active);
auto lck = active.lock();
//? Set effective user if SUID bit is set
gain_priv powers{};

View File

@@ -51,6 +51,10 @@ using std::vector;
using namespace std::literals; // for operator""s
namespace Tools {
class atomic_waiting_lock;
}
void term_resize(bool force=false);
void banner_gen();
@@ -71,7 +75,7 @@ namespace Global {
}
namespace Runner {
extern atomic<bool> active;
extern Tools::atomic_waiting_lock active;
extern atomic<bool> reading;
extern atomic<bool> stopping;
extern atomic<bool> redraw;

View File

@@ -545,11 +545,6 @@ namespace Tools {
atom.wait(old, std::memory_order_acquire);
}
void atomic_wait_for(const atomic<bool>& atom, bool old, const uint64_t wait_ms) noexcept {
const uint64_t start_time = time_ms();
while (atom.load(std::memory_order_acquire) == old and (time_ms() - start_time < wait_ms)) sleep_ms(1);
}
atomic_lock::atomic_lock(atomic<bool>& atom, bool wait) : atom(atom) {
if (wait) {
bool expected = false;
@@ -564,6 +559,62 @@ namespace Tools {
this->atom.notify_one();
}
void atomic_waiting_lock::store(bool new_value) noexcept {
{
std::lock_guard lock {mtx};
value = new_value;
}
cv.notify_all();
}
void atomic_waiting_lock::wait(bool old) const noexcept {
std::unique_lock lock {mtx};
cv.wait(lock, [this, old] { return value != old; });
}
void atomic_waiting_lock::wait_for(bool old, uint64_t wait_ms) const noexcept {
std::unique_lock lock {mtx};
cv.wait_for(lock, std::chrono::milliseconds(wait_ms), [this, old] { return value != old; });
}
atomic_waiting_lock::guard atomic_waiting_lock::lock(bool wait) {
return guard(*this, wait);
}
atomic_waiting_lock::operator bool() const noexcept {
std::lock_guard lock {mtx};
return value;
}
atomic_waiting_lock::guard::guard(atomic_waiting_lock& atom, bool wait) : atom(atom) {
if (wait) {
std::unique_lock lock {this->atom.mtx};
this->atom.cv.wait(lock, [this] { return not this->atom.value; });
this->atom.value = true;
}
else {
std::lock_guard lock {this->atom.mtx};
this->atom.value = true;
}
this->atom.cv.notify_one();
}
atomic_waiting_lock::guard::~guard() noexcept {
{
std::lock_guard lock {this->atom.mtx};
this->atom.value = false;
}
this->atom.cv.notify_one();
}
void atomic_wait(const atomic_waiting_lock& atom, bool old) noexcept {
atom.wait(old);
}
void atomic_wait_for(const atomic_waiting_lock& atom, bool old, const uint64_t wait_ms) {
atom.wait_for(old, wait_ms);
}
string readfile(const std::filesystem::path& path, const string& fallback) {
if (not fs::exists(path)) return fallback;
string out;

View File

@@ -26,9 +26,11 @@ tab-size = 4
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <cstdint>
#include <filesystem>
#include <limits.h>
#include <mutex>
#include <ranges>
#include <regex>
#include <string>
@@ -366,8 +368,6 @@ namespace Tools {
void atomic_wait(const atomic<bool>& atom, bool old = true) noexcept;
void atomic_wait_for(const atomic<bool>& atom, bool old = true, const uint64_t wait_ms = 0) noexcept;
//* Sets atomic<bool> to true on construct, sets to false on destruct
class atomic_lock {
atomic<bool>& atom;
@@ -380,6 +380,34 @@ namespace Tools {
atomic_lock& operator=(atomic_lock&& other) = delete;
};
class atomic_waiting_lock {
bool value{};
mutable std::mutex mtx;
mutable std::condition_variable cv;
public:
class guard {
atomic_waiting_lock& atom;
public:
explicit guard(atomic_waiting_lock& atom, bool wait = false);
~guard() noexcept;
guard(const guard& other) = delete;
guard& operator=(const guard& other) = delete;
guard(guard&& other) = delete;
guard& operator=(guard&& other) = delete;
};
void store(bool value) noexcept;
void wait(bool old = true) const noexcept;
void wait_for(bool old, uint64_t wait_ms) const noexcept;
[[nodiscard]] guard lock(bool wait = false);
explicit operator bool() const noexcept;
};
void atomic_wait(const atomic_waiting_lock& atom, bool old = true) noexcept;
void atomic_wait_for(const atomic_waiting_lock& atom, bool old = true, const uint64_t wait_ms = 0);
//* Read a complete file and return as a string
string readfile(const std::filesystem::path& path, const string& fallback = "");