]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/common: bring green_get() to interruptor
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Tue, 6 Dec 2022 12:06:39 +0000 (12:06 +0000)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Tue, 28 Feb 2023 16:22:04 +0000 (16:22 +0000)
The rationale
=============
Calling `get()` on an unavailable future can result in yielding
the reactor, so -- from the interruptor's POV -- the interrupt
condition must be handled exactly like it is done for `yield()`.

Interruptor takes care about that but, at the moment, only for the
interruptible futures; there is mechanism for plain `seastar::future`.
This patch paves the way for handling them as well.

Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/crimson/common/interruptible_future.h

index 6ae8689357be1a3694b307d6e03b5e5308ae5f56..c0e2c346c88b34291ac66de4129fefb30ac8fa96 100644 (file)
@@ -1413,6 +1413,28 @@ public:
     return ret;
   }
 
+  template <class FutureT>
+  static decltype(auto) green_get(FutureT&& fut) {
+    if (fut.available()) {
+      return fut.get();
+    } else {
+      // destined to wait!
+      auto interruption_condition = interrupt_cond<InterruptCond>.interrupt_cond;
+      INTR_FUT_DEBUG(
+        "green_get() waiting, interrupt_cond: {},{}",
+        (void*)interrupt_cond<InterruptCond>.interrupt_cond.get(),
+        typeid(InterruptCond).name());
+      interrupt_cond<InterruptCond>.reset();
+      auto&& value = fut.get();
+      interrupt_cond<InterruptCond>.set(interruption_condition);
+      INTR_FUT_DEBUG(
+        "green_get() got, interrupt_cond: {},{}",
+        (void*)interrupt_cond<InterruptCond>.interrupt_cond.get(),
+        typeid(InterruptCond).name());
+      return std::move(value);
+    }
+  }
+
   static void yield() {
     ceph_assert(interrupt_cond<InterruptCond>.interrupt_cond);
     auto interruption_condition = interrupt_cond<InterruptCond>.interrupt_cond;