1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef SRC_META_FUTURE_H 17 #define SRC_META_FUTURE_H 18 19 #include <mutex> 20 #include <thread> 21 22 #include <meta/base/interface_macros.h> 23 #include <meta/ext/minimal_object.h> 24 #include <meta/ext/object_factory.h> 25 #include <meta/ext/task_queue.h> 26 #include <meta/interface/intf_future.h> 27 #include <meta/interface/intf_object_flags.h> 28 #include <meta/interface/intf_promise.h> 29 #include <meta/interface/intf_task_queue.h> 30 #include <meta/interface/object_type_info.h> 31 32 META_BEGIN_NAMESPACE() 33 34 class ContinuationQueueTask; 35 36 class Future final : public IntroduceInterfaces<IFuture> { 37 public: 38 StateType GetState() const override; 39 StateType Wait() const override; 40 StateType WaitFor(const TimeSpan& time) const override; 41 IAny::Ptr GetResult() const override; 42 IFuture::Ptr Then(const IFutureContinuation::Ptr& func, const ITaskQueue::Ptr& queue) override; 43 void Cancel() override; 44 45 void SetResult(IAny::Ptr p); 46 void SetAbandoned(); 47 48 void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token); 49 50 private: 51 // Then continuation support 52 struct ContinuationData { 53 bool runInline {}; 54 ITaskQueue::WeakPtr queue; 55 BASE_NS::shared_ptr<ContinuationQueueTask> continuation; 56 }; 57 58 void ActivateContinuation(std::unique_lock<std::mutex>& lock); 59 void ActivateContinuation(const ContinuationData& d, const IAny::Ptr& result); 60 61 private: 62 mutable std::mutex mutex_; 63 mutable std::condition_variable cond_; 64 IAny::Ptr result_; 65 StateType state_ { IFuture::WAITING }; 66 ITaskQueue::WeakPtr queue_; 67 ITaskQueue::Token token_ {}; 68 BASE_NS::vector<ContinuationData> continuations_; 69 }; 70 71 class Promise final : public MinimalObject<META_NS::ClassId::Promise, IPromise> { 72 using Super = MinimalObject<META_NS::ClassId::Promise, IPromise>; 73 74 public: 75 Promise() = default; META_NO_COPY_MOVE(Promise)76 META_NO_COPY_MOVE(Promise) 77 private: 78 META_DEFINE_OBJECT_TYPE_INFO(Promise, META_NS::ClassId::Promise) 79 80 public: 81 static const StaticObjectMetadata& GetStaticObjectMetadata() 82 { 83 return StaticObjectMeta(); 84 } StaticObjectMeta()85 static StaticObjectMetadata& StaticObjectMeta() 86 { 87 static StaticObjectMetadata meta { META_NS::ClassId::Promise, nullptr }; 88 return meta; 89 } 90 91 public: GetStaticInterfaces()92 static BASE_NS::vector<BASE_NS::Uid> GetStaticInterfaces() 93 { 94 return Super::GetInterfacesVector(); 95 } 96 97 public: 98 ~Promise() override; 99 100 void Set(const IAny::Ptr& res) override; 101 void SetAbandoned() override; 102 [[nodiscard]] IFuture::Ptr GetFuture() override; 103 void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token) override; 104 105 private: 106 BASE_NS::shared_ptr<Future> future_; 107 }; 108 109 class ContinuationQueueTask : public IntroduceInterfaces<ITaskQueueTask> { 110 public: ContinuationQueueTask(IFutureContinuation::Ptr task)111 explicit ContinuationQueueTask(IFutureContinuation::Ptr task) : task_(BASE_NS::move(task)) {} 112 SetParam(IAny::Ptr arg)113 void SetParam(IAny::Ptr arg) 114 { 115 arg_ = BASE_NS::move(arg); 116 } 117 SetQueueInfo(const ITaskQueue::Ptr & queue,ITaskQueue::Token token)118 void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token) 119 { 120 promise_.SetQueueInfo(queue, token); 121 } 122 Invoke()123 bool Invoke() override 124 { 125 promise_.Set(task_->Invoke(arg_)); 126 return false; 127 } 128 GetFuture()129 [[nodiscard]] IFuture::Ptr GetFuture() 130 { 131 return promise_.GetFuture(); 132 } 133 SetAbandoned()134 void SetAbandoned() 135 { 136 promise_.SetAbandoned(); 137 } 138 139 private: 140 IAny::Ptr arg_; 141 IFutureContinuation::Ptr task_; 142 Promise promise_; 143 }; 144 145 META_END_NAMESPACE() 146 147 #endif 148