X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/b8df87e176f27b25534f27d7e240defa32ca35bc..b9625f82f86db0674e911887addce45dca31b57f:/include/simgrid/kernel/future.hpp diff --git a/include/simgrid/kernel/future.hpp b/include/simgrid/kernel/future.hpp index 30f7f51b1d..906d702937 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-2020. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -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)); @@ -135,14 +135,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) @@ -157,7 +156,7 @@ public: xbt_assert(this->value_); auto result = std::move(this->value_.get()); this->value_ = boost::optional(); - return std::move(result); + return result; } private: @@ -204,11 +203,11 @@ public: } }; -template void bind_promise(Promise promise, Future future) +template void bind_promise(Promise&& promise, Future future) { class PromiseBinder { public: - explicit PromiseBinder(Promise promise) : promise_(std::move(promise)) {} + explicit PromiseBinder(Promise&& promise) : promise_(std::move(promise)) {} void operator()(Future future) { simgrid::xbt::set_promise(promise_, future); } private: @@ -219,25 +218,14 @@ template void bind_promise(Promise promise, Future future) template Future unwrap_future(Future> future); -template -XBT_ATTRIB_DEPRECATED_v323("Please use bind_promise") void bindPromise(Promise promise, Future future) -{ - bind_promise(promise, future); -} -template -XBT_ATTRIB_DEPRECATED_v323("Please use unwrap_future") Future unwrapFuture(Future> future) -{ - unwrap_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 @@ -258,7 +246,7 @@ XBT_ATTRIB_DEPRECATED_v323("Please use unwrap_future") Future unwrapFuture(Fu * // 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()); * } @@ -279,7 +267,7 @@ XBT_ATTRIB_DEPRECATED_v323("Please use unwrap_future") Future unwrapFuture(Fu * * 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()`); @@ -291,16 +279,13 @@ 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:. * @@ -356,19 +341,12 @@ public: [](Promise promise, std::shared_ptr> state, F continuation) { // ...set the new future value by running the continuation. Future future(std::move(state)); - simgrid::xbt::fulfill_promise(promise, [&] { return continuation(std::move(future)); }); + simgrid::xbt::fulfill_promise(promise, [&continuation, &future] { return continuation(std::move(future)); }); }, std::move(promise), state, std::move(continuation))); return future; } - template - XBT_ATTRIB_DEPRECATED_v323("Please use then_no_unwrap") auto thenNoUnwrap(F continuation) - -> Future - { - then_no_unwrap(continuation); - } - /** Attach a continuation to this future * * The future must be valid in order to make this call. @@ -425,7 +403,7 @@ template Future unwrap_future(Future> future) Promise promise; Future result = promise.get_future(); bind_promise(std::move(promise), std::move(future)); - return std::move(result); + return result; } /** Producer side of a @ref simgrid::kernel::Future @@ -440,7 +418,7 @@ template Future unwrap_future(Future> future) * auto promise = std::make_shared>(); * auto future = promise->get_future(); * - * SIMIX_timer_set(date, [promise] { + * simgrid::simix::Timer::set(date, [promise] { * try { * int value = compute_the_value(); * if (value < 0) @@ -450,8 +428,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()); * } * }); @@ -463,19 +441,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_; @@ -511,14 +485,14 @@ public: } private: - std::shared_ptr> state_; + std::shared_ptr> state_{new FutureState()}; 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() { @@ -530,12 +504,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_; @@ -552,13 +522,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); @@ -566,7 +536,7 @@ public: } private: - std::shared_ptr> state_; + std::shared_ptr> state_{new FutureState()}; bool future_get_ = false; };