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#include "threading/task_queue.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <atomic>
198bf80f4bSopenharmony_ci
208bf80f4bSopenharmony_ci#include <base/containers/refcnt_ptr.h>
218bf80f4bSopenharmony_ci#include <base/containers/type_traits.h>
228bf80f4bSopenharmony_ci#include <base/containers/unique_ptr.h>
238bf80f4bSopenharmony_ci#include <core/log.h>
248bf80f4bSopenharmony_ci#include <core/namespace.h>
258bf80f4bSopenharmony_ci#include <core/threading/intf_thread_pool.h>
268bf80f4bSopenharmony_ci
278bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE()
288bf80f4bSopenharmony_ciusing BASE_NS::move;
298bf80f4bSopenharmony_ciusing BASE_NS::unique_ptr;
308bf80f4bSopenharmony_ci
318bf80f4bSopenharmony_ci// -- TaskQueue ExecuteAsyncTask, runs TaskQueue::Execute.
328bf80f4bSopenharmony_ciTaskQueue::ExecuteAsyncTask::ExecuteAsyncTask(TaskQueue& queue) : queue_(queue) {}
338bf80f4bSopenharmony_ci
348bf80f4bSopenharmony_civoid TaskQueue::ExecuteAsyncTask::operator()()
358bf80f4bSopenharmony_ci{
368bf80f4bSopenharmony_ci    queue_.Execute();
378bf80f4bSopenharmony_ci    queue_.isRunningAsync_ = false;
388bf80f4bSopenharmony_ci}
398bf80f4bSopenharmony_ci
408bf80f4bSopenharmony_civoid TaskQueue::ExecuteAsyncTask::Destroy()
418bf80f4bSopenharmony_ci{
428bf80f4bSopenharmony_ci    delete this;
438bf80f4bSopenharmony_ci}
448bf80f4bSopenharmony_ci
458bf80f4bSopenharmony_ci// -- TaskQueue
468bf80f4bSopenharmony_ciTaskQueue::TaskQueue(const IThreadPool::Ptr& threadPool) : threadPool_(threadPool), isRunningAsync_(false) {}
478bf80f4bSopenharmony_ci
488bf80f4bSopenharmony_ciTaskQueue::~TaskQueue() = default;
498bf80f4bSopenharmony_ci
508bf80f4bSopenharmony_civoid TaskQueue::ExecuteAsync()
518bf80f4bSopenharmony_ci{
528bf80f4bSopenharmony_ci    CORE_ASSERT(threadPool_ != nullptr);
538bf80f4bSopenharmony_ci
548bf80f4bSopenharmony_ci    if (!IsRunningAsync()) {
558bf80f4bSopenharmony_ci        isRunningAsync_ = true;
568bf80f4bSopenharmony_ci
578bf80f4bSopenharmony_ci        // Execute in new thread.
588bf80f4bSopenharmony_ci        asyncOperation_ = threadPool_->Push(IThreadPool::ITask::Ptr { new ExecuteAsyncTask(*this) });
598bf80f4bSopenharmony_ci    }
608bf80f4bSopenharmony_ci}
618bf80f4bSopenharmony_ci
628bf80f4bSopenharmony_cibool TaskQueue::IsRunningAsync() const
638bf80f4bSopenharmony_ci{
648bf80f4bSopenharmony_ci    return isRunningAsync_;
658bf80f4bSopenharmony_ci}
668bf80f4bSopenharmony_ci
678bf80f4bSopenharmony_civoid TaskQueue::Wait()
688bf80f4bSopenharmony_ci{
698bf80f4bSopenharmony_ci    if (IsRunningAsync()) {
708bf80f4bSopenharmony_ci        asyncOperation_->Wait();
718bf80f4bSopenharmony_ci        isRunningAsync_ = false;
728bf80f4bSopenharmony_ci    }
738bf80f4bSopenharmony_ci}
748bf80f4bSopenharmony_ci
758bf80f4bSopenharmony_ci// -- TaskQueue entry.
768bf80f4bSopenharmony_ciTaskQueue::Entry::Entry(uint64_t identifier, IThreadPool::ITask::Ptr task) : task(move(task)), identifier(identifier) {}
778bf80f4bSopenharmony_ci
788bf80f4bSopenharmony_cibool TaskQueue::Entry::operator==(uint64_t rhsIdentifier) const
798bf80f4bSopenharmony_ci{
808bf80f4bSopenharmony_ci    return identifier == rhsIdentifier;
818bf80f4bSopenharmony_ci}
828bf80f4bSopenharmony_ci
838bf80f4bSopenharmony_cibool TaskQueue::Entry::operator==(const TaskQueue::Entry& other) const
848bf80f4bSopenharmony_ci{
858bf80f4bSopenharmony_ci    return identifier == other.identifier;
868bf80f4bSopenharmony_ci}
878bf80f4bSopenharmony_ciCORE_END_NAMESPACE()
88