From: Samuel Just Date: Mon, 4 May 2020 18:42:35 +0000 (-0700) Subject: crimson/common/errorator: add errorator do_until X-Git-Tag: v16.1.0~2330^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4425cb072e1b24db8194d79d545f50631b9bbb6a;p=ceph.git crimson/common/errorator: add errorator do_until Signed-off-by: Samuel Just --- diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index d16b3d2b39ac7..b0030142ad2f0 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -45,6 +45,34 @@ inline auto do_for_each(Container& c, AsyncAction action) { return ::crimson::do_for_each(std::begin(c), std::end(c), std::move(action)); } +template +inline auto do_until(AsyncAction action) { + using futurator = \ + ::seastar::futurize>; + + while (true) { + auto f = futurator::invoke(action); + if (!seastar::need_preempt() && f.available() && std::get<0>(f.get())) { + return futurator::type::errorator_type::template make_ready_future<>(); + } + if (!f.available() || seastar::need_preempt()) { + return std::move(f)._then( + [ action = std::move(action)] (auto &&done) mutable { + if (done) { + return futurator::type::errorator_type::template make_ready_future<>(); + } + return ::crimson::do_until( + std::move(action)); + }); + } + if (f.failed()) { + return futurator::type::errorator_type::template make_exception_future2<>( + f.get_exception() + ); + } + } +} + // define the interface between error types and errorator template class error_t { @@ -620,6 +648,9 @@ private: Iterator end, AsyncAction action); + template + friend inline auto ::crimson::do_until(AsyncAction action); + template friend class ::seastar::future;