binder: Add an API to check if the threadpool has been started
Libraries that require the threadpool can check this to make sure the
threadpool has been started before it is needed.
Test: atest binderLibTest
Bug: 261652496
Change-Id: I7505319f162e2789dcc3c41bf1f7535c5c1bb9d9
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 1f311ac..254dda8 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -439,6 +439,10 @@
return mCurrentThreads;
}
+bool ProcessState::isThreadPoolStarted() const {
+ return mThreadPoolStarted;
+}
+
#define DRIVER_FEATURES_PATH "/dev/binderfs/features/"
bool ProcessState::isDriverFeatureEnabled(const DriverFeature feature) {
static const char* const names[] = {
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index 87eee3d..bad8cb1 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -97,6 +97,11 @@
*/
size_t getThreadPoolMaxTotalThreadCount() const;
+ /**
+ * Check to see if the thread pool has started.
+ */
+ bool isThreadPoolStarted() const;
+
enum class DriverFeature {
ONEWAY_SPAM_DETECTION,
EXTENDED_ERROR,
diff --git a/libs/binder/ndk/include_platform/android/binder_process.h b/libs/binder/ndk/include_platform/android/binder_process.h
index 8923129..ffcad55 100644
--- a/libs/binder/ndk/include_platform/android/binder_process.h
+++ b/libs/binder/ndk/include_platform/android/binder_process.h
@@ -43,6 +43,13 @@
*/
bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads);
/**
+ * Check if the threadpool has already been started.
+ * This tells whether someone in the process has called ABinderProcess_startThreadPool. Usually,
+ * you should use this in a library to abort if the threadpool is not started.
+ * Programs should configure binder threadpools once at the beginning.
+ */
+bool ABinderProcess_isThreadPoolStarted();
+/**
* This adds the current thread to the threadpool. This may cause the threadpool to exceed the
* maximum size.
*
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 5c7005c..54e4628 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -154,6 +154,7 @@
LIBBINDER_NDK34 { # introduced=UpsideDownCake
global:
+ ABinderProcess_isThreadPoolStarted; # systemapi llndk
AServiceManager_getUpdatableApexName; # systemapi
AServiceManager_registerForServiceNotifications; # systemapi llndk
AServiceManager_NotificationRegistration_delete; # systemapi llndk
diff --git a/libs/binder/ndk/process.cpp b/libs/binder/ndk/process.cpp
index ac582a4..bc6610e 100644
--- a/libs/binder/ndk/process.cpp
+++ b/libs/binder/ndk/process.cpp
@@ -31,6 +31,9 @@
bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads) {
return ProcessState::self()->setThreadPoolMaxThreadCount(numThreads) == 0;
}
+bool ABinderProcess_isThreadPoolStarted() {
+ return ProcessState::self()->isThreadPoolStarted();
+}
void ABinderProcess_joinThreadPool() {
IPCThreadState::self()->joinThreadPool();
}
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 25b524f..f7498c4 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -120,6 +120,7 @@
BINDER_LIB_TEST_CAN_GET_SID,
BINDER_LIB_TEST_GET_MAX_THREAD_COUNT,
BINDER_LIB_TEST_SET_MAX_THREAD_COUNT,
+ BINDER_LIB_TEST_IS_THREADPOOL_STARTED,
BINDER_LIB_TEST_LOCK_UNLOCK,
BINDER_LIB_TEST_PROCESS_LOCK,
BINDER_LIB_TEST_UNLOCK_AFTER_MS,
@@ -1383,6 +1384,14 @@
EXPECT_EQ(replyi, kKernelThreads + 1);
}
+TEST_F(BinderLibTest, ThreadPoolStarted) {
+ Parcel data, reply;
+ sp<IBinder> server = addServer();
+ ASSERT_TRUE(server != nullptr);
+ EXPECT_THAT(server->transact(BINDER_LIB_TEST_IS_THREADPOOL_STARTED, data, &reply), NO_ERROR);
+ EXPECT_TRUE(reply.readBool());
+}
+
size_t epochMillis() {
using std::chrono::duration_cast;
using std::chrono::milliseconds;
@@ -1849,6 +1858,10 @@
reply->writeInt32(ProcessState::self()->getThreadPoolMaxTotalThreadCount());
return NO_ERROR;
}
+ case BINDER_LIB_TEST_IS_THREADPOOL_STARTED: {
+ reply->writeBool(ProcessState::self()->isThreadPoolStarted());
+ return NO_ERROR;
+ }
case BINDER_LIB_TEST_PROCESS_LOCK: {
m_blockMutex.lock();
return NO_ERROR;