1/*
2 * Copyright (c) 2022 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 DELEGATE_TASKS_H
17#define DELEGATE_TASKS_H
18
19#include <cinttypes>
20#include <functional>
21#include <future>
22#include <memory>
23#include <mutex>
24#include <queue>
25
26#include "id_factory.h"
27#include "util.h"
28
29namespace OHOS {
30namespace MMI {
31using DTaskCallback = std::function<int32_t()>;
32class DelegateTasks final : public IdFactory<int32_t> {
33public:
34    struct TaskData {
35        uint64_t tid { 0 };
36        int32_t taskId { 0 };
37    };
38    class Task : public std::enable_shared_from_this<Task> {
39    public:
40        using Promise = std::promise<int32_t>;
41        using Future = std::future<int32_t>;
42        using TaskPtr = std::shared_ptr<DelegateTasks::Task>;
43        Task(int32_t id, DTaskCallback fun, Promise *promise = nullptr)
44            : id_(id), fun_(fun), promise_(promise) {}
45        ~Task() = default;
46        void ProcessTask();
47
48        int32_t GetId() const
49        {
50            return id_;
51        }
52        TaskPtr GetSharedPtr()
53        {
54            return shared_from_this();
55        }
56        void SetWaited()
57        {
58            hasWaited_ = true;
59        }
60
61    private:
62        std::atomic_bool hasWaited_ { false };
63        int32_t id_ { 0 };
64        DTaskCallback fun_;
65        Promise* promise_ { nullptr };
66    };
67    using TaskPtr = Task::TaskPtr;
68    using Promise = Task::Promise;
69    using Future = Task::Future;
70
71public:
72    DelegateTasks() = default;
73    ~DelegateTasks();
74
75    bool Init();
76    void ProcessTasks();
77    int32_t PostSyncTask(DTaskCallback callback);
78    int32_t PostAsyncTask(DTaskCallback callback);
79
80    int32_t GetReadFd() const
81    {
82        return fds_[0];
83    }
84    void SetWorkerThreadId(uint64_t tid)
85    {
86        workerThreadId_ = tid;
87    }
88    bool IsCallFromWorkerThread() const
89    {
90        return (GetThisThreadId() == workerThreadId_);
91    }
92
93private:
94    void PopPendingTaskList(std::vector<TaskPtr> &tasks);
95    TaskPtr PostTask(DTaskCallback callback, Promise *promise = nullptr);
96
97private:
98    uint64_t workerThreadId_ { 0 };
99    int32_t fds_[2] = {};
100    std::mutex mux_;
101    std::queue<TaskPtr> tasks_;
102};
103} // namespace MMI
104} // namespace OHOS
105#endif // DELEGATE_TASKS_H