• 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 <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