summaryrefslogtreecommitdiff
path: root/libs/binder/IPCThreadState.cpp
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2021-01-21 17:15:14 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2021-01-21 17:15:14 +0000
commit7677da691e589e3c99161b89d14d0b38c7abb90b (patch)
treedb8f0e5113780f42e8df0b6cc786e5a04eda8371 /libs/binder/IPCThreadState.cpp
parentda4a5ca5b7cd4865c315d41fad30f56db0a1a13e (diff)
parent0442a8694dfb4f04a2d3da9290627c92483d50f2 (diff)
Merge "Flush BC_FREE_BUFFER and ref ops from non-looper threads."
Diffstat (limited to 'libs/binder/IPCThreadState.cpp')
-rw-r--r--libs/binder/IPCThreadState.cpp35
1 files changed, 29 insertions, 6 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index b038feb878..5c34069b23 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -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);
@@ -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();
@@ -626,6 +640,7 @@ void IPCThreadState::joinThreadPool(bool isMain)
(void*)pthread_self(), getpid(), result);
mOut.writeInt32(BC_EXIT_LOOPER);
+ mIsLooper = false;
talkWithDriver(false);
}
@@ -739,9 +754,11 @@ void IPCThreadState::incStrongHandle(int32_t handle, BpBinder *proxy)
LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
mOut.writeInt32(BC_ACQUIRE);
mOut.writeInt32(handle);
- // Create a temp reference until the driver has handled this command.
- proxy->incStrong(mProcess.get());
- mPostWriteStrongDerefs.push(proxy);
+ 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)
@@ -749,6 +766,7 @@ 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)
@@ -756,9 +774,11 @@ void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy)
LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
mOut.writeInt32(BC_INCREFS);
mOut.writeInt32(handle);
- // Create a temp reference until the driver has handled this command.
- proxy->getWeakRefs()->incWeak(mProcess.get());
- mPostWriteWeakDerefs.push(proxy->getWeakRefs());
+ 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)
@@ -766,6 +786,7 @@ 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)
@@ -821,6 +842,7 @@ IPCThreadState::IPCThreadState()
mServingStackPointer(nullptr),
mWorkSource(kUnsetWorkSource),
mPropagateWorkSource(false),
+ mIsLooper(false),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0),
mCallRestriction(mProcess->mCallRestriction)
@@ -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