• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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