Android ProcessState init
调用流程
1. sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
2. BinderInternal.getContextObject())
3. static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{sp<IBinder> b = ProcessState::self()->getContextObject(NULL);return javaObjectForIBinder(env, b);
}
4. ProcessState::self()
5. sp<ProcessState> ProcessState::self()
{return init(kDefaultDriver, false /*requireDefault*/);
}
源码分析
#ifdef __ANDROID_VNDK__
const char* kDefaultDriver = "/dev/vndbinder";
#else
const char* kDefaultDriver = "/dev/binder";
#endifsp<ProcessState> ProcessState::init(const char* driver, bool requireDefault) {if (driver == nullptr) { //1std::lock_guard<std::mutex> l(gProcessMutex);if (gProcess) {verifyNotForked(gProcess->mForked);}return gProcess;}[[clang::no_destroy]] static std::once_flag gProcessOnce;std::call_once(gProcessOnce, [&](){ //2if (access(driver, R_OK) == -1) {ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.", driver);driver = "/dev/binder";}if (0 == strcmp(driver, "/dev/vndbinder") && !isVndservicemanagerEnabled()) {ALOGE("vndservicemanager is not started on this device, you can save resources/threads ""by not initializing ProcessState with /dev/vndbinder.");}// we must install these before instantiating the gProcess object,// otherwise this would race with creating it, and there could be the// possibility of an invalid gProcess object forked by another thread// before these are installed// 3int 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); //4});if (requireDefault) { //5// Detect if we are trying to initialize with a different driver, and// consider that an error. ProcessState will only be initialized once above.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); //6return gProcess;
}
一、单例模式与线程安全
1. 单例控制
当 driver == nullptr 时直接返回现有实例 gProcess,确保全局唯一性。若需要初始化新实例,通过 std::call_once 保证多线程环境下仅执行一次初始化。
2. 锁机制
使用 std::mutex 锁保护 gProcess 的访问,避免多线程竞争条件。例如,std::lock_guardstd::mutex l(gProcessMutex) 在关键代码段加锁。
二、驱动路径处理
1. 驱动可用性检查
通过 access(driver, R_OK) 验证指定驱动路径的可读性。若失败(如 /dev/vndbinder 不可用),自动回退到默认路径 /dev/binder,并记录错误日志。
2. vndbinder 的特殊处理
当尝试初始化 /dev/vndbinder 时,会额外检查 vndservicemanager 是否已启动。若未启动,输出警告日志提示资源浪费风险。
三、进程 Fork 处理
通过 pthread_atfork 注册以下回调函数,确保进程 fork 时 Binder 状态正确:
- onFork:fork 前执行,用于锁定资源。
- parentPostFork:父进程 fork 后恢复状态。
- childPostFork:子进程 fork 后重置 Binder 驱动连接(如关闭文件描述符)。
四、参数验证与错误处理
1. 驱动一致性校验
若 requireDefault 为 true,强制要求当前实例的驱动名称必须与传入的 driver 一致,否则触发致命错误(LOG_ALWAYS_FATAL_IF),防止重复初始化不同驱动。
2. Fork 状态检查
调用 verifyNotForked(gProcess->mForked) 确保当前进程未处于 fork 后的子进程中,避免跨进程状态污染。
五、关键对象创建
- 实例化 ProcessState
通过 sp::make(driver) 创建智能指针管理的 ProcessState 对象,其构造函数会执行以下操作:- 调用 open_driver() 打开 Binder 驱动设备(如 /dev/binder)。
- 使用 mmap 在内核空间映射内存区域(默认大小 1MB-8KB),用于 Binder 事务传输。
- 通过 ioctl 设置 Binder 版本和最大线程数。
总结
此函数是 Binder 通信的基石,负责:
1. 单例生命周期管理:确保进程内唯一的 ProcessState 实例。
2. 驱动兼容性适配:动态处理不同驱动路径(标准/VND Binder)。
3. 多进程安全:通过 fork 处理回调避免状态泄漏。
4. 资源初始化:完成驱动连接、内存映射等底层操作。
通过上述机制,ProcessState::init() 为 Android 跨进程通信提供了稳定的进程状态管理框架。