1 /* 2 * Copyright (C) 2023 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 #include "app_process.h" 18 19 #include <pthread.h> 20 21 #include <condition_variable> 22 #include <mutex> 23 24 #include "berberis/base/forever_alloc.h" 25 26 namespace berberis { 27 28 namespace { 29 30 class AppProcess { 31 public: GetInstance()32 static AppProcess* GetInstance() { 33 static auto* g_app_process = NewForever<AppProcess>(); 34 return g_app_process; 35 } 36 PostInit()37 void PostInit() { 38 { 39 std::lock_guard<std::mutex> guard(mutex_); 40 initialized_ = true; 41 } 42 cv_.notify_all(); 43 44 // Expect this call to occur on the main guest thread, after app 45 // initialization is done. Force exit since keeping the thread in the 46 // background might confuse an app that expects to be single-threaded. 47 // Specifically, this scenario happens when guest code is executed in 48 // app-zygote before forking children (b/146904103). 49 // 50 // Other threads may use main thread's stack to access argc/argv/auxvals. 51 // We ensure that stack is retained after pthread_exit() by disallowing 52 // stack unmap in main guest thread when starting an executable. 53 // 54 // Note that we cannot just let the thread exit from main(), which would 55 // exit the whole process, not just this thread. 56 pthread_exit(nullptr); 57 } 58 WaitForPostInit()59 void WaitForPostInit() { 60 std::unique_lock<std::mutex> lock(mutex_); 61 cv_.wait(lock, [this] { return initialized_; }); 62 } 63 64 private: 65 AppProcess() = default; 66 AppProcess(const AppProcess&) = delete; 67 AppProcess& operator=(const AppProcess&) = delete; 68 69 friend AppProcess* NewForever<AppProcess>(); 70 71 std::mutex mutex_; 72 std::condition_variable cv_; 73 bool initialized_ = false; 74 }; 75 76 } // namespace 77 AppProcessPostInit()78void AppProcessPostInit() { 79 AppProcess::GetInstance()->PostInit(); 80 } 81 WaitForAppProcess()82void WaitForAppProcess() { 83 AppProcess::GetInstance()->WaitForPostInit(); 84 } 85 86 } // namespace berberis 87