jeudi 20 avril 2023

C++11 code for removing delay-queue elements in temporal order

I need to remove elements from a delay-queue in temporal order (where earlier elements have higher priority). I have a C++11 solution, but I'm wondering if there isn't a better one.

The relevant sections of code are these. (Please forgive or correct any typos.)

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <queue>
...
using Clock = std::steady_clock;
using Value = ...; ///< The values stored in the delay-queue

std::mutex              mutex;
std::condition_variable cond;
struct Elt {
    Value             value;
    Clock::time_point time;
    Elt(const Value& value, const Clock::time_point& time)
        : value(value)
        , time(time)
    {}
    bool operator<(const Elt& rhs) {
        return time > rhs.time; // Later times have lower priority
    }
}
std::priority_queue<Elt> queue; ///< The delay-queue
...
    // On one thread
    Clock::duration delay = ...; ///< The delay before the value should be removed
    std::lock_guard guard{mutex};
    queue.emplace(value, Clock::now() + delay);
    cond.notify_one();
...
    // On another thread
    std::unique_lock lock{mutex};

    if (queue.empty())
        cond.wait(lock, [&]{return !queue.empty();});

    auto pred = [&]{return queue.top().time >= Clock::now();};
    cond.wait_until(lock, queue.top().time, pred);

    auto value = queue.top().value;
    queue.pop();
...

In particular, I wonder if two condition-variable calls are necessary to ensure correct behavior under all circumstances.

Is there a "better" way?

Aucun commentaire:

Enregistrer un commentaire