]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/common/errorator: add errorator do_until
authorSamuel Just <sjust@redhat.com>
Mon, 4 May 2020 18:42:35 +0000 (11:42 -0700)
committerSamuel Just <sjust@redhat.com>
Thu, 7 May 2020 06:40:34 +0000 (23:40 -0700)
Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/common/errorator.h

index d16b3d2b39ac7d87ab90cac4a7bd46d0d1d38984..b0030142ad2f07bd75005a7ea68f9a8d288de936 100644 (file)
@@ -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<typename AsyncAction>
+inline auto do_until(AsyncAction action) {
+  using futurator = \
+    ::seastar::futurize<std::result_of_t<AsyncAction()>>;
+
+  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 ConcreteErrorT>
 class error_t {
@@ -620,6 +648,9 @@ private:
                                               Iterator end,
                                               AsyncAction action);
 
+    template<typename AsyncAction>
+    friend inline auto ::crimson::do_until(AsyncAction action);
+
     template <class...>
     friend class ::seastar::future;