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