diff options
| author | 2024-08-05 23:41:17 +0000 | |
|---|---|---|
| committer | 2024-08-05 23:41:17 +0000 | |
| commit | f0063973af550cd32fc4f4b7e056ec76a79eaf73 (patch) | |
| tree | 471bab1b45e94ecfd7cf8282e74693d5d0a2684f /libs/binder/ProcessState.cpp | |
| parent | e1c075b7e498370f0a4af6802b6e39ff1c48cb9b (diff) | |
| parent | 908b09ce78edc6a3403d152f9f350077a3007dae (diff) | |
Merge "fix race in ProcessState::getThreadPoolMaxTotalThreadCount" into main
Diffstat (limited to 'libs/binder/ProcessState.cpp')
| -rw-r--r-- | libs/binder/ProcessState.cpp | 12 |
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; |