1/*
2 * Copyright (c) 2023 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 OHOS_ROSEN_WINDOW_SCENE_TASK_SCHEDULER_H
17#define OHOS_ROSEN_WINDOW_SCENE_TASK_SCHEDULER_H
18
19#include <event_handler.h>
20
21#include <unistd.h>
22
23namespace OHOS::Rosen {
24
25void StartTraceForSyncTask(std::string name);
26void FinishTraceForSyncTask();
27
28class TaskScheduler : public std::enable_shared_from_this<TaskScheduler> {
29public:
30    explicit TaskScheduler(const std::string& threadName);
31    ~TaskScheduler() = default;
32
33    std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler();
34    using Task = std::function<void()>;
35    void PostAsyncTask(Task&& task, const std::string& name = "ssmTask", int64_t delayTime = 0);
36    void PostVoidSyncTask(Task&& task, const std::string& name = "ssmTask");
37    void PostTask(Task&& task, const std::string& name, int64_t delayTime = 0);
38    void RemoveTask(const std::string& name);
39    template<typename SyncTask, typename Return = std::invoke_result_t<SyncTask>>
40    Return PostSyncTask(SyncTask&& task, const std::string& name = "ssmTask")
41    {
42        Return ret;
43        if (handler_->GetEventRunner()->IsCurrentRunnerThread()) {
44            StartTraceForSyncTask(name);
45            ret = task();
46            FinishTraceForSyncTask();
47            return ret;
48        }
49        auto syncTask = [weak = weak_from_this(), &ret, &task, name]() {
50            StartTraceForSyncTask(name);
51            ret = task();
52            FinishTraceForSyncTask();
53            if (auto self = weak.lock()) {
54                self->ExecuteExportTask();
55            }
56        };
57        AppExecFwk::EventQueue::Priority priority = AppExecFwk::EventQueue::Priority::IMMEDIATE;
58        static pid_t pid = getpid();
59        if (pid == gettid()) {
60            priority = AppExecFwk::EventQueue::Priority::VIP;
61        }
62        handler_->PostSyncTask(std::move(syncTask), "wms:" + name, priority);
63        return ret;
64    }
65
66    void SetExportHandler(const std::shared_ptr<AppExecFwk::EventHandler>& handler);
67    /*
68     * add export task, will be executed after a task OS_SceneSession,
69     * same name means same task, will be only executed once
70     */
71    void AddExportTask(std::string taskName, Task task);
72
73private:
74    void ExecuteExportTask();
75    std::unordered_map<std::string, Task> exportFuncMap_; // will used in OS_SceneSession
76    std::shared_ptr<AppExecFwk::EventHandler> handler_;
77    std::weak_ptr<AppExecFwk::EventHandler> exportHandler_;
78    pid_t ssmTid_ = 0;
79};
80} // namespace OHOS::Rosen
81#endif // OHOS_ROSEN_WINDOW_SCENE_TASK_SCHEDULER_H
82