Binder学习笔记-4——binder service实现框架
一、一个HIDL binder服务的例子
1. 实现源码
/hardware/interfaces/graphics/composer/2.3/default/service.cpp
#include <binder/ProcessState.h> int main() { android::ProcessState::initWithDriver("/dev/vndbinder"); android::ProcessState::self()->setThreadPoolMaxThreadCount(4); android::ProcessState::self()->startThreadPool(); android::hardware::configureRpcThreadpool(4, true /* will join */); android::sp<IComposer> composer = HwcLoader::load(); composer->registerAsService(); android::hardware::joinRpcThreadpool(); ALOGE("service is terminating"); return 1; }
可以看出包含的是哪个头文件,直接通过 ProcessState 进行使用的是 libs/binder 下的接口。
/system/libhwbinder/include/hwbinder/ProcessState.h
/frameworks/native/libs/binder/include/binder/ProcessState.h
通过 android::ProcessState:: 进行引用,是因为接口函数定义在 namespace android { 下。
2. 各函数调用路径
/system/libhidl/transport/HidlTransportSupport.cpp
//一套接口
/frameworks/native/libs/binder/ProcessState.cpp
/frameworks/native/libs/binder/IPCThreadState.cpp
//第二套接口
/system/libhwbinder/ProcessState.cpp
/system/libhwbinder/IPCThreadState.cpp
ProcessState::self() 返回一个每进程的单例模式的 ProcessState("/dev/vndbinder"或 "/dev/binder") 结构。
(1) initWithDriver
android::ProcessState::initWithDriver("/dev/vndbinder"); new ProcessState(driver); open_driver(driver) mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
(2) setThreadPoolMaxThreadCount
android::ProcessState::self()->setThreadPoolMaxThreadCount(4) //service.cpp ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) //ProcessState.cpp ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads) mMaxThreads = maxThreads;
(3) startThreadPool
android::ProcessState::self()->startThreadPool() ProcessState::startThreadPool() //ProcessState.cpp mThreadPoolStarted = true; spawnPooledThread(true) //ProcessState.cpp makeBinderThreadName() //ProcessState.cpp 构建binder线程名"Binder:PID_X" sp<Thread> t = new PoolThread(true); //只是将参数true赋值给PoolThread::mIsMain t->run(name.string()); PoolThread::threadLoop() IPCThreadState::self()->joinThreadPool(mIsMain) mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); do { //在这里循环处理 result = getAndExecuteCommand(); if(result == TIMED_OUT && !isMain) break; } while (result != -ECONNREFUSED && result != -EBADF); mOut.writeInt32(BC_EXIT_LOOPER); //下面是出错后的返回清理 talkWithDriver(false);
这就是将主线程变成一个binder线程了。
(4) configureRpcThreadpool
android::hardware::configureRpcThreadpool(4, true /* will join */); //这个是调用 namespace android{ namespace hardware ( 中定义的函数。 configureRpcThreadpool(size_t maxThreads, bool callerWillJoin) //HidlTransportSupport.cpp 此例 callerWillJoin=true configureBinderRpcThreadpool(maxThreads, callerWillJoin); ProcessState::self()->setThreadPoolConfiguration(maxThreads, callerWillJoin /*callerJoinsPool*/); ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool) //libhwbinder/ProcessState.cpp size_t threadsToAllocate = maxThreads; if (callerJoinsPool) threadsToAllocate--; //若主线程加入,这4个中已经包含了加入的主线程 是不是只有hwbinder的会减去主线程的? if (threadsToAllocate > 0) threadsToAllocate--; //【1】为啥又减去一个了呢? ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &threadsToAllocate)
【1】位置是这么注释的:如果可以的话,在线程池启动时从用户空间生成一个线程。 这确保了线程池启动后始终有一个线程可用于启动更多线程。
(5) joinRpcThreadpool
android::hardware::joinRpcThreadpool(); joinRpcThreadpool() //HidlTransportSupport.cpp joinBinderRpcThreadpool() IPCThreadState::self()->joinThreadPool() mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); do { //在这里循环处理 result = getAndExecuteCommand(); if(result == TIMED_OUT && !isMain) break; } while (result != -ECONNREFUSED && result != -EBADF); mOut.writeInt32(BC_EXIT_LOOPER); //下面是出错后的返回清理 talkWithDriver(false);
TODO: 为啥会高重复两套操作呢? 一个是vnd的一个是hwbinder的?
3. 注册的binder线程状态
# echo 265 > /sys/module/binder/parameters/debug_mask # dmesg | grep BC_ENTER_LOOPER 和 BC_REGISTER_LOOPER [ 2004.456404] (1)[13312:Binder:13311_1]binder: 13311:13312 BC_ENTER_LOOPER [ 2004.457452] (3)[13313:Binder:13311_2]binder: 13311:13313 BC_REGISTER_LOOPER [ 2005.473689] (5)[13322:HwBinder:13311_]binder: 13311:13322 BC_ENTER_LOOPER [ 2005.474421] (6)[13323:HwBinder:13311_]binder: 13311:13323 BC_REGISTER_LOOPER [ 2005.477112] (6)[13311:composer@2.3-se]binder: 13311:13311 BC_ENTER_LOOPER
注意,有的是 Binder 有的是 HwBinder。systrace上显示和SF交互参与混合的是 HwBinder 线程。
4. startThreadPool() 是创建一个线程加入binder,joinThreadpool()是让主线程加入binder.
posted on 2023-10-26 16:51 Hello-World3 阅读(250) 评论(0) 编辑 收藏 举报