@@ -70,12 +70,21 @@ RepRequest::interruptible_future<> RepRequest::with_pg_interruptible(
7070 LOG_PREFIX (RepRequest::with_pg_interruptible);
7171 DEBUGI (" {}" , *this );
7272 co_await this ->template enter_stage <interruptor>(repop_pipeline (*pg).process );
73- co_await interruptor::make_interruptible (this ->template with_blocking_event <
74- PG_OSDMapGate::OSDMapBlocker::BlockingEvent
75- >([this , pg](auto &&trigger) {
76- return pg->osdmap_gate .wait_for_map (
77- std::move (trigger), req->min_epoch );
78- }));
73+ {
74+ /* Splitting this expression into a fut and a seperate co_await
75+ * works around a gcc 11 bug (observed on 11.4.1 and gcc 11.5.0)
76+ * which results in the pg ref captured by the lambda being
77+ * destructed twice. We can probably remove these workarounds
78+ * once we disallow gcc 11 */
79+ auto fut = interruptor::make_interruptible (
80+ this ->template with_blocking_event <
81+ PG_OSDMapGate::OSDMapBlocker::BlockingEvent
82+ >([this , pg](auto &&trigger) {
83+ return pg->osdmap_gate .wait_for_map (
84+ std::move (trigger), req->min_epoch );
85+ }));
86+ co_await std::move (fut);
87+ }
7988
8089 if (pg->can_discard_replica_op (*req)) {
8190 co_return ;
@@ -107,9 +116,11 @@ seastar::future<> RepRequest::with_pg(
107116 return with_pg_interruptible (pg);
108117 }, [](std::exception_ptr) {
109118 return seastar::now ();
110- }, pg, pg->get_osdmap_epoch ()).finally ([this , ref=std::move (ref)] {
119+ }, pg, pg->get_osdmap_epoch ()
120+ ).finally ([this , pg, ref=std::move (ref)]() mutable {
111121 logger ().debug (" {}: exit" , *this );
112- return handle.complete ();
122+ return handle.complete (
123+ ).finally ([ref=std::move (ref), pg=std::move (pg)] {});
113124 });
114125}
115126
0 commit comments