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 <iostream> 22 #include <string> 23 #include <utility> 24 #include <memory> 25 #include <list> 26 27 #include "actor/actor.h" 28 #include "actor/log.h" 29 #include "async/spinlock.h" 30 #include "async/status.h" 31 32 namespace mindspore { 33 34 template <typename T> 35 class Future; 36 37 template <typename T> 38 class Promise; 39 40 class LessFuture { 41 public: LessFuture()42 LessFuture() {} LessFuture(const LessFuture & obj)43 LessFuture(const LessFuture &obj) {} 44 LessFuture &operator=(const LessFuture &) = delete; ~LessFuture()45 virtual ~LessFuture() {} 46 }; 47 48 class FutureBase : public LessFuture { 49 public: FutureBase()50 FutureBase() {} FutureBase(const FutureBase & obj)51 FutureBase(const FutureBase &obj) : LessFuture(obj) {} 52 FutureBase &operator=(const FutureBase &) = delete; ~FutureBase()53 ~FutureBase() override {} 54 }; 55 56 template <typename T> 57 struct FutureData { 58 public: 59 typedef std::function<void(const Future<T> &)> CompleteCallback; 60 typedef std::function<void(const Future<T> &)> AbandonedCallback; 61 FutureDataFutureData62 FutureData() 63 : status(MindrtStatus::KINIT), 64 associated(false), 65 abandoned(false), 66 gotten(false), 67 promise(), 68 future(promise.get_future()), 69 t() {} 70 ~FutureDataFutureData71 ~FutureData() { 72 // try { 73 Clear(); 74 // } catch (...) { 75 // } 76 } 77 78 // remove all callbacks ClearFutureData79 void Clear() { 80 onCompleteCallbacks.clear(); 81 onAbandonedCallbacks.clear(); 82 } 83 84 // status of future 85 SpinLock lock; 86 MindrtStatus status; 87 88 bool associated; 89 bool abandoned; 90 bool gotten; 91 92 std::promise<T> promise; 93 94 // get from promise 95 std::future<T> future; 96 97 // complete callback 98 std::list<CompleteCallback> onCompleteCallbacks; 99 100 // abandoned callback 101 std::list<AbandonedCallback> onAbandonedCallbacks; 102 103 T t; 104 }; 105 106 namespace internal { 107 108 template <typename T> 109 class DeferredHelper; 110 111 template <typename T> 112 struct Wrap { 113 typedef Future<T> type; 114 }; 115 116 template <typename T> 117 struct Wrap<Future<T>> { 118 typedef Future<T> type; 119 }; 120 121 template <typename T> 122 struct Unwrap { 123 typedef T type; 124 }; 125 126 template <typename T> 127 struct Unwrap<Future<T>> { 128 typedef T type; 129 }; 130 131 template <typename T> 132 struct IsFuture : public std::integral_constant<bool, std::is_base_of<FutureBase, T>::value> {}; 133 134 template <typename H, typename... Args> 135 static void Run(std::list<H> &&handlers, Args &&... args) { 136 for (auto iter = handlers.begin(); iter != handlers.end(); ++iter) { 137 std::move (*iter)(std::forward<Args>(args)...); 138 } 139 } 140 141 template <typename T> 142 static void Complete(const Future<T> &future, const Future<T> &f) { 143 if (f.IsError()) { 144 future.SetFailed(f.GetErrorCode()); 145 } else if (f.IsOK()) { 146 future.SetValue(f.Get()); 147 } 148 } 149 150 template <typename T> 151 static void Abandon(const Future<T> &future, bool abandon) { 152 future.Abandon(abandon); 153 } 154 155 template <typename T, typename R> 156 static void Thenf(const std::function<Future<R>(const T &)> &function, const std::shared_ptr<Promise<R>> &promise, 157 const Future<T> &f) { 158 if (f.IsError()) { 159 promise->SetFailed(f.GetErrorCode()); 160 } else if (f.IsOK()) { 161 promise->Associate(function(f.Get())); 162 } 163 } 164 165 template <typename T, typename R> 166 static void Then(const std::function<R(const T &)> &function, const std::shared_ptr<Promise<R>> &promise, 167 const Future<T> &f) { 168 if (f.IsError()) { 169 promise->SetFailed(f.GetErrorCode()); 170 } else if (f.IsOK()) { 171 promise->SetValue(function(f.Get())); 172 } 173 } 174 175 template <typename T> 176 static void Afterf(const std::function<Future<T>(const Future<T> &)> &f, const std::shared_ptr<Promise<T>> &promise, 177 const Future<T> &future) { 178 promise->Associate(f(future)); 179 } 180 181 void Waitf(const AID &aid); 182 183 } // namespace internal 184 185 } // namespace mindspore 186 187 #endif 188