X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/65beede857f93e33c96e544f76b93793c973dc10..3dd753cd9e46d794e00629d03183250aec4a17e4:/include/simgrid/kernel/future.hpp diff --git a/include/simgrid/kernel/future.hpp b/include/simgrid/kernel/future.hpp index fea70d43f0..ac6a4486a3 100644 --- a/include/simgrid/kernel/future.hpp +++ b/include/simgrid/kernel/future.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019. The SimGrid Team. +/* Copyright (c) 2016-2022. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -17,7 +17,7 @@ #include #include -#include +#include namespace simgrid { namespace kernel { @@ -48,7 +48,7 @@ public: FutureStateBase(FutureStateBase const&) = delete; FutureStateBase& operator=(FutureStateBase const&) = delete; - XBT_PUBLIC void schedule(simgrid::xbt::Task&& job); + XBT_PUBLIC void schedule(simgrid::xbt::Task&& job) const; void set_exception(std::exception_ptr exception) { @@ -74,7 +74,7 @@ public: schedule(std::move(continuation)); break; case FutureStatus::not_ready: - // The future is not ready so we mast keep the continuation for + // The future is not ready so we must keep the continuation for // executing it later: continuation_ = std::move(continuation); break; @@ -103,7 +103,7 @@ protected: status_ = FutureStatus::ready; if (continuation_) { // We unregister the continuation before executing it. - // We need to do this becase the current implementation of the + // We need to do this because the current implementation of the // continuation has a shared_ptr to the FutureState. auto continuation = std::move(continuation_); this->schedule(std::move(continuation)); @@ -116,8 +116,7 @@ protected: **/ void resolve() { - if (status_ != FutureStatus::ready) - xbt_die("Deadlock: this future is not ready"); + xbt_assert(status_ == FutureStatus::ready, "Deadlock: this future is not ready"); status_ = FutureStatus::done; if (exception_) { std::exception_ptr exception = std::move(exception_); @@ -135,14 +134,13 @@ private: /** Shared state for future and promises * * You are not expected to use them directly but to create them - * implicitely through a @ref simgrid::kernel::Promise. + * implicitly through a @ref simgrid::kernel::Promise. * Alternatively kernel operations could inherit or contain FutureState * if they are managed with std::shared_ptr. **/ template class FutureState : public FutureStateBase { public: - void set_value(T value) { if (this->get_status() != FutureStatus::not_ready) @@ -222,11 +220,11 @@ template Future unwrap_future(Future> future); /** Result of some (probably) asynchronous operation in the SimGrid kernel * * @ref simgrid::simix::Future and @ref simgrid::simix::Future provide an - * abstration for asynchronous stuff happening in the SimGrid kernel. They + * abstraction for asynchronous stuff happening in the SimGrid kernel. They * are based on C++1z futures. * * The future represents a value which will be available at some point when this - * asynchronous operaiont is finished. Alternatively, if this operations fails, + * asynchronous operation is finished. Alternatively, if this operations fails, * the result of the operation might be an exception. * * As the operation is possibly no terminated yet, we cannot get the result @@ -247,7 +245,7 @@ template Future unwrap_future(Future> future); * // available: * try { * // Try to get value, this might throw an exception if the operation - * // failed (such as an exception throwed by the worker process): + * // failed (such as an exception thrown by the worker process): * std::string value = result.get(); * XBT_INFO("Value: %s", value.c_str()); * } @@ -268,7 +266,7 @@ template Future unwrap_future(Future> future); * * inside the `.then()`, `.get()` can be used; * * * `.get()` can only be used when `.is_ready()` (as everything happens in - * a single-thread, the future would be guaranted to deadlock if `.get()` + * a single-thread, the future would be guaranteed to deadlock if `.get()` * is called when the future is not ready); * * * there is no future chaining support for now (`.then().then()`); @@ -280,17 +278,12 @@ class Future { public: Future() = default; explicit Future(std::shared_ptr> state) : state_(std::move(state)) {} - ~Future() = default; // Move type: Future(Future&) = delete; - Future& operator=(Future&) = delete; - Future(Future&& that) : state_(std::move(that.state_)) {} - Future& operator=(Future&& that) - { - state_ = std::move(that.state_); - return *this; - } + Future& operator=(const Future&) = delete; + Future(Future&&) noexcept = default; + Future& operator=(Future&&) noexcept = default; /** Whether the future is valid:. * @@ -334,7 +327,7 @@ public: */ template auto then_no_unwrap(F continuation) -> Future { - typedef decltype(continuation(std::move(*this))) R; + using R = decltype(continuation(std::move(*this))); if (state_ == nullptr) throw std::future_error(std::future_errc::no_state); auto state = std::move(state_); @@ -363,19 +356,16 @@ public: * @exception std::future_error no state is associated with the future */ template - auto then(F continuation) -> typename std::enable_if::value, - Future>::type + auto then(F continuation) -> typename std::enable_if_t::value, + Future> { return this->then_no_unwrap(std::move(continuation)); } /** Attach a continuation to this future (future chaining) */ - template - auto then(F continuation) - -> typename std::enable_if< - is_future::value, - decltype(continuation(std::move(*this))) - >::type + template + auto then(F continuation) -> typename std::enable_if_t::value, + decltype(continuation(std::move(*this)))> { return unwrap_future(this->then_no_unwrap(std::move(continuation))); } @@ -423,7 +413,7 @@ template Future unwrap_future(Future> future) * auto promise = std::make_shared>(); * auto future = promise->get_future(); * - * simgrid::simix::Timer::set(date, [promise] { + * simgrid::kernel::timer::Timer::set(date, [promise] { * try { * int value = compute_the_value(); * if (value < 0) @@ -433,8 +423,8 @@ template Future unwrap_future(Future> future) * promise.set_value(value); * } * catch (...) { - * // If an error occured, we can set an exception which - * // will be throwed buy future.get(): + * // If an error occurred, we can set an exception which + * // will be thrown by future.get(): * promise.set_exception(std::current_exception()); * } * }); @@ -446,19 +436,15 @@ template Future unwrap_future(Future> future) template class Promise { public: - Promise() : state_(std::make_shared>()) {} + Promise() = default; explicit Promise(std::shared_ptr> state) : state_(std::move(state)) {} // Move type Promise(Promise const&) = delete; Promise& operator=(Promise const&) = delete; - Promise(Promise&& that) : - state_(std::move(that.state_)), future_get_(that.future_get_) - { - that.future_get_ = false; - } + Promise(Promise&& that) noexcept : state_(std::move(that.state_)) { std::swap(future_get_, that.future_get_); } - Promise& operator=(Promise&& that) + Promise& operator=(Promise&& that) noexcept { this->state_ = std::move(that.state_); this->future_get_ = that.future_get_; @@ -494,14 +480,14 @@ public: } private: - std::shared_ptr> state_; + std::shared_ptr> state_ = std::make_shared>(); bool future_get_ = false; }; template<> class Promise { public: - Promise() : state_(std::make_shared>()) {} + Promise() = default; explicit Promise(std::shared_ptr> state) : state_(std::move(state)) {} ~Promise() { @@ -513,12 +499,8 @@ public: // Move type Promise(Promise const&) = delete; Promise& operator=(Promise const&) = delete; - Promise(Promise&& that) : - state_(std::move(that.state_)), future_get_(that.future_get_) - { - that.future_get_ = false; - } - Promise& operator=(Promise&& that) + Promise(Promise&& that) noexcept : state_(std::move(that.state_)) { std::swap(future_get_, that.future_get_); } + Promise& operator=(Promise&& that) noexcept { this->state_ = std::move(that.state_); this->future_get_ = that.future_get_; @@ -535,13 +517,13 @@ public: future_get_ = true; return Future(state_); } - void set_value() + void set_value() const { if (state_ == nullptr) throw std::future_error(std::future_errc::no_state); state_->set_value(); } - void set_exception(std::exception_ptr exception) + void set_exception(std::exception_ptr exception) const { if (state_ == nullptr) throw std::future_error(std::future_errc::no_state); @@ -549,7 +531,7 @@ public: } private: - std::shared_ptr> state_; + std::shared_ptr> state_ = std::make_shared>(); bool future_get_ = false; };