1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef HWUI_THREADBASE_H 18 #define HWUI_THREADBASE_H 19 20 #include <utils/Thread.h> 21 22 #include <algorithm> 23 24 #include "thread/WorkQueue.h" 25 #include "utils/Macros.h" 26 27 namespace android::uirenderer { 28 29 class ThreadBase : public Thread { 30 PREVENT_COPY_AND_ASSIGN(ThreadBase); 31 32 public: ThreadBase()33 ThreadBase() : Thread(false), mQueue([this]() { mCondition.notify_all(); }, mLock) {} 34 queue()35 WorkQueue& queue() { return mQueue; } 36 requestExit()37 void requestExit() { Thread::requestExit(); } 38 39 void start(const char* name = "ThreadBase") { Thread::run(name); } 40 join()41 void join() { Thread::join(); } 42 isRunning()43 bool isRunning() const { return Thread::isRunning(); } 44 45 protected: waitForWork()46 void waitForWork() { 47 std::unique_lock lock{mLock}; 48 nsecs_t nextWakeup = mQueue.nextWakeup(lock); 49 std::chrono::nanoseconds duration = std::chrono::nanoseconds::max(); 50 if (nextWakeup < std::numeric_limits<nsecs_t>::max()) { 51 nsecs_t timeout = nextWakeup - WorkQueue::clock::now(); 52 if (timeout < 0) timeout = 0; 53 duration = std::chrono::nanoseconds(timeout); 54 } 55 mCondition.wait_for(lock, duration); 56 } 57 processQueue()58 void processQueue() { mQueue.process(); } 59 threadLoop()60 virtual bool threadLoop() override { 61 while (!exitPending()) { 62 waitForWork(); 63 processQueue(); 64 } 65 return false; 66 } 67 68 private: 69 WorkQueue mQueue; 70 std::mutex mLock; 71 std::condition_variable mCondition; 72 }; 73 74 } // namespace android::uirenderer 75 76 #endif // HWUI_THREADBASE_H 77