146debc2cSopenharmony_ci/*
246debc2cSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
346debc2cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
446debc2cSopenharmony_ci * you may not use this file except in compliance with the License.
546debc2cSopenharmony_ci * You may obtain a copy of the License at
646debc2cSopenharmony_ci *
746debc2cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
846debc2cSopenharmony_ci *
946debc2cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1046debc2cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1146debc2cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1246debc2cSopenharmony_ci * See the License for the specific language governing permissions and
1346debc2cSopenharmony_ci * limitations under the License.
1446debc2cSopenharmony_ci */
1546debc2cSopenharmony_ci
1646debc2cSopenharmony_ci#include "operation_queue.h"
1746debc2cSopenharmony_ci#include "print_log.h"
1846debc2cSopenharmony_ci
1946debc2cSopenharmony_cinamespace {
2046debc2cSopenharmony_ciconst int CHECK_OP_INTERVAL_MS = 1000;
2146debc2cSopenharmony_ci}
2246debc2cSopenharmony_ciusing namespace OHOS::Print;
2346debc2cSopenharmony_ci
2446debc2cSopenharmony_civoid OperationQueue::Run()
2546debc2cSopenharmony_ci{
2646debc2cSopenharmony_ci    bool expectRunning = false;
2746debc2cSopenharmony_ci    if (!isRunning.compare_exchange_strong(expectRunning, true)) {
2846debc2cSopenharmony_ci        PRINT_HILOGW("Operation queue is running");
2946debc2cSopenharmony_ci        return;
3046debc2cSopenharmony_ci    }
3146debc2cSopenharmony_ci    opThread = std::thread([this]() {
3246debc2cSopenharmony_ci        while (isRunning) {
3346debc2cSopenharmony_ci            std::function<void()> op = Pop();
3446debc2cSopenharmony_ci            if (op != nullptr) {
3546debc2cSopenharmony_ci                op();
3646debc2cSopenharmony_ci            } else {
3746debc2cSopenharmony_ci                syncWait.Wait(CHECK_OP_INTERVAL_MS);
3846debc2cSopenharmony_ci            }
3946debc2cSopenharmony_ci        }
4046debc2cSopenharmony_ci    });
4146debc2cSopenharmony_ci}
4246debc2cSopenharmony_civoid OperationQueue::Stop()
4346debc2cSopenharmony_ci{
4446debc2cSopenharmony_ci    bool expectRunning = true;
4546debc2cSopenharmony_ci    if (!isRunning.compare_exchange_strong(expectRunning, false)) {
4646debc2cSopenharmony_ci        PRINT_HILOGW("Operation queue is not running");
4746debc2cSopenharmony_ci        return;
4846debc2cSopenharmony_ci    }
4946debc2cSopenharmony_ci    syncWait.Notify();
5046debc2cSopenharmony_ci    if (opThread.joinable()) {
5146debc2cSopenharmony_ci        opThread.join();
5246debc2cSopenharmony_ci    }
5346debc2cSopenharmony_ci    {
5446debc2cSopenharmony_ci        std::lock_guard<std::mutex> lock(listMutex);
5546debc2cSopenharmony_ci        opList.clear();
5646debc2cSopenharmony_ci    }
5746debc2cSopenharmony_ci}
5846debc2cSopenharmony_ci
5946debc2cSopenharmony_cibool OperationQueue::Push(std::function<void()> op)
6046debc2cSopenharmony_ci{
6146debc2cSopenharmony_ci    if (!isRunning.load()) {
6246debc2cSopenharmony_ci        PRINT_HILOGW("Operation queue is not running");
6346debc2cSopenharmony_ci        return false;
6446debc2cSopenharmony_ci    }
6546debc2cSopenharmony_ci    {
6646debc2cSopenharmony_ci        std::lock_guard<std::mutex> lock(listMutex);
6746debc2cSopenharmony_ci        if (opList.size() >= maxCount) {
6846debc2cSopenharmony_ci            PRINT_HILOGW("Operation queue full");
6946debc2cSopenharmony_ci            opList.pop_back();
7046debc2cSopenharmony_ci        }
7146debc2cSopenharmony_ci        opList.push_front(op);
7246debc2cSopenharmony_ci    }
7346debc2cSopenharmony_ci    syncWait.Notify();
7446debc2cSopenharmony_ci    return true;
7546debc2cSopenharmony_ci}
7646debc2cSopenharmony_ci
7746debc2cSopenharmony_cistd::function<void()> OperationQueue::Pop()
7846debc2cSopenharmony_ci{
7946debc2cSopenharmony_ci    std::lock_guard<std::mutex> lock(listMutex);
8046debc2cSopenharmony_ci    if (opList.empty()) {
8146debc2cSopenharmony_ci        return nullptr;
8246debc2cSopenharmony_ci    }
8346debc2cSopenharmony_ci    std::function<void()> op = opList.back();
8446debc2cSopenharmony_ci    opList.pop_back();
8546debc2cSopenharmony_ci    return op;
8646debc2cSopenharmony_ci}
87