Binder学习二 MediaServer

以MediaServer为例,进程初始化如下:

1.创建进程中所有Service实例

2.注册service到service manager

3.创建线程池,等待处理binder事件


MediaServer处理原理如下图所示:


上图中,mediaserver的两个线程首先调用binder的ioctl方法并挂起等待binder唤醒,如图中步骤a1和b1所示。其次客户端通过BpXXX发送命令給binder,如步骤a2,b2所示,此时客服端线程将被挂起。binder设备收到请求后首先更新binder_write_read数据结构,然后唤醒挂起的线程,并调用BnXXX::onTransact()执行客户请求。服务端完成处理后将通知binder,binder唤醒客户端线程,从而得到最终结果。


以下为详细调用代码:

frameworks/base/media/mediaserver/Main_mediaserver.cpp

int main(int argc, char** argv)
{
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    LOGI("ServiceManager: %p", sm.get());
    MediaPlayerService::instantiate();      //new MediaPlayerService并注册
    CameraService::instantiate();
    AudioPolicyService::instantiate();
    ProcessState::self()->startThreadPool(); //创建线程并调用IPCThreadState::joinThreadPool(true) why??
    IPCThreadState::self()->joinThreadPool(); //在主线程中调用IPCThreadState::joinThreadPool(true)
}

疑点:startThreadPool和joinThreadPool完后有两个线程,主线程和工作线程,而且都在做消息循环,且参数isMain都是true。难道google怕一个线程工作量太多,所以搞两个线程来工作?网上有人测试过把最后一句屏蔽掉,也能正常工作。

frameworks/base/libs/binder/ProcessState.cpp

ProcessState::ProcessState()
    : mDriverFD(open_driver())
    , mVMStart(MAP_FAILED)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
...}

static int open_driver()
{
    if (gSingleProcess) {
        return -1;
    }

    int fd = open("/dev/binder", O_RDWR);
    if (fd >= 0) {
        fcntl(fd, F_SETFD, FD_CLOEXEC); //这里设置为FD_CLOEXEC表示当程序执行exec函数时本fd将被系统自动关闭,表示不传递给exec创建的新进程 ??
        int vers;
        status_t result = ioctl(fd, BINDER_V
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值