1 /* 2 * Copyright (C) 2018 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 #define LOG_TAG "IPCThreadStateBase" 18 19 #include <binderthreadstate/IPCThreadStateBase.h> 20 #include <android-base/macros.h> 21 22 #include <utils/Log.h> 23 24 #include <errno.h> 25 #include <inttypes.h> 26 #include <pthread.h> 27 28 namespace android { 29 30 static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; 31 static bool gHaveTLS = false; 32 static pthread_key_t gTLS = 0; 33 IPCThreadStateBase()34IPCThreadStateBase::IPCThreadStateBase() { 35 pthread_setspecific(gTLS, this); 36 } 37 self()38IPCThreadStateBase* IPCThreadStateBase::self() 39 { 40 if (gHaveTLS) { 41 restart: 42 const pthread_key_t k = gTLS; 43 IPCThreadStateBase* st = (IPCThreadStateBase*)pthread_getspecific(k); 44 if (st) return st; 45 return new IPCThreadStateBase; 46 } 47 48 pthread_mutex_lock(&gTLSMutex); 49 if (!gHaveTLS) { 50 int key_create_value = pthread_key_create(&gTLS, threadDestructor); 51 if (key_create_value != 0) { 52 pthread_mutex_unlock(&gTLSMutex); 53 ALOGW("IPCThreadStateBase::self() unable to create TLS key, expect a crash: %s\n", 54 strerror(key_create_value)); 55 return nullptr; 56 } 57 gHaveTLS = true; 58 } 59 pthread_mutex_unlock(&gTLSMutex); 60 goto restart; 61 } 62 pushCurrentState(CallState callState)63void IPCThreadStateBase::pushCurrentState(CallState callState) { 64 mCallStateStack.emplace(callState); 65 } 66 popCurrentState()67IPCThreadStateBase::CallState IPCThreadStateBase::popCurrentState() { 68 ALOG_ASSERT(mCallStateStack.size > 0); 69 CallState val = mCallStateStack.top(); 70 mCallStateStack.pop(); 71 return val; 72 } 73 getCurrentBinderCallState()74IPCThreadStateBase::CallState IPCThreadStateBase::getCurrentBinderCallState() { 75 if (mCallStateStack.size() > 0) { 76 return mCallStateStack.top(); 77 } 78 return CallState::NONE; 79 } 80 threadDestructor(void * st)81void IPCThreadStateBase::threadDestructor(void *st) 82 { 83 IPCThreadStateBase* const self = static_cast<IPCThreadStateBase*>(st); 84 if (self) { 85 delete self; 86 } 87 } 88 89 }; // namespace android 90