21#include <condition_variable>
28#include <unordered_set>
33void encodeBase64(
const void *data,
size_t size, std::string &out);
37 return h1 + 0x9e3779b9 + (h2 << 6) + (h2 >> 2);
49 using Lock = std::lock_guard<std::mutex>;
52 mutable std::mutex
qM;
57 std::condition_variable
cv;
85 template <
typename... E>
98 std::optional<T>
pop() {
112 std::unique_lock<std::mutex> l(
qM);
113 cv.wait(l, [
this] {
return shutdown || !
q.empty(); });
123 void pop(std::function<
bool(
const T &)> callback) {
176template <
typename ID = u
int16_t>
183 std::lock_guard<std::mutex> lock(
mutex);
197 std::optional<std::chrono::milliseconds> backoff = {}) {
198 std::unique_lock<std::mutex> lock(
mutex);
201 cv.wait_for(lock, *backoff, pred);
212 std::lock_guard<std::mutex> lock(
mutex);
220 std::lock_guard<std::mutex> lock(
mutex);
226 std::condition_variable
cv;
232inline uint64_t
bitsToBytes(uint64_t bits) {
return (bits + 7) / 8; }
Multi-producer / single-consumer dirty-set of channel ids, with CV-style blocking drain semantics.
void requestShutdown()
Signal a clean shutdown: wakes every current and future waitDrain caller, which will then observe fal...
bool isShutdown() const
True once requestShutdown() has been called.
std::condition_variable cv
bool waitDrain(std::unordered_set< ID > &out, std::optional< std::chrono::milliseconds > backoff={})
Block until either requestShutdown() is called or the set is non-empty, then atomically swap the curr...
void markReady(ID id)
Add id to the dirty set and wake the consumer (if any).
std::unordered_set< ID > ready
std::mutex qM
The queue and its mutex.
const std::function< void()> notifier
Optional external notifier invoked after push releases the queue lock.
TSQueue()=default
Default constructor: no external notifier.
bool isShutdown() const
True once requestShutdown() has been called.
TSQueue(std::function< void()> notifier)
Construct a queue that calls notifier after every successful push, once the queue mutex has been rele...
std::mutex popM
A mutex to ensure that only one 'pop' operation is happening at a time.
std::condition_variable cv
CV signalled by push and requestShutdown.
bool empty() const
Is the queue empty?
void push(E... t)
Push onto the queue.
std::lock_guard< std::mutex > Lock
void requestShutdown()
Permanently retire the queue: wake every current and future waitPop() with nullopt so consumer thread...
void pop(std::function< bool(const T &)> callback)
Call the callback for the front of the queue (if anything is there).
std::optional< T > waitPop()
Block until an item is available or requestShutdown() is called.
std::optional< T > pop()
Pop something off the queue but return nullopt if the queue is empty.
uint64_t bitsToBytes(uint64_t bits)
Compute ceil(bits/8).
void encodeBase64(const void *data, size_t size, std::string &out)
size_t hash_combine(size_t h1, size_t h2)
C++'s stdlib doesn't have a hash_combine function. This is a simple one.