From: Samuel Just Date: Sat, 7 May 2022 07:02:58 +0000 (+0000) Subject: crimson/common/operation: trim AggregateBlockingEvent::events entries X-Git-Tag: v18.0.0~937^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=29a00b4482761a3ca3fe6b5b314a1327d34a54f5;p=ceph-ci.git crimson/common/operation: trim AggregateBlockingEvent::events entries PglogBasedRecovery and BackfillRecovery reuse the same Operation until their respective operations are complete. Each recovery operation adds an entry to AggregateBlockingEvent::events. This way, we only retain entries that are currently blocking. Signed-off-by: Samuel Just --- diff --git a/src/crimson/common/operation.h b/src/crimson/common/operation.h index ec224deb7d9..2622a69d6ee 100644 --- a/src/crimson/common/operation.h +++ b/src/crimson/common/operation.h @@ -232,28 +232,58 @@ private: template struct AggregateBlockingEvent { struct TriggerI { + protected: + struct TriggerContainerI { + virtual typename T::TriggerI& get_trigger() = 0; + virtual ~TriggerContainerI() = default; + }; + using TriggerContainerIRef = std::unique_ptr; + virtual TriggerContainerIRef create_part_trigger() = 0; + + public: template auto maybe_record_blocking(FutureT&& fut, const typename T::Blocker& blocker) { // AggregateBlockingEvent is supposed to be used on relatively cold // paths (recovery), so we don't need to worry about the dynamic // polymothps / dynamic memory's overhead. - return create_part_trigger()->maybe_record_blocking( - std::move(fut), blocker); + auto tcont = create_part_trigger(); + return tcont->get_trigger().maybe_record_blocking( + std::move(fut), blocker + ).finally([tcont=std::move(tcont)] {}); } - virtual std::unique_ptr create_part_trigger() = 0; virtual ~TriggerI() = default; }; template - struct Trigger : TriggerI { + struct Trigger final : TriggerI { Trigger(AggregateBlockingEvent& event, const OpT& op) : event(event), op(op) {} - std::unique_ptr create_part_trigger() override { - return std::make_unique>( - event.events.emplace_back(), op); + class TriggerContainer final : public TriggerI::TriggerContainerI { + AggregateBlockingEvent& event; + typename decltype(event.events)::iterator iter; + typename T::template Trigger trigger; + + typename T::TriggerI &get_trigger() final { + return trigger; + } + + public: + TriggerContainer(AggregateBlockingEvent& _event, const OpT& op) : + event(_event), + iter(event.events.emplace(event.events.end())), + trigger(*iter, op) {} + + ~TriggerContainer() final { + event.events.erase(iter); + } + }; + + protected: + typename TriggerI::TriggerContainerIRef create_part_trigger() final { + return std::make_unique(event, op); } private: