Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://github.com/mpoquet/simgrid
[simgrid.git] / include / simgrid / kernel / future.hpp
index 5c11dbb..da5bd08 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <xbt/base.h>
 #include <xbt/functional.hpp>
+#include <xbt/future.hpp>
 
 namespace simgrid {
 namespace kernel {
@@ -36,9 +37,9 @@ enum class FutureStatus {
 };
 
 template<class T>
-struct is_future : public std::integral_constant<bool, false> {};
+struct is_future : std::false_type {};
 template<class T>
-struct is_future<Future<T>> : public std::integral_constant<bool, true> {};
+struct is_future<Future<T>> : std::true_type {};
 
 /** Bases stuff for all @ref simgrid::kernel::FutureState<T> */
 class FutureStateBase {
@@ -47,6 +48,8 @@ public:
   FutureStateBase(FutureStateBase const&) = delete;
   FutureStateBase& operator=(FutureStateBase const&) = delete;
 
+  XBT_PUBLIC(void) schedule(simgrid::xbt::Task<void()>&& job);
+
   void set_exception(std::exception_ptr exception)
   {
     xbt_assert(exception_ == nullptr);
@@ -56,7 +59,7 @@ public:
     this->set_ready();
   }
 
-  void set_continuation(simgrid::xbt::Task<void()> continuation)
+  void set_continuation(simgrid::xbt::Task<void()>&& continuation)
   {
     xbt_assert(!continuation_);
     switch (status_) {
@@ -68,7 +71,7 @@ public:
     case FutureStatus::ready:
       // The future is ready, execute the continuation directly.
       // We might execute it from the event loop instead:
-      continuation();
+      schedule(std::move(continuation));
       break;
     case FutureStatus::not_ready:
       // The future is not ready so we mast keep the continuation for
@@ -103,7 +106,7 @@ protected:
       // We need to do this becase the current implementation of the
       // continuation has a shared_ptr to the FutureState.
       auto continuation = std::move(continuation_);
-      continuation();
+      this->schedule(std::move(continuation));
     }
   }
 
@@ -118,6 +121,7 @@ protected:
     status_ = FutureStatus::done;
     if (exception_) {
       std::exception_ptr exception = std::move(exception_);
+      exception_ = nullptr;
       std::rethrow_exception(std::move(exception));
     }
   }
@@ -387,8 +391,6 @@ public:
   }
 
   /** Get the value from the future
-   *
-   *  This is expected to be called
    *
    *  The future must be valid and ready in order to make this call.
    *  @ref std::future blocks when the future is not ready but we are
@@ -420,7 +422,7 @@ Future<T> unwrapFuture(Future<Future<T>> future)
   return std::move(result);
 }
 
-/** Producer side of a @simgrid::kernel::Future
+/** Producer side of a @ref simgrid::kernel::Future
  *
  *  A @ref Promise is connected to some `Future` and can be used to
  *  set its result.