/* * Tencent is pleased to support the open source community by making * Hippy available. * * Copyright (C) 2017-2019 THL A29 Limited, a Tencent company. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include "devtools_base/common/macros.h" #include "devtools_base/common/task.h" #include "devtools_base/common/time_delta.h" #include "devtools_base/common/time_point.h" #include "devtools_base/common/worker.h" namespace hippy::devtools { inline namespace runner { class TaskRunner { public: using TimePoint = time::TimePoint; using TimeDelta = time::TimeDelta; explicit TaskRunner(bool is_excl = false, int priority = 1, const std::string& name = ""); ~TaskRunner(); void Clear(); void Terminate(); void AddSubTaskRunner(std::shared_ptr sub_runner, bool is_task_running = false); void RemoveSubTaskRunner(std::shared_ptr sub_runner); void PostTask(std::unique_ptr task); template void PostTask(F&& f, Args... args) { using T = typename std::result_of::type; auto packaged_task = std::make_shared>(std::bind(std::forward(f), std::forward(args)...)); auto task = std::make_unique([packaged_task]() { (*packaged_task)(); }); PostTask(std::move(task)); } void PostDelayedTask(std::unique_ptr task, TimeDelta delay); template void PostDelayedTask(F&& f, TimeDelta delay, Args... args) { using T = typename std::result_of::type; auto packaged_task = std::make_shared>(std::bind(std::forward(f), std::forward(args)...)); auto task = std::make_unique([packaged_task]() { (*packaged_task)(); }); PostDelayedTask(std::move(task), delay); } TimeDelta GetNextTimeDelta(TimePoint now); int32_t RunnerKeyCreate(std::function destruct); bool RunnerKeyDelete(int32_t key); bool RunnerSetSpecific(int32_t key, void* p); void* RunnerGetSpecific(int32_t key); void RunnerDestroySpecifics(); inline bool GetExclusive() { return is_excl_; } inline int32_t GetPriority() { return priority_; } inline int32_t GetId() { return id_; } inline std::string GetName() { return name_; } inline TimeDelta GetTime() { return time_; } inline TimeDelta AddTime(TimeDelta time) { time_ = time_ + time; return time_; } inline void SetTime(TimeDelta time) { time_ = time; } // 必须要在 task 运行时调用 GetCurrentTaskRunner 才能得到正确的 Runner,task 运行之外调用都将返回 nullptr static std::shared_ptr GetCurrentTaskRunner(); private: friend class Worker; friend class Scheduler; friend class WorkerPool; std::unique_ptr popTaskFromDelayedQueueNoLock(TimePoint now); std::unique_ptr PopTask(); std::unique_ptr GetTopDelayTask(); std::unique_ptr GetNext(); void SetCv(std::shared_ptr cv); std::queue> task_queue_; using DelayedEntry = std::pair>; struct DelayedEntryCompare { bool operator()(const DelayedEntry& left, const DelayedEntry& right) const { return left.first > right.first; } }; std::priority_queue, DelayedEntryCompare> delayed_task_queue_; std::mutex mutex_; std::shared_ptr cv_; std::weak_ptr worker_; bool is_terminated_; bool is_excl_; std::string name_; bool has_sub_runner_; int32_t priority_; int32_t id_; TimeDelta time_; TDF_BASE_DISALLOW_COPY_AND_ASSIGN(TaskRunner); }; } // namespace runner } // namespace hippy::devtools