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 META_SRC_FUTURE_H 17 #define META_SRC_FUTURE_H 18 19 #include <condition_variable> 20 #include <mutex> 21 #include <thread> 22 23 #include <base/containers/shared_ptr.h> 24 25 #include <meta/base/interface_macros.h> 26 #include <meta/base/namespace.h> 27 #include <meta/ext/minimal_object.h> 28 #include <meta/ext/object_factory.h> 29 #include <meta/ext/task_queue.h> 30 #include <meta/interface/intf_future.h> 31 #include <meta/interface/intf_object_flags.h> 32 #include <meta/interface/intf_promise.h> 33 #include <meta/interface/intf_task_queue.h> 34 #include <meta/interface/object_type_info.h> 35 36 META_BEGIN_NAMESPACE() 37 38 class ContinuationQueueTask; 39 40 class IFutureSetInfo : public CORE_NS::IInterface { 41 META_INTERFACE(CORE_NS::IInterface, IFutureSetInfo, "3aad605c-080f-447a-b013-f1f7d68216ba") 42 public: 43 virtual void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token) = 0; 44 }; 45 46 class Future final : public IntroduceInterfaces<IFuture, IFutureSetInfo> { 47 public: 48 StateType GetState() const override; 49 StateType Wait() const override; 50 StateType WaitFor(const TimeSpan& time) const override; 51 IAny::Ptr GetResult() const override; 52 IFuture::Ptr Then(const IFutureContinuation::Ptr& func, const ITaskQueue::Ptr& queue) override; 53 void Cancel() override; 54 55 void SetResult(IAny::Ptr p); 56 void SetAbandoned(); 57 58 void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token) override; 59 60 private: 61 // Then continuation support 62 struct ContinuationData { 63 bool runInline {}; 64 ITaskQueue::WeakPtr queue; 65 BASE_NS::shared_ptr<ContinuationQueueTask> continuation; 66 }; 67 68 void ActivateContinuation(std::unique_lock<std::mutex>& lock); 69 void ActivateContinuation(ContinuationData d, const IAny::Ptr& result); 70 71 private: 72 mutable std::mutex mutex_; 73 mutable std::condition_variable cond_; 74 IAny::Ptr result_; 75 StateType state_ { IFuture::WAITING }; 76 ITaskQueue::WeakPtr queue_; 77 ITaskQueue::Token token_ {}; 78 BASE_NS::vector<ContinuationData> continuations_; 79 }; 80 81 class Promise final : public IntroduceInterfaces<MinimalObject, IPromise> { 82 META_OBJECT(Promise, META_NS::ClassId::Promise, IntroduceInterfaces) 83 public: 84 Promise() = default; 85 META_NO_COPY_MOVE(Promise) 86 public: 87 ~Promise() override; 88 89 void Set(const IAny::Ptr& res) override; 90 void SetAbandoned() override; 91 [[nodiscard]] IFuture::Ptr GetFuture() override; 92 void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token) override; 93 94 private: 95 BASE_NS::shared_ptr<Future> future_; 96 }; 97 98 class ContinuationQueueTask : public IntroduceInterfaces<ITaskQueueTask> { 99 public: ContinuationQueueTask(IFutureContinuation::Ptr task)100 explicit ContinuationQueueTask(IFutureContinuation::Ptr task) : task_(BASE_NS::move(task)) {} 101 SetParam(IAny::Ptr arg)102 void SetParam(IAny::Ptr arg) 103 { 104 arg_ = BASE_NS::move(arg); 105 } 106 SetQueueInfo(const ITaskQueue::Ptr & queue,ITaskQueue::Token token)107 void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token) 108 { 109 promise_.SetQueueInfo(queue, token); 110 } 111 Invoke()112 bool Invoke() override 113 { 114 promise_.Set(task_->Invoke(arg_)); 115 return false; 116 } 117 GetFuture()118 [[nodiscard]] IFuture::Ptr GetFuture() 119 { 120 return promise_.GetFuture(); 121 } 122 SetAbandoned()123 void SetAbandoned() 124 { 125 promise_.SetAbandoned(); 126 } 127 128 private: 129 IAny::Ptr arg_; 130 IFutureContinuation::Ptr task_; 131 Promise promise_; 132 }; 133 134 META_END_NAMESPACE() 135 136 #endif 137