From fd21a457f8d3c5071c3261d74c6f89c31f1af7b6 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 25 Sep 2024 07:16:13 -0500 Subject: [PATCH] GH-529 If an existing handler with the same priority exists for a non-unique id then do not post it --- .../include/eosio/chain/exec_pri_queue.hpp | 14 ++++--------- .../tests/custom_appbase_tests.cpp | 20 +++++++++++-------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/libraries/custom_appbase/include/eosio/chain/exec_pri_queue.hpp b/libraries/custom_appbase/include/eosio/chain/exec_pri_queue.hpp index 07f220867e..39b2a31b20 100644 --- a/libraries/custom_appbase/include/eosio/chain/exec_pri_queue.hpp +++ b/libraries/custom_appbase/include/eosio/chain/exec_pri_queue.hpp @@ -110,16 +110,10 @@ class exec_pri_queue : public boost::asio::execution_context auto i = std::lower_bound(que.ordered_begin(), end, priority, [](const auto& h, int priority) { return h->priority() > priority; }); - if (i != end) { - // ordered iterator appears to only be a forward iterator - // find last posted handler with same priority - auto p = i; - for (; i != end; p = i, ++i) { - if ((*i)->priority() != priority) - break; - } - // if last posted handler with the same priority is same id then do not post it - if ((*p)->priority() == priority && (*p)->id() == id) + // boost::heap ordered iterator is a forward iterator + // if an existing handler with the id exists within the same priority then do not post + for (; i != end && (*i)->priority() == priority; ++i) { + if ((*i)->id() == id) return; } } diff --git a/libraries/custom_appbase/tests/custom_appbase_tests.cpp b/libraries/custom_appbase/tests/custom_appbase_tests.cpp index ab12697859..e76c05cf49 100644 --- a/libraries/custom_appbase/tests/custom_appbase_tests.cpp +++ b/libraries/custom_appbase/tests/custom_appbase_tests.cpp @@ -243,15 +243,19 @@ BOOST_AUTO_TEST_CASE( exec_with_handler_id ) { BOOST_REQUIRE_EQUAL( app->executor().read_write_queue_empty(), true); // does not post if one already exists at the same priority - BOOST_TEST( rslts.size() == 8u ); - - BOOST_TEST(!rslts.contains(1)); // not added to execute - BOOST_TEST(!rslts.contains(3)); // not added to execute - BOOST_TEST(!rslts.contains(5)); // not added to execute - BOOST_TEST(!rslts.contains(7)); // not added to execute - BOOST_TEST(rslts.contains(9)); + BOOST_TEST( rslts.size() == 6u ); + + BOOST_TEST(!rslts.contains(1)); + BOOST_TEST(rslts.contains(2)); + BOOST_TEST(!rslts.contains(3)); + BOOST_TEST(rslts.contains(4)); + BOOST_TEST(!rslts.contains(5)); + BOOST_TEST(rslts.contains(6)); + BOOST_TEST(!rslts.contains(7)); + BOOST_TEST(rslts.contains(8)); + BOOST_TEST(!rslts.contains(9)); BOOST_TEST(rslts.contains(10)); - BOOST_TEST(rslts.contains(11)); + BOOST_TEST(!rslts.contains(11)); } // verify functions only from read_only queue are processed during read window on the main thread