Loading libs/binder/IPCThreadState.cpp +29 −6 Original line number Diff line number Diff line Loading @@ -486,6 +486,19 @@ void IPCThreadState::flushCommands() } } bool IPCThreadState::flushIfNeeded() { if (mIsLooper || mServingStackPointer != nullptr) { return false; } // In case this thread is not a looper and is not currently serving a binder transaction, // there's no guarantee that this thread will call back into the kernel driver any time // soon. Therefore, flush pending commands such as BC_FREE_BUFFER, to prevent them from getting // stuck in this thread's out buffer. flushCommands(); return true; } void IPCThreadState::blockUntilThreadAvailable() { pthread_mutex_lock(&mProcess->mThreadCountLock); Loading Loading @@ -604,6 +617,7 @@ void IPCThreadState::joinThreadPool(bool isMain) mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); mIsLooper = true; status_t result; do { processPendingDerefs(); Loading @@ -626,6 +640,7 @@ void IPCThreadState::joinThreadPool(bool isMain) (void*)pthread_self(), getpid(), result); mOut.writeInt32(BC_EXIT_LOOPER); mIsLooper = false; talkWithDriver(false); } Loading Loading @@ -739,16 +754,19 @@ void IPCThreadState::incStrongHandle(int32_t handle, BpBinder *proxy) LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle); mOut.writeInt32(BC_ACQUIRE); mOut.writeInt32(handle); if (!flushIfNeeded()) { // Create a temp reference until the driver has handled this command. proxy->incStrong(mProcess.get()); mPostWriteStrongDerefs.push(proxy); } } void IPCThreadState::decStrongHandle(int32_t handle) { LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle); mOut.writeInt32(BC_RELEASE); mOut.writeInt32(handle); flushIfNeeded(); } void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) Loading @@ -756,16 +774,19 @@ void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle); mOut.writeInt32(BC_INCREFS); mOut.writeInt32(handle); if (!flushIfNeeded()) { // Create a temp reference until the driver has handled this command. proxy->getWeakRefs()->incWeak(mProcess.get()); mPostWriteWeakDerefs.push(proxy->getWeakRefs()); } } void IPCThreadState::decWeakHandle(int32_t handle) { LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle); mOut.writeInt32(BC_DECREFS); mOut.writeInt32(handle); flushIfNeeded(); } status_t IPCThreadState::attemptIncStrongHandle(int32_t handle) Loading Loading @@ -821,6 +842,7 @@ IPCThreadState::IPCThreadState() mServingStackPointer(nullptr), mWorkSource(kUnsetWorkSource), mPropagateWorkSource(false), mIsLooper(false), mStrictModePolicy(0), mLastTransactionBinderFlags(0), mCallRestriction(mProcess->mCallRestriction) Loading Loading @@ -1401,6 +1423,7 @@ void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, IPCThreadState* state = self(); state->mOut.writeInt32(BC_FREE_BUFFER); state->mOut.writePointer((uintptr_t)data); state->flushIfNeeded(); } } // namespace android libs/binder/include/binder/IPCThreadState.h +2 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ public: status_t setupPolling(int* fd); status_t handlePolledCommands(); void flushCommands(); bool flushIfNeeded(); void joinThreadPool(bool isMain = true); Loading Loading @@ -204,6 +205,7 @@ private: int32_t mWorkSource; // Whether the work source should be propagated. bool mPropagateWorkSource; bool mIsLooper; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; CallRestriction mCallRestriction; Loading libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -375,8 +375,7 @@ TEST(NdkBinder, ABpBinderRefCount) { AIBinder_decStrong(binder); // assert because would need to decStrong if non-null and we shouldn't need to add a no-op here ASSERT_NE(nullptr, AIBinder_Weak_promote(wBinder)); ASSERT_EQ(nullptr, AIBinder_Weak_promote(wBinder)); AIBinder_Weak_delete(wBinder); } Loading Loading
libs/binder/IPCThreadState.cpp +29 −6 Original line number Diff line number Diff line Loading @@ -486,6 +486,19 @@ void IPCThreadState::flushCommands() } } bool IPCThreadState::flushIfNeeded() { if (mIsLooper || mServingStackPointer != nullptr) { return false; } // In case this thread is not a looper and is not currently serving a binder transaction, // there's no guarantee that this thread will call back into the kernel driver any time // soon. Therefore, flush pending commands such as BC_FREE_BUFFER, to prevent them from getting // stuck in this thread's out buffer. flushCommands(); return true; } void IPCThreadState::blockUntilThreadAvailable() { pthread_mutex_lock(&mProcess->mThreadCountLock); Loading Loading @@ -604,6 +617,7 @@ void IPCThreadState::joinThreadPool(bool isMain) mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); mIsLooper = true; status_t result; do { processPendingDerefs(); Loading @@ -626,6 +640,7 @@ void IPCThreadState::joinThreadPool(bool isMain) (void*)pthread_self(), getpid(), result); mOut.writeInt32(BC_EXIT_LOOPER); mIsLooper = false; talkWithDriver(false); } Loading Loading @@ -739,16 +754,19 @@ void IPCThreadState::incStrongHandle(int32_t handle, BpBinder *proxy) LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle); mOut.writeInt32(BC_ACQUIRE); mOut.writeInt32(handle); if (!flushIfNeeded()) { // Create a temp reference until the driver has handled this command. proxy->incStrong(mProcess.get()); mPostWriteStrongDerefs.push(proxy); } } void IPCThreadState::decStrongHandle(int32_t handle) { LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle); mOut.writeInt32(BC_RELEASE); mOut.writeInt32(handle); flushIfNeeded(); } void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) Loading @@ -756,16 +774,19 @@ void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle); mOut.writeInt32(BC_INCREFS); mOut.writeInt32(handle); if (!flushIfNeeded()) { // Create a temp reference until the driver has handled this command. proxy->getWeakRefs()->incWeak(mProcess.get()); mPostWriteWeakDerefs.push(proxy->getWeakRefs()); } } void IPCThreadState::decWeakHandle(int32_t handle) { LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle); mOut.writeInt32(BC_DECREFS); mOut.writeInt32(handle); flushIfNeeded(); } status_t IPCThreadState::attemptIncStrongHandle(int32_t handle) Loading Loading @@ -821,6 +842,7 @@ IPCThreadState::IPCThreadState() mServingStackPointer(nullptr), mWorkSource(kUnsetWorkSource), mPropagateWorkSource(false), mIsLooper(false), mStrictModePolicy(0), mLastTransactionBinderFlags(0), mCallRestriction(mProcess->mCallRestriction) Loading Loading @@ -1401,6 +1423,7 @@ void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, IPCThreadState* state = self(); state->mOut.writeInt32(BC_FREE_BUFFER); state->mOut.writePointer((uintptr_t)data); state->flushIfNeeded(); } } // namespace android
libs/binder/include/binder/IPCThreadState.h +2 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ public: status_t setupPolling(int* fd); status_t handlePolledCommands(); void flushCommands(); bool flushIfNeeded(); void joinThreadPool(bool isMain = true); Loading Loading @@ -204,6 +205,7 @@ private: int32_t mWorkSource; // Whether the work source should be propagated. bool mPropagateWorkSource; bool mIsLooper; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; CallRestriction mCallRestriction; Loading
libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -375,8 +375,7 @@ TEST(NdkBinder, ABpBinderRefCount) { AIBinder_decStrong(binder); // assert because would need to decStrong if non-null and we shouldn't need to add a no-op here ASSERT_NE(nullptr, AIBinder_Weak_promote(wBinder)); ASSERT_EQ(nullptr, AIBinder_Weak_promote(wBinder)); AIBinder_Weak_delete(wBinder); } Loading