ProcessState初始化
ProcessState 是 libbinder 进程级状态的 owner:它保存 Binder 驱动 fd、事务接收区映射、线程池计数、handle 到 BpBinder 的表以及 fork 状态。初始化不是简单的 C++ 单例构造,而是“选择 driver → call_once 竞争保护 → pthread_atfork 注册 → 打开并协商驱动 → mmap 接收区”的组合流程。
本文面向已经读过 Binder设备打开、Binder内存映射 和 ServiceManager启动 的读者。本文回答 self()、initWithDriver() 和 selfOrNull() 如何共享单例、驱动路径何时生效、初始化失败如何表现,以及 fork 后为什么不能继续使用原 ProcessState。线程池如何加入和处理事务由后续 Native 框架文章展开。
1. 入口选择
1.1 默认驱动
源码文件:frameworks/native/libs/binder/ProcessState.cpp
相关函数:self()、initWithDriver()、selfOrNull()、selfIfKernelBinderEnabled()
sp<ProcessState> ProcessState::self() {
return init(kDefaultDriver, false /*requireDefault*/);
}
sp<ProcessState> ProcessState::initWithDriver(const char* driver) {
return init(driver, true /*requireDefault*/);
}
sp<ProcessState> ProcessState::selfOrNull() {
return init(nullptr, false /*requireDefault*/);
}
sp<ProcessState> ProcessState::selfIfKernelBinderEnabled() {
if (access(kDefaultDriver, R_OK) == -1) return nullptr;
return init(kDefaultDriver, false /*requireDefault*/);
}普通构建的 kDefaultDriver 是 /dev/binder,VNDK 构建选择 /dev/vndbinder。selfOrNull() 的 null 参数表示只查询已有单例;selfIfKernelBinderEnabled() 先做设备节点可读性检查,但这只是访问门槛,不等于后续 open()、协议协商和 mmap 一定成功。
1.2 路径关系
2. 单例竞争
2.1 查询分支
源码文件:frameworks/native/libs/binder/ProcessState.cpp
相关函数:ProcessState::init()
[[clang::no_destroy]] static sp<ProcessState> gProcess;
[[clang::no_destroy]] static std::mutex gProcessMutex;
sp<ProcessState> ProcessState::init(
const char* driver, bool requireDefault) {
if (driver == nullptr) {
std::lock_guard<std::mutex> l(gProcessMutex);
if (gProcess) verifyNotForked(gProcess->mForked);
return gProcess;
}
...
}查询分支锁住全局 mutex 后读取 gProcess。它不会创建驱动 fd,也不会通过 access() 证明 Binder 当前可用;调用者得到的是“是否已经有对象”的答案。
2.2 初始化分支
[[clang::no_destroy]] static std::once_flag gProcessOnce;
std::call_once(gProcessOnce, [&] {
if (access(driver, R_OK) == -1) {
ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.",
driver);
driver = "/dev/binder";
}
int ret = pthread_atfork(ProcessState::onFork,
ProcessState::parentPostFork,
ProcessState::childPostFork);
LOG_ALWAYS_FATAL_IF(ret != 0,
"pthread_atfork error %s", strerror(ret));
std::lock_guard<std::mutex> l(gProcessMutex);
gProcess = sp<ProcessState>::make(driver);
});call_once 保证 lambda 只执行一次;mutex 保护对象指针和 fork 回调安装顺序。驱动不可读时源码回退到 /dev/binder,但构造函数仍可能因为打开、版本或 mmap 失败而产生无效状态。
2.3 驱动一致性
if (requireDefault) {
LOG_ALWAYS_FATAL_IF(
gProcess->getDriverName() != driver,
"ProcessState was already initialized with %s, "
"can't initialize with %s.",
gProcess->getDriverName().c_str(), driver);
}
verifyNotForked(gProcess->mForked);
return gProcess;initWithDriver() 要求调用必须发生在其他初始化之前;若单例已经用不同 driver 建立,路径不一致会 fatal。self() 的 requireDefault=false 不会主动切换已经存在的单例。
3. 驱动建立
3.1 打开与协商
源码文件:frameworks/native/libs/binder/ProcessState.cpp
相关函数:open_driver()
static unique_fd open_driver(
const char* driver, String8* error) {
auto fd = unique_fd(open(
driver, O_RDWR | O_CLOEXEC));
if (!fd.ok()) return {};
int vers = 0;
int result = ioctl(fd.get(), BINDER_VERSION, &vers);
if (result == -1 ||
vers != BINDER_CURRENT_PROTOCOL_VERSION) {
return {};
}
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
result = ioctl(fd.get(), BINDER_SET_MAX_THREADS,
&maxThreads);
if (result == -1) {
ALOGE("Binder ioctl to set max threads failed: %s",
strerror(errno));
}
return fd;
}打开使用 O_RDWR | O_CLOEXEC。版本不匹配是失败;设置最大线程数失败只记录错误,fd 仍可返回。默认线程上限由 DEFAULT_MAX_BINDER_THREADS 初始化,后续进程代码仍可调用 setThreadPoolMaxThreadCount() 调整策略。
3.2 特性启用
uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
result = ioctl(fd.get(), BINDER_ENABLE_ONEWAY_SPAM_DETECTION,
&enable);
if (result == -1) {
ALOGE_IF(ProcessState::isDriverFeatureEnabled(
ProcessState::DriverFeature::ONEWAY_SPAM_DETECTION),
"Binder ioctl to enable oneway spam detection failed: %s",
strerror(errno));
}oneway spam detection 的 ioctl 失败不一定让打开流程失败:只有当 binderfs feature 文件表明驱动支持该能力时才记录错误。这里的“可选特性失败”与协议版本失败是不同级别。
4. 接收映射
4.1 构造状态
源码文件:frameworks/native/libs/binder/ProcessState.cpp
相关函数:ProcessState::ProcessState()
ProcessState::ProcessState(const char* driver)
: mDriverName(String8(driver)),
mDriverFD(-1),
mVMStart(MAP_FAILED),
mMaxThreads(DEFAULT_MAX_BINDER_THREADS),
mCurrentThreads(0),
mKernelStartedThreads(0),
mForked(false),
mThreadPoolStarted(false),
mThreadPoolSeq(1),
mCallRestriction(CallRestriction::NONE) {
String8 error;
unique_fd opened = open_driver(driver, &error);
...
}构造函数先把 fd、映射和线程状态置于可识别的初始值,再尝试建立 driver。mVMStart=MAP_FAILED 让析构可以区分“没有映射”与有效地址。
4.2 mmap失败
if (opened.ok()) {
mVMStart = mmap(nullptr, BINDER_VM_SIZE,
PROT_READ,
MAP_PRIVATE | MAP_NORESERVE,
opened.get(), 0);
if (mVMStart == MAP_FAILED) {
ALOGE("Using %s failed: unable to mmap transaction memory.",
driver);
opened.reset();
mDriverName.clear();
}
}Binder 接收区是用户态地址空间预留,权限为 PROT_READ,内核通过同一 fd 管理事务页。mmap 失败会关闭临时 fd 并清空 driver 名;Android 构建下 EXPECT_BINDER_OPEN_SUCCESS 还会让打开失败 fatal,host 构建则记录错误后保留对象。
5. Fork保护
5.1 atfork回调
源码文件:frameworks/native/libs/binder/ProcessState.cpp
相关函数:onFork()、parentPostFork()、childPostFork()
void ProcessState::onFork() {
gProcessMutex.lock();
}
void ProcessState::parentPostFork() {
gProcessMutex.unlock();
}
void ProcessState::childPostFork() {
if (gProcess) {
gProcess->mForked = true;
close(gProcess->mDriverFD);
gProcess->mDriverFD = -1;
}
gProcessMutex.unlock();
}子进程继承了用户态对象和映射状态,却不能安全地继续复用父进程 Binder 状态。子 fork 回调关闭 fd 并标记 mForked;之后任何入口调用 verifyNotForked() 都 fatal。
5.2 初始化时机
pthread_atfork() 必须在创建 gProcess 前安装,否则另一个线程可能在回调安装前 fork,产生没有 fork 保护的 ProcessState。这个顺序是并发安全的一部分,不是初始化风格偏好。
6. 生命周期边界
6.1 线程池字段
源码文件:frameworks/native/libs/binder/include/binder/ProcessState.h
相关字段:mMaxThreads、mCurrentThreads、mKernelStartedThreads、mThreadPoolStarted
初始化只建立计数和 fd,不自动启动用户态线程池。startThreadPool()、joinThreadPool() 或 polling 由进程主线决定;因此 ProcessState 存在不等于已经能消费 Binder transaction。
6.2 析构清理
ProcessState::~ProcessState() {
if (mDriverFD >= 0) {
if (mVMStart != MAP_FAILED) {
munmap(mVMStart, BINDER_VM_SIZE);
}
close(mDriverFD);
}
mDriverFD = -1;
}析构先解除映射,再关闭 fd。全局 gProcess 使用 no_destroy,正常进程退出时通常不会走普通单例析构;这段代码主要为显式生命周期和测试提供资源释放逻辑。
7. 源码验证
7.1 入口搜索
rg -n "ProcessState::(self|selfOrNull|initWithDriver|init)|pthread_atfork|call_once" \
frameworks/native/libs/binder/ProcessState.cpp
rg -n "open_driver|BINDER_VERSION|BINDER_SET_MAX_THREADS|mmap|BINDER_VM_SIZE" \
frameworks/native/libs/binder/ProcessState.cpp
rg -n "onFork|parentPostFork|childPostFork|verifyNotForked" \
frameworks/native/libs/binder/ProcessState.cpp7.2 证明边界
固定源码范围没有把 ProcessState 的所有初始化分支包装成一个直接生产单元测试;本文的关键结论分别由静态控制流、驱动 ioctl 分支、构造/析构清理和 ServiceManager 启动调用共同支撑。读者可以用以下问题检查理解:为什么 selfOrNull() 不会创建对象,为什么 initWithDriver() 不能晚于 self(),为什么 mmap 失败必须关闭 fd,以及 fork 后为什么关闭 fd 还不够、仍需 mForked fatal 保护。
