1/*
2 * Copyright (c) 2021-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 /**
17 * @file thread_ex.h
18 *
19 * @brief Provides interfaces of the <b>Thread</b> class
20 * implemented in c_utils.
21 */
22
23#ifndef UTILS_THREAD_EX_H
24#define UTILS_THREAD_EX_H
25
26#include <pthread.h>
27#include <string>
28#include <mutex>
29#include <condition_variable>
30
31namespace OHOS {
32
33enum class ThreadStatus {
34    OK,
35    WOULD_BLOCK,
36    INVALID_OPERATION,
37    UNKNOWN_ERROR,
38};
39
40enum ThreadPrio {
41    THREAD_PROI_NORMAL = 0,
42    THREAD_PROI_LOW = 10,
43    THREAD_PROI_LOWEST = 19,
44};
45
46constexpr int INVALID_PTHREAD_T = -1;
47constexpr int MAX_THREAD_NAME_LEN = 15;
48
49/**
50 * @brief Provides interfaces for creating a thread
51 * and obtaining a thread ID.
52 */
53class Thread {
54public:
55
56/**
57 * @brief A constructor used to create a <b>Thread</b> object, without
58 * starting the thread.
59 */
60    Thread();
61    virtual ~Thread();
62
63/**
64 * @brief Creates and starts a child thread, and executes
65 * <b>Run()</b> in a loop.
66 * The loop stops when <b>Run()</b> returns <b>false</b> or it is notified
67 * to exit by `NotifyExitSync()` or `NotifyExitAsync()` from another thread.
68 *
69 * @param name Indicates the name of the thread.
70 * @param priority Indicates the thread priority.
71 * @param stack Indicates the size of the thread stack.
72 * @return Returns <b>OK</b> if the call is successful;
73 * returns <b>INVALID_OPERATION</b> if the thread already exists;
74 * returns <b>UNKNOWN_ERROR</b> if the thread creation fails.
75 * @see {@link NotifyExitSync()} or {@link NotifyExitAsync()}
76 */
77    ThreadStatus Start(const std::string& name, int32_t priority = THREAD_PROI_NORMAL, size_t stack = 0);
78
79/**
80 * @brief Synchronously instructs this <b>Thread</b> object to exit.
81 *
82 * This method can be called only by another thread to instruct this
83 * <b>Thread</b> object to exit. The calling thread will be blocked until this
84 * <b>Thread</b> object exits.
85 */
86    ThreadStatus NotifyExitSync();
87
88/**
89 * @brief Asynchronously instructs this <b>Thread</b> object to exit.
90 *
91 * This method can be called only by another thread to instruct this
92 * <b>Thread</b> object to exit. However, the calling thread will not be blocked
93 * when this <b>Thread</b> object exits.
94 */
95    virtual void NotifyExitAsync();
96
97/**
98 * @brief Checks whether the thread is ready.
99 */
100    virtual bool ReadyToWork();
101
102/**
103 * @brief Checks whether there is any thread waiting for exit.
104 *
105 * If <b>true</b> is returned, the waiting threads who have called
106 * `NotifyExitSync()` will be woken up when the current thread finishes
107 * running and exits.
108 *
109 * @return Returns <b>true</b> if there is any thread that is
110 * blocked to wait for the current thread to exit.
111 * Returns <b>false</b> otherwise.
112 */
113    bool IsExitPending() const;
114
115/**
116 * @brief Checks whether the thread is running.
117 *
118 * @return Returns <b>true</b> if the thread is running;
119 * returns <b>false</b> otherwise.
120 */
121    bool IsRunning() const;
122
123/**
124 * @brief Obtains the thread ID.
125 */
126    pthread_t GetThread() const { return thread_; }
127
128protected:
129    virtual bool Run() = 0; // Derived class must implement Run()
130
131private:
132    Thread(const Thread&) = delete;
133    Thread& operator=(const Thread&) = delete;
134    static int ThreadStart(void* args);
135
136private:
137    pthread_t thread_;  // Thread ID
138    mutable std::mutex lock_;
139    std::condition_variable cvThreadExited_;
140    ThreadStatus status_;
141    volatile bool exitPending_;
142    volatile bool running_; // flag of thread running
143};
144
145} // namespace OHOS
146
147#endif
148
149