1 // Copyright (C) 2014 The Android Open Source Project 2 // 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 #pragma once 16 17 #include "aemu/base/Compiler.h" 18 #include "aemu/base/threads/Types.h" 19 #include "aemu/base/synchronization/Lock.h" 20 21 #ifdef _WIN32 22 #include <windows.h> 23 #else 24 #include <pthread.h> 25 #endif 26 27 #include <inttypes.h> 28 #include <optional> 29 #include <string> 30 31 namespace android { 32 namespace base { 33 34 // Wrapper class for platform-specific threads. 35 // To create your own thread, define a sub-class of emugl::Thread 36 // and override its main() method. 37 // 38 // For example: 39 // 40 // class MyThread : public emugl::Thread { 41 // public: 42 // MyThread() : Thread() {} 43 // 44 // virtual intptr_t main() { 45 // ... main thread loop implementation 46 // return 0; 47 // } 48 // }; 49 // 50 // ... 51 // 52 // // Create new instance, but does not start it. 53 // MyThread* thread = new MyThread(); 54 // 55 // // Start the thread. 56 // thread->start(); 57 // 58 // // Wait for thread completion, and gets result into |exitStatus|. 59 // int exitStatus; 60 // thread->wait(&exitStatus); 61 // 62 class Thread { 63 DISALLOW_COPY_ASSIGN_AND_MOVE(Thread); 64 65 public: 66 // Public constructor. 67 Thread(ThreadFlags flags = ThreadFlags::MaskSignals, int stackSize = 0, 68 std::optional<std::string> name = std::nullopt); 69 70 // Virtual destructor. 71 virtual ~Thread(); 72 73 // Override this method in your own thread sub-classes. This will 74 // be called when start() is invoked on the Thread instance. 75 virtual intptr_t main() = 0; 76 77 // Override this if you need to execute some code after thread has 78 // exited main() and is guaranteed not to access any of its members. 79 // E.g. if you need to delete a thread object from the same thread 80 // it has created onExit()81 virtual void onExit() {} 82 83 // Start a thread instance. Return true on success, false otherwise 84 // (e.g. if the thread was already started or terminated). 85 bool start(); 86 87 // Wait for thread termination and retrieve exist status into 88 // |*exitStatus|. Return true on success, false otherwise. 89 // NOTE: |exitStatus| can be NULL. 90 virtual bool wait(intptr_t *exitStatus = nullptr); 91 92 // Check whether a thread has terminated. On success, return true 93 // and sets |*exitStatus|. On failure, return false. 94 // NOTE: |exitStatus| can be NULL. 95 bool tryWait(intptr_t *exitStatus); 96 97 // Mask all signals for the current thread 98 // This is needed for the qemu guest to run properly 99 // NB: noop for Win32 100 static void maskAllSignals(); 101 102 // Sleep for |n| milliseconds 103 static void sleepMs(unsigned n); 104 105 // Sleep for |n| microseconds 106 static void sleepUs(unsigned n); 107 108 // Yield the remaining part of current thread's CPU time slice to another 109 // thread that's ready to run. 110 static void yield(); 111 112 protected: 113 std::optional<std::string> mNameOpt = std::nullopt; 114 115 private: 116 #ifdef _WIN32 117 static DWORD WINAPI thread_main(void* arg); 118 119 HANDLE mThread = nullptr; 120 #else // !WIN32 121 static void* thread_main(void* arg); 122 123 pthread_t mThread; 124 #endif 125 Lock mLock; 126 // Access guarded by |mLock|. 127 intptr_t mExitStatus = 0; 128 int mStackSize; 129 const ThreadFlags mFlags; 130 bool mStarted = false; 131 // Access guarded by |mLock|. 132 bool mFinished = false; 133 #ifndef _WIN32 134 // Posix-only, remember if we've joined our non-detached thread already. 135 bool mJoined = false; 136 #endif 137 }; 138 139 // Helper function to obtain a printable id for the current thread. 140 unsigned long getCurrentThreadId(); 141 142 // Helper function to set/get/ui thread status. 143 void setUiThreadId(unsigned long id); 144 bool isRunningInUiThread(); 145 146 // Subclass of Thread covering interruptible threads. 147 class InterruptibleThread : public Thread { 148 DISALLOW_COPY_ASSIGN_AND_MOVE(InterruptibleThread); 149 public: 150 // Public constructor. 151 InterruptibleThread(ThreadFlags flags = ThreadFlags::MaskSignals, int stackSize = 0) : Thread(flags,stackSize)152 Thread(flags, stackSize) { } 153 154 virtual void interrupt() = 0; 155 }; 156 157 } // namespace base 158 } // namespace android 159