13f4cbf05Sopenharmony_ci/*
23f4cbf05Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License.
53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at
63f4cbf05Sopenharmony_ci *
73f4cbf05Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83f4cbf05Sopenharmony_ci *
93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and
133f4cbf05Sopenharmony_ci * limitations under the License.
143f4cbf05Sopenharmony_ci */
153f4cbf05Sopenharmony_ci
163f4cbf05Sopenharmony_ci /**
173f4cbf05Sopenharmony_ci * @file thread_ex.h
183f4cbf05Sopenharmony_ci *
193f4cbf05Sopenharmony_ci * @brief Provides interfaces of the <b>Thread</b> class
203f4cbf05Sopenharmony_ci * implemented in c_utils.
213f4cbf05Sopenharmony_ci */
223f4cbf05Sopenharmony_ci
233f4cbf05Sopenharmony_ci#ifndef UTILS_THREAD_EX_H
243f4cbf05Sopenharmony_ci#define UTILS_THREAD_EX_H
253f4cbf05Sopenharmony_ci
263f4cbf05Sopenharmony_ci#include <pthread.h>
273f4cbf05Sopenharmony_ci#include <string>
283f4cbf05Sopenharmony_ci#include <mutex>
293f4cbf05Sopenharmony_ci#include <condition_variable>
303f4cbf05Sopenharmony_ci
313f4cbf05Sopenharmony_cinamespace OHOS {
323f4cbf05Sopenharmony_ci
333f4cbf05Sopenharmony_cienum class ThreadStatus {
343f4cbf05Sopenharmony_ci    OK,
353f4cbf05Sopenharmony_ci    WOULD_BLOCK,
363f4cbf05Sopenharmony_ci    INVALID_OPERATION,
373f4cbf05Sopenharmony_ci    UNKNOWN_ERROR,
383f4cbf05Sopenharmony_ci};
393f4cbf05Sopenharmony_ci
403f4cbf05Sopenharmony_cienum ThreadPrio {
413f4cbf05Sopenharmony_ci    THREAD_PROI_NORMAL = 0,
423f4cbf05Sopenharmony_ci    THREAD_PROI_LOW = 10,
433f4cbf05Sopenharmony_ci    THREAD_PROI_LOWEST = 19,
443f4cbf05Sopenharmony_ci};
453f4cbf05Sopenharmony_ci
463f4cbf05Sopenharmony_ciconstexpr int INVALID_PTHREAD_T = -1;
473f4cbf05Sopenharmony_ciconstexpr int MAX_THREAD_NAME_LEN = 15;
483f4cbf05Sopenharmony_ci
493f4cbf05Sopenharmony_ci/**
503f4cbf05Sopenharmony_ci * @brief Provides interfaces for creating a thread
513f4cbf05Sopenharmony_ci * and obtaining a thread ID.
523f4cbf05Sopenharmony_ci */
533f4cbf05Sopenharmony_ciclass Thread {
543f4cbf05Sopenharmony_cipublic:
553f4cbf05Sopenharmony_ci
563f4cbf05Sopenharmony_ci/**
573f4cbf05Sopenharmony_ci * @brief A constructor used to create a <b>Thread</b> object, without
583f4cbf05Sopenharmony_ci * starting the thread.
593f4cbf05Sopenharmony_ci */
603f4cbf05Sopenharmony_ci    Thread();
613f4cbf05Sopenharmony_ci    virtual ~Thread();
623f4cbf05Sopenharmony_ci
633f4cbf05Sopenharmony_ci/**
643f4cbf05Sopenharmony_ci * @brief Creates and starts a child thread, and executes
653f4cbf05Sopenharmony_ci * <b>Run()</b> in a loop.
663f4cbf05Sopenharmony_ci * The loop stops when <b>Run()</b> returns <b>false</b> or it is notified
673f4cbf05Sopenharmony_ci * to exit by `NotifyExitSync()` or `NotifyExitAsync()` from another thread.
683f4cbf05Sopenharmony_ci *
693f4cbf05Sopenharmony_ci * @param name Indicates the name of the thread.
703f4cbf05Sopenharmony_ci * @param priority Indicates the thread priority.
713f4cbf05Sopenharmony_ci * @param stack Indicates the size of the thread stack.
723f4cbf05Sopenharmony_ci * @return Returns <b>OK</b> if the call is successful;
733f4cbf05Sopenharmony_ci * returns <b>INVALID_OPERATION</b> if the thread already exists;
743f4cbf05Sopenharmony_ci * returns <b>UNKNOWN_ERROR</b> if the thread creation fails.
753f4cbf05Sopenharmony_ci * @see {@link NotifyExitSync()} or {@link NotifyExitAsync()}
763f4cbf05Sopenharmony_ci */
773f4cbf05Sopenharmony_ci    ThreadStatus Start(const std::string& name, int32_t priority = THREAD_PROI_NORMAL, size_t stack = 0);
783f4cbf05Sopenharmony_ci
793f4cbf05Sopenharmony_ci/**
803f4cbf05Sopenharmony_ci * @brief Synchronously instructs this <b>Thread</b> object to exit.
813f4cbf05Sopenharmony_ci *
823f4cbf05Sopenharmony_ci * This method can be called only by another thread to instruct this
833f4cbf05Sopenharmony_ci * <b>Thread</b> object to exit. The calling thread will be blocked until this
843f4cbf05Sopenharmony_ci * <b>Thread</b> object exits.
853f4cbf05Sopenharmony_ci */
863f4cbf05Sopenharmony_ci    ThreadStatus NotifyExitSync();
873f4cbf05Sopenharmony_ci
883f4cbf05Sopenharmony_ci/**
893f4cbf05Sopenharmony_ci * @brief Asynchronously instructs this <b>Thread</b> object to exit.
903f4cbf05Sopenharmony_ci *
913f4cbf05Sopenharmony_ci * This method can be called only by another thread to instruct this
923f4cbf05Sopenharmony_ci * <b>Thread</b> object to exit. However, the calling thread will not be blocked
933f4cbf05Sopenharmony_ci * when this <b>Thread</b> object exits.
943f4cbf05Sopenharmony_ci */
953f4cbf05Sopenharmony_ci    virtual void NotifyExitAsync();
963f4cbf05Sopenharmony_ci
973f4cbf05Sopenharmony_ci/**
983f4cbf05Sopenharmony_ci * @brief Checks whether the thread is ready.
993f4cbf05Sopenharmony_ci */
1003f4cbf05Sopenharmony_ci    virtual bool ReadyToWork();
1013f4cbf05Sopenharmony_ci
1023f4cbf05Sopenharmony_ci/**
1033f4cbf05Sopenharmony_ci * @brief Checks whether there is any thread waiting for exit.
1043f4cbf05Sopenharmony_ci *
1053f4cbf05Sopenharmony_ci * If <b>true</b> is returned, the waiting threads who have called
1063f4cbf05Sopenharmony_ci * `NotifyExitSync()` will be woken up when the current thread finishes
1073f4cbf05Sopenharmony_ci * running and exits.
1083f4cbf05Sopenharmony_ci *
1093f4cbf05Sopenharmony_ci * @return Returns <b>true</b> if there is any thread that is
1103f4cbf05Sopenharmony_ci * blocked to wait for the current thread to exit.
1113f4cbf05Sopenharmony_ci * Returns <b>false</b> otherwise.
1123f4cbf05Sopenharmony_ci */
1133f4cbf05Sopenharmony_ci    bool IsExitPending() const;
1143f4cbf05Sopenharmony_ci
1153f4cbf05Sopenharmony_ci/**
1163f4cbf05Sopenharmony_ci * @brief Checks whether the thread is running.
1173f4cbf05Sopenharmony_ci *
1183f4cbf05Sopenharmony_ci * @return Returns <b>true</b> if the thread is running;
1193f4cbf05Sopenharmony_ci * returns <b>false</b> otherwise.
1203f4cbf05Sopenharmony_ci */
1213f4cbf05Sopenharmony_ci    bool IsRunning() const;
1223f4cbf05Sopenharmony_ci
1233f4cbf05Sopenharmony_ci/**
1243f4cbf05Sopenharmony_ci * @brief Obtains the thread ID.
1253f4cbf05Sopenharmony_ci */
1263f4cbf05Sopenharmony_ci    pthread_t GetThread() const { return thread_; }
1273f4cbf05Sopenharmony_ci
1283f4cbf05Sopenharmony_ciprotected:
1293f4cbf05Sopenharmony_ci    virtual bool Run() = 0; // Derived class must implement Run()
1303f4cbf05Sopenharmony_ci
1313f4cbf05Sopenharmony_ciprivate:
1323f4cbf05Sopenharmony_ci    Thread(const Thread&) = delete;
1333f4cbf05Sopenharmony_ci    Thread& operator=(const Thread&) = delete;
1343f4cbf05Sopenharmony_ci    static int ThreadStart(void* args);
1353f4cbf05Sopenharmony_ci
1363f4cbf05Sopenharmony_ciprivate:
1373f4cbf05Sopenharmony_ci    pthread_t thread_;  // Thread ID
1383f4cbf05Sopenharmony_ci    mutable std::mutex lock_;
1393f4cbf05Sopenharmony_ci    std::condition_variable cvThreadExited_;
1403f4cbf05Sopenharmony_ci    ThreadStatus status_;
1413f4cbf05Sopenharmony_ci    volatile bool exitPending_;
1423f4cbf05Sopenharmony_ci    volatile bool running_; // flag of thread running
1433f4cbf05Sopenharmony_ci};
1443f4cbf05Sopenharmony_ci
1453f4cbf05Sopenharmony_ci} // namespace OHOS
1463f4cbf05Sopenharmony_ci
1473f4cbf05Sopenharmony_ci#endif
1483f4cbf05Sopenharmony_ci
149