1 /** 2 * Copyright 2021 Huawei Technologies Co., Ltd 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MINDSPORE_CORE_MINDRT_INCLUDE_ASYNC_FUTURE_BASE_H 18 #define MINDSPORE_CORE_MINDRT_INCLUDE_ASYNC_FUTURE_BASE_H 19 20 #include <future> 21 #include <utility> 22 #include <memory> 23 #include <list> 24 25 #include "actor/actor.h" 26 #include "async/spinlock.h" 27 #include "async/status.h" 28 29 namespace mindspore { 30 template <typename T> 31 class Future; 32 33 template <typename T> 34 class Promise; 35 class LessFuture { 36 public: LessFuture()37 LessFuture() {} LessFuture(const LessFuture & obj)38 LessFuture(const LessFuture &obj) {} 39 LessFuture &operator=(const LessFuture &) = delete; ~LessFuture()40 virtual ~LessFuture() {} 41 }; 42 43 class FutureBase : public LessFuture { 44 public: FutureBase()45 FutureBase() {} FutureBase(const FutureBase & obj)46 FutureBase(const FutureBase &obj) : LessFuture(obj) {} 47 FutureBase &operator=(const FutureBase &) = delete; ~FutureBase()48 ~FutureBase() override {} 49 }; 50 51 template <typename T> 52 struct FutureData { 53 public: 54 typedef std::function<void(const Future<T> &)> CompleteCallback; 55 typedef std::function<void(const Future<T> &)> AbandonedCallback; 56 FutureDataFutureData57 FutureData() 58 : status(MindrtStatus::KINIT), 59 associated(false), 60 abandoned(false), 61 gotten(false), 62 promise(), 63 future(promise.get_future()), 64 t() {} 65 ~FutureDataFutureData66 ~FutureData() { Clear(); } 67 68 // remove all callbacks ClearFutureData69 void Clear() { 70 onCompleteCallbacks.clear(); 71 onAbandonedCallbacks.clear(); 72 } 73 74 // status of future 75 SpinLock lock; 76 MindrtStatus status; 77 78 bool associated; 79 bool abandoned; 80 bool gotten; 81 82 std::promise<T> promise; 83 84 // get from promise 85 std::future<T> future; 86 87 // complete callback 88 std::list<CompleteCallback> onCompleteCallbacks; 89 90 // abandoned callback 91 std::list<AbandonedCallback> onAbandonedCallbacks; 92 93 T t; 94 }; 95 96 namespace internal { 97 template <typename T> 98 class DeferredHelper; 99 100 template <typename T> 101 struct Wrap { 102 typedef Future<T> type; 103 }; 104 105 template <typename T> 106 struct Wrap<Future<T>> { 107 typedef Future<T> type; 108 }; 109 110 template <typename T> 111 struct Unwrap { 112 typedef T type; 113 }; 114 115 template <typename T> 116 struct Unwrap<Future<T>> { 117 typedef T type; 118 }; 119 120 template <typename T> 121 struct IsFuture : public std::integral_constant<bool, std::is_base_of<FutureBase, T>::value> {}; 122 123 template <typename H, typename... Args> 124 static void Run(std::list<H> &&handlers, Args &&... args) { 125 for (auto iter = handlers.begin(); iter != handlers.end(); ++iter) { 126 std::move (*iter)(std::forward<Args>(args)...); 127 } 128 } 129 130 template <typename T> 131 static void Complete(const Future<T> &future, const Future<T> &f) { 132 if (f.IsError()) { 133 future.SetFailed(f.GetErrorCode()); 134 } else if (f.IsOK()) { 135 future.SetValue(f.Get()); 136 } 137 } 138 139 template <typename T> 140 static void Abandon(const Future<T> &future, bool abandon) { 141 future.Abandon(abandon); 142 } 143 144 template <typename T, typename R> 145 static void Thenf(const std::function<Future<R>(const T &)> &function, const std::shared_ptr<Promise<R>> &promise, 146 const Future<T> &f) { 147 if (f.IsError()) { 148 promise->SetFailed(f.GetErrorCode()); 149 } else if (f.IsOK()) { 150 promise->Associate(function(f.Get())); 151 } 152 } 153 154 template <typename T, typename R> 155 static void Then(const std::function<R(const T &)> &function, const std::shared_ptr<Promise<R>> &promise, 156 const Future<T> &f) { 157 if (f.IsError()) { 158 promise->SetFailed(f.GetErrorCode()); 159 } else if (f.IsOK()) { 160 promise->SetValue(function(f.Get())); 161 } 162 } 163 164 template <typename T> 165 static void Afterf(const std::function<Future<T>(const Future<T> &)> &f, const std::shared_ptr<Promise<T>> &promise, 166 const Future<T> &future) { 167 promise->Associate(f(future)); 168 } 169 170 void Waitf(const AID &aid); 171 } // namespace internal 172 } // namespace mindspore 173 174 #endif 175