Loading libs/binder/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ cc_library_shared { "liblog", "libcutils", "libutils", "libbinderthreadstate", ], header_libs: [ Loading libs/binder/IPCThreadState.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "IPCThreadState" #include <binder/IPCThreadState.h> #include <binderthreadstate/IPCThreadStateBase.h> #include <binder/Binder.h> #include <binder/BpBinder.h> Loading Loading @@ -742,6 +743,7 @@ IPCThreadState::IPCThreadState() clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256); mIPCThreadStateBase = IPCThreadStateBase::self(); } IPCThreadState::~IPCThreadState() Loading Loading @@ -1082,6 +1084,9 @@ status_t IPCThreadState::executeCommand(int32_t cmd) "Not enough command data for brTRANSACTION"); if (result != NO_ERROR) break; //Record the fact that we're in a binder call. mIPCThreadStateBase->pushCurrentState( IPCThreadStateBase::CallState::BINDER); Parcel buffer; buffer.ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), Loading Loading @@ -1129,6 +1134,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); } mIPCThreadStateBase->popCurrentState(); //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n", // mCallingPid, origPid, origUid); Loading Loading @@ -1192,6 +1198,10 @@ status_t IPCThreadState::executeCommand(int32_t cmd) return result; } bool IPCThreadState::isServingCall() const { return mIPCThreadStateBase->getCurrentBinderCallState() == IPCThreadStateBase::CallState::BINDER; } void IPCThreadState::threadDestructor(void *st) { IPCThreadState* const self = static_cast<IPCThreadState*>(st); Loading libs/binder/include/binder/IPCThreadState.h +30 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ typedef int uid_t; // --------------------------------------------------------------------------- namespace android { class IPCThreadStateBase; class IPCThreadState { public: Loading Loading @@ -89,6 +91,33 @@ public: // the maximum number of binder threads threads allowed for this process. void blockUntilThreadAvailable(); // Is this thread currently serving a binder call. This method // returns true if while traversing backwards from the function call // stack for this thread, we encounter a function serving a binder // call before encountering a hwbinder call / hitting the end of the // call stack. // Eg: If thread T1 went through the following call pattern // 1) T1 receives and executes hwbinder call H1. // 2) While handling H1, T1 makes binder call B1. // 3) The handler of B1, calls into T1 with a callback B2. // If isServingCall() is called during H1 before 3), this method // will return false, else true. // // ---- // | B2 | ---> While callback B2 is being handled, during 3). // ---- // | H1 | ---> While H1 is being handled. // ---- // Fig: Thread Call stack while handling B2 // // This is since after 3), while traversing the thread call stack, // we hit a binder call before a hwbinder call / end of stack. This // method may be typically used to determine whether to use // hardware::IPCThreadState methods or IPCThreadState methods to // infer information about thread state. bool isServingCall() const; private: IPCThreadState(); ~IPCThreadState(); Loading Loading @@ -128,6 +157,7 @@ private: uid_t mCallingUid; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; IPCThreadStateBase *mIPCThreadStateBase; }; }; // namespace android Loading libs/binderthreadstate/Android.bp 0 → 100644 +44 −0 Original line number Diff line number Diff line // Copyright (C) 2018 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. cc_library { name: "libbinderthreadstate", recovery_available: true, vendor_available: false, vndk: { enabled: true, support_system_process: true, }, srcs: [ "IPCThreadStateBase.cpp", ], shared_libs: [ "libbase", "liblog", "libcutils", "libutils", ], export_include_dirs: ["include"], sanitize: { misc_undefined: ["integer"], }, cflags: [ "-Wall", "-Werror", ], } libs/binderthreadstate/IPCThreadStateBase.cpp 0 → 100644 +89 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "IPCThreadStateBase" #include <binderthreadstate/IPCThreadStateBase.h> #include <android-base/macros.h> #include <utils/Log.h> #include <errno.h> #include <inttypes.h> #include <pthread.h> namespace android { static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; static bool gHaveTLS = false; static pthread_key_t gTLS = 0; IPCThreadStateBase::IPCThreadStateBase() { pthread_setspecific(gTLS, this); } IPCThreadStateBase* IPCThreadStateBase::self() { if (gHaveTLS) { restart: const pthread_key_t k = gTLS; IPCThreadStateBase* st = (IPCThreadStateBase*)pthread_getspecific(k); if (st) return st; return new IPCThreadStateBase; } pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { int key_create_value = pthread_key_create(&gTLS, threadDestructor); if (key_create_value != 0) { pthread_mutex_unlock(&gTLSMutex); ALOGW("IPCThreadStateBase::self() unable to create TLS key, expect a crash: %s\n", strerror(key_create_value)); return nullptr; } gHaveTLS = true; } pthread_mutex_unlock(&gTLSMutex); goto restart; } void IPCThreadStateBase::pushCurrentState(CallState callState) { mCallStateStack.emplace(callState); } IPCThreadStateBase::CallState IPCThreadStateBase::popCurrentState() { ALOG_ASSERT(mCallStateStack.size > 0); CallState val = mCallStateStack.top(); mCallStateStack.pop(); return val; } IPCThreadStateBase::CallState IPCThreadStateBase::getCurrentBinderCallState() { if (mCallStateStack.size() > 0) { return mCallStateStack.top(); } return CallState::NONE; } void IPCThreadStateBase::threadDestructor(void *st) { IPCThreadStateBase* const self = static_cast<IPCThreadStateBase*>(st); if (self) { delete self; } } }; // namespace android Loading
libs/binder/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ cc_library_shared { "liblog", "libcutils", "libutils", "libbinderthreadstate", ], header_libs: [ Loading
libs/binder/IPCThreadState.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "IPCThreadState" #include <binder/IPCThreadState.h> #include <binderthreadstate/IPCThreadStateBase.h> #include <binder/Binder.h> #include <binder/BpBinder.h> Loading Loading @@ -742,6 +743,7 @@ IPCThreadState::IPCThreadState() clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256); mIPCThreadStateBase = IPCThreadStateBase::self(); } IPCThreadState::~IPCThreadState() Loading Loading @@ -1082,6 +1084,9 @@ status_t IPCThreadState::executeCommand(int32_t cmd) "Not enough command data for brTRANSACTION"); if (result != NO_ERROR) break; //Record the fact that we're in a binder call. mIPCThreadStateBase->pushCurrentState( IPCThreadStateBase::CallState::BINDER); Parcel buffer; buffer.ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), Loading Loading @@ -1129,6 +1134,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); } mIPCThreadStateBase->popCurrentState(); //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n", // mCallingPid, origPid, origUid); Loading Loading @@ -1192,6 +1198,10 @@ status_t IPCThreadState::executeCommand(int32_t cmd) return result; } bool IPCThreadState::isServingCall() const { return mIPCThreadStateBase->getCurrentBinderCallState() == IPCThreadStateBase::CallState::BINDER; } void IPCThreadState::threadDestructor(void *st) { IPCThreadState* const self = static_cast<IPCThreadState*>(st); Loading
libs/binder/include/binder/IPCThreadState.h +30 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ typedef int uid_t; // --------------------------------------------------------------------------- namespace android { class IPCThreadStateBase; class IPCThreadState { public: Loading Loading @@ -89,6 +91,33 @@ public: // the maximum number of binder threads threads allowed for this process. void blockUntilThreadAvailable(); // Is this thread currently serving a binder call. This method // returns true if while traversing backwards from the function call // stack for this thread, we encounter a function serving a binder // call before encountering a hwbinder call / hitting the end of the // call stack. // Eg: If thread T1 went through the following call pattern // 1) T1 receives and executes hwbinder call H1. // 2) While handling H1, T1 makes binder call B1. // 3) The handler of B1, calls into T1 with a callback B2. // If isServingCall() is called during H1 before 3), this method // will return false, else true. // // ---- // | B2 | ---> While callback B2 is being handled, during 3). // ---- // | H1 | ---> While H1 is being handled. // ---- // Fig: Thread Call stack while handling B2 // // This is since after 3), while traversing the thread call stack, // we hit a binder call before a hwbinder call / end of stack. This // method may be typically used to determine whether to use // hardware::IPCThreadState methods or IPCThreadState methods to // infer information about thread state. bool isServingCall() const; private: IPCThreadState(); ~IPCThreadState(); Loading Loading @@ -128,6 +157,7 @@ private: uid_t mCallingUid; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; IPCThreadStateBase *mIPCThreadStateBase; }; }; // namespace android Loading
libs/binderthreadstate/Android.bp 0 → 100644 +44 −0 Original line number Diff line number Diff line // Copyright (C) 2018 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. cc_library { name: "libbinderthreadstate", recovery_available: true, vendor_available: false, vndk: { enabled: true, support_system_process: true, }, srcs: [ "IPCThreadStateBase.cpp", ], shared_libs: [ "libbase", "liblog", "libcutils", "libutils", ], export_include_dirs: ["include"], sanitize: { misc_undefined: ["integer"], }, cflags: [ "-Wall", "-Werror", ], }
libs/binderthreadstate/IPCThreadStateBase.cpp 0 → 100644 +89 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "IPCThreadStateBase" #include <binderthreadstate/IPCThreadStateBase.h> #include <android-base/macros.h> #include <utils/Log.h> #include <errno.h> #include <inttypes.h> #include <pthread.h> namespace android { static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; static bool gHaveTLS = false; static pthread_key_t gTLS = 0; IPCThreadStateBase::IPCThreadStateBase() { pthread_setspecific(gTLS, this); } IPCThreadStateBase* IPCThreadStateBase::self() { if (gHaveTLS) { restart: const pthread_key_t k = gTLS; IPCThreadStateBase* st = (IPCThreadStateBase*)pthread_getspecific(k); if (st) return st; return new IPCThreadStateBase; } pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { int key_create_value = pthread_key_create(&gTLS, threadDestructor); if (key_create_value != 0) { pthread_mutex_unlock(&gTLSMutex); ALOGW("IPCThreadStateBase::self() unable to create TLS key, expect a crash: %s\n", strerror(key_create_value)); return nullptr; } gHaveTLS = true; } pthread_mutex_unlock(&gTLSMutex); goto restart; } void IPCThreadStateBase::pushCurrentState(CallState callState) { mCallStateStack.emplace(callState); } IPCThreadStateBase::CallState IPCThreadStateBase::popCurrentState() { ALOG_ASSERT(mCallStateStack.size > 0); CallState val = mCallStateStack.top(); mCallStateStack.pop(); return val; } IPCThreadStateBase::CallState IPCThreadStateBase::getCurrentBinderCallState() { if (mCallStateStack.size() > 0) { return mCallStateStack.top(); } return CallState::NONE; } void IPCThreadStateBase::threadDestructor(void *st) { IPCThreadStateBase* const self = static_cast<IPCThreadStateBase*>(st); if (self) { delete self; } } }; // namespace android