From aa2fe8ccbfcb117efa207d10229eeeac5d0f97c7 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 6 Feb 2023 17:11:30 +0100 Subject: Adding upstream version 1.38.0. Signed-off-by: Daniel Baumann --- ml/Queue.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ml/Queue.h (limited to 'ml/Queue.h') diff --git a/ml/Queue.h b/ml/Queue.h new file mode 100644 index 000000000..37a74bd07 --- /dev/null +++ b/ml/Queue.h @@ -0,0 +1,66 @@ +#ifndef QUEUE_H +#define QUEUE_H + +#include "ml-private.h" +#include "Mutex.h" +#include +#include +#include + +template +class Queue { +public: + Queue(void) : Q(), M() { + pthread_cond_init(&CV, nullptr); + Exit = false; + } + + ~Queue() { + pthread_cond_destroy(&CV); + } + + void push(T t) { + std::lock_guard L(M); + + Q.push(t); + pthread_cond_signal(&CV); + } + + std::pair pop(void) { + std::lock_guard L(M); + + while (Q.empty()) { + pthread_cond_wait(&CV, M.inner()); + + if (Exit) { + // This should happen only when we are destroying a host. + // Callers should use a flag dedicated to checking if we + // are about to delete the host or exit the agent. The original + // implementation would call pthread_exit which would cause + // the queue's mutex to be destroyed twice (and fail on the + // 2nd time) + return { T(), 0 }; + } + } + + T V = Q.front(); + size_t Size = Q.size(); + Q.pop(); + + return { V, Size }; + } + + void signal() { + std::lock_guard L(M); + Exit = true; + pthread_cond_signal(&CV); + } + +private: + std::queue Q; + Mutex M; + pthread_cond_t CV; + std::atomic Exit; +}; + +#endif /* QUEUE_H */ -- cgit v1.2.3