18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#ifndef SRC_META_FUTURE_H
178bf80f4bSopenharmony_ci#define SRC_META_FUTURE_H
188bf80f4bSopenharmony_ci
198bf80f4bSopenharmony_ci#include <mutex>
208bf80f4bSopenharmony_ci#include <thread>
218bf80f4bSopenharmony_ci
228bf80f4bSopenharmony_ci#include <meta/base/interface_macros.h>
238bf80f4bSopenharmony_ci#include <meta/ext/minimal_object.h>
248bf80f4bSopenharmony_ci#include <meta/ext/object_factory.h>
258bf80f4bSopenharmony_ci#include <meta/ext/task_queue.h>
268bf80f4bSopenharmony_ci#include <meta/interface/intf_future.h>
278bf80f4bSopenharmony_ci#include <meta/interface/intf_object_flags.h>
288bf80f4bSopenharmony_ci#include <meta/interface/intf_promise.h>
298bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue.h>
308bf80f4bSopenharmony_ci#include <meta/interface/object_type_info.h>
318bf80f4bSopenharmony_ci
328bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
338bf80f4bSopenharmony_ci
348bf80f4bSopenharmony_ciclass ContinuationQueueTask;
358bf80f4bSopenharmony_ci
368bf80f4bSopenharmony_ciclass Future final : public IntroduceInterfaces<IFuture> {
378bf80f4bSopenharmony_cipublic:
388bf80f4bSopenharmony_ci    StateType GetState() const override;
398bf80f4bSopenharmony_ci    StateType Wait() const override;
408bf80f4bSopenharmony_ci    StateType WaitFor(const TimeSpan& time) const override;
418bf80f4bSopenharmony_ci    IAny::Ptr GetResult() const override;
428bf80f4bSopenharmony_ci    IFuture::Ptr Then(const IFutureContinuation::Ptr& func, const ITaskQueue::Ptr& queue) override;
438bf80f4bSopenharmony_ci    void Cancel() override;
448bf80f4bSopenharmony_ci
458bf80f4bSopenharmony_ci    void SetResult(IAny::Ptr p);
468bf80f4bSopenharmony_ci    void SetAbandoned();
478bf80f4bSopenharmony_ci
488bf80f4bSopenharmony_ci    void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token);
498bf80f4bSopenharmony_ci
508bf80f4bSopenharmony_ciprivate:
518bf80f4bSopenharmony_ci    // Then continuation support
528bf80f4bSopenharmony_ci    struct ContinuationData {
538bf80f4bSopenharmony_ci        bool runInline {};
548bf80f4bSopenharmony_ci        ITaskQueue::WeakPtr queue;
558bf80f4bSopenharmony_ci        BASE_NS::shared_ptr<ContinuationQueueTask> continuation;
568bf80f4bSopenharmony_ci    };
578bf80f4bSopenharmony_ci
588bf80f4bSopenharmony_ci    void ActivateContinuation(std::unique_lock<std::mutex>& lock);
598bf80f4bSopenharmony_ci    void ActivateContinuation(const ContinuationData& d, const IAny::Ptr& result);
608bf80f4bSopenharmony_ci
618bf80f4bSopenharmony_ciprivate:
628bf80f4bSopenharmony_ci    mutable std::mutex mutex_;
638bf80f4bSopenharmony_ci    mutable std::condition_variable cond_;
648bf80f4bSopenharmony_ci    IAny::Ptr result_;
658bf80f4bSopenharmony_ci    StateType state_ { IFuture::WAITING };
668bf80f4bSopenharmony_ci    ITaskQueue::WeakPtr queue_;
678bf80f4bSopenharmony_ci    ITaskQueue::Token token_ {};
688bf80f4bSopenharmony_ci    BASE_NS::vector<ContinuationData> continuations_;
698bf80f4bSopenharmony_ci};
708bf80f4bSopenharmony_ci
718bf80f4bSopenharmony_ciclass Promise final : public MinimalObject<META_NS::ClassId::Promise, IPromise> {
728bf80f4bSopenharmony_ci    using Super = MinimalObject<META_NS::ClassId::Promise, IPromise>;
738bf80f4bSopenharmony_ci
748bf80f4bSopenharmony_cipublic:
758bf80f4bSopenharmony_ci    Promise() = default;
768bf80f4bSopenharmony_ci    META_NO_COPY_MOVE(Promise)
778bf80f4bSopenharmony_ciprivate:
788bf80f4bSopenharmony_ci    META_DEFINE_OBJECT_TYPE_INFO(Promise, META_NS::ClassId::Promise)
798bf80f4bSopenharmony_ci
808bf80f4bSopenharmony_cipublic:
818bf80f4bSopenharmony_ci    static const StaticObjectMetadata& GetStaticObjectMetadata()
828bf80f4bSopenharmony_ci    {
838bf80f4bSopenharmony_ci        return StaticObjectMeta();
848bf80f4bSopenharmony_ci    }
858bf80f4bSopenharmony_ci    static StaticObjectMetadata& StaticObjectMeta()
868bf80f4bSopenharmony_ci    {
878bf80f4bSopenharmony_ci        static StaticObjectMetadata meta { META_NS::ClassId::Promise, nullptr };
888bf80f4bSopenharmony_ci        return meta;
898bf80f4bSopenharmony_ci    }
908bf80f4bSopenharmony_ci
918bf80f4bSopenharmony_cipublic:
928bf80f4bSopenharmony_ci    static BASE_NS::vector<BASE_NS::Uid> GetStaticInterfaces()
938bf80f4bSopenharmony_ci    {
948bf80f4bSopenharmony_ci        return Super::GetInterfacesVector();
958bf80f4bSopenharmony_ci    }
968bf80f4bSopenharmony_ci
978bf80f4bSopenharmony_cipublic:
988bf80f4bSopenharmony_ci    ~Promise() override;
998bf80f4bSopenharmony_ci
1008bf80f4bSopenharmony_ci    void Set(const IAny::Ptr& res) override;
1018bf80f4bSopenharmony_ci    void SetAbandoned() override;
1028bf80f4bSopenharmony_ci    [[nodiscard]] IFuture::Ptr GetFuture() override;
1038bf80f4bSopenharmony_ci    void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token) override;
1048bf80f4bSopenharmony_ci
1058bf80f4bSopenharmony_ciprivate:
1068bf80f4bSopenharmony_ci    BASE_NS::shared_ptr<Future> future_;
1078bf80f4bSopenharmony_ci};
1088bf80f4bSopenharmony_ci
1098bf80f4bSopenharmony_ciclass ContinuationQueueTask : public IntroduceInterfaces<ITaskQueueTask> {
1108bf80f4bSopenharmony_cipublic:
1118bf80f4bSopenharmony_ci    explicit ContinuationQueueTask(IFutureContinuation::Ptr task) : task_(BASE_NS::move(task)) {}
1128bf80f4bSopenharmony_ci
1138bf80f4bSopenharmony_ci    void SetParam(IAny::Ptr arg)
1148bf80f4bSopenharmony_ci    {
1158bf80f4bSopenharmony_ci        arg_ = BASE_NS::move(arg);
1168bf80f4bSopenharmony_ci    }
1178bf80f4bSopenharmony_ci
1188bf80f4bSopenharmony_ci    void SetQueueInfo(const ITaskQueue::Ptr& queue, ITaskQueue::Token token)
1198bf80f4bSopenharmony_ci    {
1208bf80f4bSopenharmony_ci        promise_.SetQueueInfo(queue, token);
1218bf80f4bSopenharmony_ci    }
1228bf80f4bSopenharmony_ci
1238bf80f4bSopenharmony_ci    bool Invoke() override
1248bf80f4bSopenharmony_ci    {
1258bf80f4bSopenharmony_ci        promise_.Set(task_->Invoke(arg_));
1268bf80f4bSopenharmony_ci        return false;
1278bf80f4bSopenharmony_ci    }
1288bf80f4bSopenharmony_ci
1298bf80f4bSopenharmony_ci    [[nodiscard]] IFuture::Ptr GetFuture()
1308bf80f4bSopenharmony_ci    {
1318bf80f4bSopenharmony_ci        return promise_.GetFuture();
1328bf80f4bSopenharmony_ci    }
1338bf80f4bSopenharmony_ci
1348bf80f4bSopenharmony_ci    void SetAbandoned()
1358bf80f4bSopenharmony_ci    {
1368bf80f4bSopenharmony_ci        promise_.SetAbandoned();
1378bf80f4bSopenharmony_ci    }
1388bf80f4bSopenharmony_ci
1398bf80f4bSopenharmony_ciprivate:
1408bf80f4bSopenharmony_ci    IAny::Ptr arg_;
1418bf80f4bSopenharmony_ci    IFutureContinuation::Ptr task_;
1428bf80f4bSopenharmony_ci    Promise promise_;
1438bf80f4bSopenharmony_ci};
1448bf80f4bSopenharmony_ci
1458bf80f4bSopenharmony_ciMETA_END_NAMESPACE()
1468bf80f4bSopenharmony_ci
1478bf80f4bSopenharmony_ci#endif
148