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 
31 namespace OHOS {
32 
33 enum class ThreadStatus {
34     OK,
35     WOULD_BLOCK,
36     INVALID_OPERATION,
37     UNKNOWN_ERROR,
38 };
39 
40 enum ThreadPrio {
41     THREAD_PROI_NORMAL = 0,
42     THREAD_PROI_LOW = 10,
43     THREAD_PROI_LOWEST = 19,
44 };
45 
46 constexpr int INVALID_PTHREAD_T = -1;
47 constexpr int MAX_THREAD_NAME_LEN = 15;
48 
49 /**
50  * @brief Provides interfaces for creating a thread
51  * and obtaining a thread ID.
52  */
53 class Thread {
54 public:
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  */
GetThread()126     pthread_t GetThread() const { return thread_; }
127 
128 protected:
129     virtual bool Run() = 0; // Derived class must implement Run()
130 
131 private:
132     Thread(const Thread&) = delete;
133     Thread& operator=(const Thread&) = delete;
134     static int ThreadStart(void* args);
135 
136 private:
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