summaryrefslogtreecommitdiff
path: root/libs/binder/ProcessState.cpp
diff options
context:
space:
mode:
author Frederick Mayle <fmayle@google.com> 2024-08-05 23:41:17 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2024-08-05 23:41:17 +0000
commitf0063973af550cd32fc4f4b7e056ec76a79eaf73 (patch)
tree471bab1b45e94ecfd7cf8282e74693d5d0a2684f /libs/binder/ProcessState.cpp
parente1c075b7e498370f0a4af6802b6e39ff1c48cb9b (diff)
parent908b09ce78edc6a3403d152f9f350077a3007dae (diff)
Merge "fix race in ProcessState::getThreadPoolMaxTotalThreadCount" into main
Diffstat (limited to 'libs/binder/ProcessState.cpp')
-rw-r--r--libs/binder/ProcessState.cpp12
1 files changed, 10 insertions, 2 deletions
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index a42ede29a2..7c29dba2d0 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -429,8 +429,17 @@ status_t ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) {
}
size_t ProcessState::getThreadPoolMaxTotalThreadCount() const {
+ // Need to read `mKernelStartedThreads` before `mThreadPoolStarted` (with
+ // non-relaxed memory ordering) to avoid a race like the following:
+ //
+ // thread A: if (mThreadPoolStarted) { // evaluates false
+ // thread B: mThreadPoolStarted = true;
+ // thread B: mKernelStartedThreads++;
+ // thread A: size_t kernelStarted = mKernelStartedThreads;
+ // thread A: LOG_ALWAYS_FATAL_IF(kernelStarted != 0, ...);
+ size_t kernelStarted = mKernelStartedThreads;
+
if (mThreadPoolStarted) {
- size_t kernelStarted = mKernelStartedThreads;
size_t max = mMaxThreads;
size_t current = mCurrentThreads;
@@ -460,7 +469,6 @@ size_t ProcessState::getThreadPoolMaxTotalThreadCount() const {
// must not be initialized or maybe has poll thread setup, we
// currently don't track this in libbinder
- size_t kernelStarted = mKernelStartedThreads;
LOG_ALWAYS_FATAL_IF(kernelStarted != 0, "Expecting 0 kernel started threads but have %zu",
kernelStarted);
return mCurrentThreads;