From 68d6c44e06c47271baf543d9edbc14a15b86777a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:32:57 +0100 Subject: [PATCH] Track writer request id --- nano/store/write_queue.cpp | 24 ++++++++++++++---------- nano/store/write_queue.hpp | 4 +++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/nano/store/write_queue.cpp b/nano/store/write_queue.cpp index 41b687ce7..9791a0645 100644 --- a/nano/store/write_queue.cpp +++ b/nano/store/write_queue.cpp @@ -66,7 +66,9 @@ nano::store::write_guard nano::store::write_queue::wait (writer writer) bool nano::store::write_queue::contains (writer writer) const { nano::lock_guard guard{ mutex }; - return std::find (queue.cbegin (), queue.cend (), writer) != queue.cend (); + return std::any_of (queue.cbegin (), queue.cend (), [writer] (auto const & item) { + return item.first == writer; + }); } void nano::store::write_queue::pop () @@ -83,17 +85,19 @@ void nano::store::write_queue::acquire (writer writer) { nano::unique_lock lock{ mutex }; - // There should be no duplicates in the queue - debug_assert (std::none_of (queue.cbegin (), queue.cend (), [writer] (auto const & item) { return item == writer; })); + // There should be no duplicates in the queue (exception is testing) + debug_assert (std::none_of (queue.cbegin (), queue.cend (), [writer] (auto const & item) { + return item.first == writer; + }) + || writer == writer::testing); + + auto const id = next++; // Add writer to the end of the queue if it's not already waiting - auto exists = std::find (queue.cbegin (), queue.cend (), writer) != queue.cend (); - if (!exists) - { - queue.push_back (writer); - } + queue.push_back ({ writer, id }); - condition.wait (lock, [&] () { return queue.front () == writer; }); + // Wait until we are at the front of the queue + condition.wait (lock, [&] () { return queue.front ().second == id; }); } void nano::store::write_queue::release (writer writer) @@ -101,7 +105,7 @@ void nano::store::write_queue::release (writer writer) { nano::lock_guard guard{ mutex }; release_assert (!queue.empty ()); - release_assert (queue.front () == writer); + release_assert (queue.front ().first == writer); queue.pop_front (); } condition.notify_all (); diff --git a/nano/store/write_queue.hpp b/nano/store/write_queue.hpp index 6b4688618..0171685b8 100644 --- a/nano/store/write_queue.hpp +++ b/nano/store/write_queue.hpp @@ -70,7 +70,9 @@ private: void release (writer writer); private: - std::deque queue; + uint64_t next{ 0 }; + using entry = std::pair; // uint64_t is a unique id for each write_guard + std::deque queue; mutable nano::mutex mutex; nano::condition_variable condition;