日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Binder ProcessState IPCThreadState相关介绍

發布時間:2025/3/15 Android 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Binder ProcessState IPCThreadState相关介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之前幾篇博客我們介紹了傳統Binder的使用方法,包括c層和java層,這篇博客我們主要介紹下ProcessState和IPCThreadState類的相關方法。


一、正常demon binder調用流程

在一個傳統的demon中,如果我們要使用Binder通信,代碼大致如下:

[cpp]?view plaincopy
  • int?main(int?argc,?char**?argv)????
  • ?{????
  • ?????sp<ProcessState>?proc(ProcessState::self());??
  • ?????MediaPlayerService::instantiate();????
  • ?????ProcessState::self()->startThreadPool();????
  • ?????IPCThreadState::self()->joinThreadPool();????
  • ?}????

  • 1.1 ProcessState::self函數

    上面先調用了ProcessState的self方法,

    [cpp]?view plaincopy
  • sp<ProcessState>?ProcessState::self()??
  • {??
  • ????Mutex::Autolock?_l(gProcessMutex);??
  • ????if?(gProcess?!=?NULL)?{??
  • ????????return?gProcess;??
  • ????}??
  • ????gProcess?=?new?ProcessState;??
  • ????return?gProcess;??
  • }??
  • 典型的單例模式,我們先來看看ProcessState的構造函數

    [cpp]?view plaincopy
  • ProcessState::ProcessState()??
  • ????:?mDriverFD(open_driver())??
  • ????,?mVMStart(MAP_FAILED)??
  • ????,?mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)??
  • ????,?mThreadCountDecrement(PTHREAD_COND_INITIALIZER)??
  • ????,?mExecutingThreadsCount(0)??
  • ????,?mMaxThreads(DEFAULT_MAX_BINDER_THREADS)??
  • ????,?mManagesContexts(false)??
  • ????,?mBinderContextCheckFunc(NULL)??
  • ????,?mBinderContextUserData(NULL)??
  • ????,?mThreadPoolStarted(false)??
  • ????,?mThreadPoolSeq(1)??
  • {??
  • ????if?(mDriverFD?>=?0)?{??
  • ????????//?XXX?Ideally,?there?should?be?a?specific?define?for?whether?we??
  • ????????//?have?mmap?(or?whether?we?could?possibly?have?the?kernel?module??
  • ????????//?availabla).??
  • #if?!defined(HAVE_WIN32_IPC)??
  • ????????//?mmap?the?binder,?providing?a?chunk?of?virtual?address?space?to?receive?transactions.??
  • ????????mVMStart?=?mmap(0,?BINDER_VM_SIZE,?PROT_READ,?MAP_PRIVATE?|?MAP_NORESERVE,?mDriverFD,?0);??
  • ????????if?(mVMStart?==?MAP_FAILED)?{??
  • ????????????//?*sigh*??
  • ????????????ALOGE("Using?/dev/binder?failed:?unable?to?mmap?transaction?memory.\n");??
  • ????????????close(mDriverFD);??
  • ????????????mDriverFD?=?-1;??
  • ????????}??
  • #else??
  • ????????mDriverFD?=?-1;??
  • #endif??
  • ????}??
  • ??
  • ????LOG_ALWAYS_FATAL_IF(mDriverFD?<?0,?"Binder?driver?could?not?be?opened.??Terminating.");??
  • }??
  • 我們在賦值的時候有如下函數 mDriverFD(open_driver())

    [cpp]?view plaincopy
  • static?int?open_driver()??
  • {??
  • ????int?fd?=?open("/dev/binder",?O_RDWR);//打開binder驅動??
  • ????if?(fd?>=?0)?{??
  • ????????fcntl(fd,?F_SETFD,?FD_CLOEXEC);??
  • ????????int?vers?=?0;??
  • ????????status_t?result?=?ioctl(fd,?BINDER_VERSION,?&vers);??
  • ????????if?(result?==?-1)?{??
  • ????????????ALOGE("Binder?ioctl?to?obtain?version?failed:?%s",?strerror(errno));??
  • ????????????close(fd);??
  • ????????????fd?=?-1;??
  • ????????}??
  • ????????if?(result?!=?0?||?vers?!=?BINDER_CURRENT_PROTOCOL_VERSION)?{??
  • ????????????ALOGE("Binder?driver?protocol?does?not?match?user?space?protocol!");??
  • ????????????close(fd);??
  • ????????????fd?=?-1;??
  • ????????}??
  • ????????size_t?maxThreads?=?DEFAULT_MAX_BINDER_THREADS;//設置binder線程數,默認15??
  • ????????result?=?ioctl(fd,?BINDER_SET_MAX_THREADS,?&maxThreads);??
  • ????????if?(result?==?-1)?{??
  • ????????????ALOGE("Binder?ioctl?to?set?max?threads?failed:?%s",?strerror(errno));??
  • ????????}??
  • ????}?else?{??
  • ????????ALOGW("Opening?'/dev/binder'?failed:?%s\n",?strerror(errno));??
  • ????}??
  • ????return?fd;??
  • }??
  • 上面這個函數打開了binder驅動節點,然后設置了binder線程數量。binder驅動打開的fd保存在mDriverFD 中。
    具體關閉Binder中線程的問題,可以參考Binder通信過程中的用戶空間線程池的管理?這篇博文。

    上面函數中還通過mmap來把設備文件/dev/binder映射到內存中。


    1.2 instantiate函數

    而instantiate函數一般是將service注冊到serviceManager中去。

    [cpp]?view plaincopy
  • void?MediaPlayerService::instantiate()?{????
  • ?????defaultServiceManager()->addService(????
  • ?????????????String16("media.player"),?new?MediaPlayerService());????
  • ?}????

  • 1.3 ProcessState::startThreadPool函數

    我們再來看startThreadPool函數

    [cpp]?view plaincopy
  • void?ProcessState::startThreadPool()??
  • {??
  • ????AutoMutex?_l(mLock);??
  • ????if?(!mThreadPoolStarted)?{??
  • ????????mThreadPoolStarted?=?true;??
  • ????????spawnPooledThread(true);??
  • ????}??
  • }??
  • 而在spawnPooledThread函數中,先建了一個線程PoolThread

    [cpp]?view plaincopy
  • void?ProcessState::spawnPooledThread(bool?isMain)??
  • {??
  • ????if?(mThreadPoolStarted)?{??
  • ????????String8?name?=?makeBinderThreadName();??
  • ????????ALOGV("Spawning?new?pooled?thread,?name=%s\n",?name.string());??
  • ????????sp<Thread>?t?=?new?PoolThread(isMain);??
  • ????????t->run(name.string());??
  • ????}??
  • }??
  • 我們看下這個PoolThread線程,最后還是調用了IPCThreadState::self()->joinThreadPool(mIsMain);

    [cpp]?view plaincopy
  • class?PoolThread?:?public?Thread??
  • {??
  • public:??
  • ????PoolThread(bool?isMain)??
  • ????????:?mIsMain(isMain)??
  • ????{??
  • ????}??
  • ??????
  • protected:??
  • ????virtual?bool?threadLoop()??
  • ????{??
  • ????????IPCThreadState::self()->joinThreadPool(mIsMain);??
  • ????????return?false;??
  • ????}??
  • ??????
  • ????const?bool?mIsMain;??
  • };??

  • 我們再來看看IPCThreadState的joinThreadPool函數,先看看其定義,參數默認是true。

    [cpp]?view plaincopy
  • void????????????????joinThreadPool(bool?isMain?=?true);??
  • 也就是在main函數中
    ???? ProcessState::self()->startThreadPool();??
    ???? IPCThreadState::self()->joinThreadPool();

    這兩個函數都是調用了joinThreadPool函數且參數都是true,只是上面的函數新建了一個thread。


    1.4 IPCThreadState::joinThreadPool函數

    我們再來看看這個函數 joinThreadPool:

    [cpp]?view plaincopy
  • void?IPCThreadState::joinThreadPool(bool?isMain)??
  • {??
  • ????LOG_THREADPOOL("****?THREAD?%p?(PID?%d)?IS?JOINING?THE?THREAD?POOL\n",?(void*)pthread_self(),?getpid());??
  • ??
  • ????mOut.writeInt32(isMain???BC_ENTER_LOOPER?:?BC_REGISTER_LOOPER);??
  • ??????
  • ????//?This?thread?may?have?been?spawned?by?a?thread?that?was?in?the?background??
  • ????//?scheduling?group,?so?first?we?will?make?sure?it?is?in?the?foreground??
  • ????//?one?to?avoid?performing?an?initial?transaction?in?the?background.??
  • ????set_sched_policy(mMyThreadId,?SP_FOREGROUND);??
  • ??????????
  • ????status_t?result;??
  • ????do?{??
  • ????????processPendingDerefs();??
  • ????????//?now?get?the?next?command?to?be?processed,?waiting?if?necessary??
  • ????????result?=?getAndExecuteCommand();??
  • ??
  • ????????if?(result?<?NO_ERROR?&&?result?!=?TIMED_OUT?&&?result?!=?-ECONNREFUSED?&&?result?!=?-EBADF)?{??
  • ????????????ALOGE("getAndExecuteCommand(fd=%d)?returned?unexpected?error?%d,?aborting",??
  • ??????????????????mProcess->mDriverFD,?result);??
  • ????????????abort();??
  • ????????}??
  • ??????????
  • ????????//?Let?this?thread?exit?the?thread?pool?if?it?is?no?longer??
  • ????????//?needed?and?it?is?not?the?main?process?thread.??
  • ????????if(result?==?TIMED_OUT?&&?!isMain)?{??
  • ????????????break;??
  • ????????}??
  • ????}?while?(result?!=?-ECONNREFUSED?&&?result?!=?-EBADF);??
  • ??
  • ????LOG_THREADPOOL("****?THREAD?%p?(PID?%d)?IS?LEAVING?THE?THREAD?POOL?err=%p\n",??
  • ????????(void*)pthread_self(),?getpid(),?(void*)result);??
  • ??????
  • ????mOut.writeInt32(BC_EXIT_LOOPER);??
  • ????talkWithDriver(false);??
  • }??
  • 這個函數就是一個死循環,不斷從驅動獲取數據,我們來看getAndExecuteCommand函數:

    [cpp]?view plaincopy
  • status_t?IPCThreadState::getAndExecuteCommand()??
  • {??
  • ????status_t?result;??
  • ????int32_t?cmd;??
  • ??
  • ????result?=?talkWithDriver();//獲取binder驅動數據??
  • ????if?(result?>=?NO_ERROR)?{??
  • ????????size_t?IN?=?mIn.dataAvail();??
  • ????????if?(IN?<?sizeof(int32_t))?return?result;??
  • ????????cmd?=?mIn.readInt32();??
  • ????????IF_LOG_COMMANDS()?{??
  • ????????????alog?<<?"Processing?top-level?Command:?"??
  • ?????????????????<<?getReturnString(cmd)?<<?endl;??
  • ????????}??
  • ??
  • ????????pthread_mutex_lock(&mProcess->mThreadCountLock);??
  • ????????mProcess->mExecutingThreadsCount++;??
  • ????????pthread_mutex_unlock(&mProcess->mThreadCountLock);??
  • ??
  • ????????result?=?executeCommand(cmd);??
  • ??
  • ????????pthread_mutex_lock(&mProcess->mThreadCountLock);??
  • ????????mProcess->mExecutingThreadsCount--;??
  • ????????pthread_cond_broadcast(&mProcess->mThreadCountDecrement);??
  • ????????pthread_mutex_unlock(&mProcess->mThreadCountLock);??
  • ??
  • ????????//?After?executing?the?command,?ensure?that?the?thread?is?returned?to?the??
  • ????????//?foreground?cgroup?before?rejoining?the?pool.??The?driver?takes?care?of??
  • ????????//?restoring?the?priority,?but?doesn't?do?anything?with?cgroups?so?we??
  • ????????//?need?to?take?care?of?that?here?in?userspace.??Note?that?we?do?make??
  • ????????//?sure?to?go?in?the?foreground?after?executing?a?transaction,?but??
  • ????????//?there?are?other?callbacks?into?user?code?that?could?have?changed??
  • ????????//?our?group?so?we?want?to?make?absolutely?sure?it?is?put?back.??
  • ????????set_sched_policy(mMyThreadId,?SP_FOREGROUND);??
  • ????}??
  • ??
  • ????return?result;??
  • }??
  • getAndExecuteCommand函數中先調用talkWithDriver就是從binder驅動獲取數據,然后調用executeCommand執行命令

    [cpp]?view plaincopy
  • status_t?IPCThreadState::executeCommand(int32_t?cmd)??
  • {??
  • ????BBinder*?obj;??
  • ????RefBase::weakref_type*?refs;??
  • ????status_t?result?=?NO_ERROR;??
  • ??????
  • ????switch?((uint32_t)cmd)?{??
  • ????case?BR_ERROR:??
  • ????????result?=?mIn.readInt32();??
  • ????????break;??
  • ??????????
  • ????case?BR_OK:??
  • ????????break;??
  • ??????????
  • ......??
  • ??????
  • ????case?BR_TRANSACTION:??
  • ????????{??
  • ????????????binder_transaction_data?tr;??
  • ????????????result?=?mIn.read(&tr,?sizeof(tr));??
  • ????????????ALOG_ASSERT(result?==?NO_ERROR,??
  • ????????????????"Not?enough?command?data?for?brTRANSACTION");??
  • ????????????if?(result?!=?NO_ERROR)?break;??
  • ??????????????
  • ????????????Parcel?buffer;??
  • ????????????buffer.ipcSetDataReference(??
  • ????????????????reinterpret_cast<const?uint8_t*>(tr.data.ptr.buffer),??
  • ????????????????tr.data_size,??
  • ????????????????reinterpret_cast<const?binder_size_t*>(tr.data.ptr.offsets),??
  • ????????????????tr.offsets_size/sizeof(binder_size_t),?freeBuffer,?this);??
  • ??????????????
  • ????????????const?pid_t?origPid?=?mCallingPid;??
  • ????????????const?uid_t?origUid?=?mCallingUid;??
  • ????????????const?int32_t?origStrictModePolicy?=?mStrictModePolicy;??
  • ????????????const?int32_t?origTransactionBinderFlags?=?mLastTransactionBinderFlags;??
  • ??
  • ????????????mCallingPid?=?tr.sender_pid;??
  • ????????????mCallingUid?=?tr.sender_euid;??
  • ????????????mLastTransactionBinderFlags?=?tr.flags;??
  • ??
  • ????????????int?curPrio?=?getpriority(PRIO_PROCESS,?mMyThreadId);??
  • ????????????if?(gDisableBackgroundScheduling)?{??
  • ????????????????if?(curPrio?>?ANDROID_PRIORITY_NORMAL)?{??
  • ????????????????????//?We?have?inherited?a?reduced?priority?from?the?caller,?but?do?not??
  • ????????????????????//?want?to?run?in?that?state?in?this?process.??The?driver?set?our??
  • ????????????????????//?priority?already?(though?not?our?scheduling?class),?so?bounce??
  • ????????????????????//?it?back?to?the?default?before?invoking?the?transaction.??
  • ????????????????????setpriority(PRIO_PROCESS,?mMyThreadId,?ANDROID_PRIORITY_NORMAL);??
  • ????????????????}??
  • ????????????}?else?{??
  • ????????????????if?(curPrio?>=?ANDROID_PRIORITY_BACKGROUND)?{??
  • ????????????????????//?We?want?to?use?the?inherited?priority?from?the?caller.??
  • ????????????????????//?Ensure?this?thread?is?in?the?background?scheduling?class,??
  • ????????????????????//?since?the?driver?won't?modify?scheduling?classes?for?us.??
  • ????????????????????//?The?scheduling?group?is?reset?to?default?by?the?caller??
  • ????????????????????//?once?this?method?returns?after?the?transaction?is?complete.??
  • ????????????????????set_sched_policy(mMyThreadId,?SP_BACKGROUND);??
  • ????????????????}??
  • ????????????}??
  • ??
  • ????????????//ALOGI(">>>>?TRANSACT?from?pid?%d?uid?%d\n",?mCallingPid,?mCallingUid);??
  • ??
  • ????????????Parcel?reply;??
  • ????????????status_t?error;??
  • ????????????IF_LOG_TRANSACTIONS()?{??
  • ????????????????TextOutput::Bundle?_b(alog);??
  • ????????????????alog?<<?"BR_TRANSACTION?thr?"?<<?(void*)pthread_self()??
  • ????????????????????<<?"?/?obj?"?<<?tr.target.ptr?<<?"?/?code?"??
  • ????????????????????<<?TypeCode(tr.code)?<<?":?"?<<?indent?<<?buffer??
  • ????????????????????<<?dedent?<<?endl??
  • ????????????????????<<?"Data?addr?=?"??
  • ????????????????????<<?reinterpret_cast<const?uint8_t*>(tr.data.ptr.buffer)??
  • ????????????????????<<?",?offsets?addr="??
  • ????????????????????<<?reinterpret_cast<const?size_t*>(tr.data.ptr.offsets)?<<?endl;??
  • ????????????}??
  • ????????????if?(tr.target.ptr)?{??
  • ????????????????sp<BBinder>?b((BBinder*)tr.cookie);??
  • ????????????????error?=?b->transact(tr.code,?buffer,?&reply,?tr.flags);//這個最終到service的onTransact函數??
  • ??
  • ????????????}?else?{??
  • ????????????????error?=?the_context_object->transact(tr.code,?buffer,?&reply,?tr.flags);??
  • ????????????}??
  • ??
  • ????????????//ALOGI("<<<<?TRANSACT?from?pid?%d?restore?pid?%d?uid?%d\n",??
  • ????????????//?????mCallingPid,?origPid,?origUid);??
  • ??????????????
  • ????????????if?((tr.flags?&?TF_ONE_WAY)?==?0)?{??
  • ????????????????LOG_ONEWAY("Sending?reply?to?%d!",?mCallingPid);??
  • ????????????????if?(error?<?NO_ERROR)?reply.setError(error);??
  • ????????????????sendReply(reply,?0);??
  • ????????????}?else?{??
  • ????????????????LOG_ONEWAY("NOT?sending?reply?to?%d!",?mCallingPid);??
  • ????????????}??
  • ??????????????
  • ????????????mCallingPid?=?origPid;??
  • ????????????mCallingUid?=?origUid;??
  • ????????????mStrictModePolicy?=?origStrictModePolicy;??
  • ????????????mLastTransactionBinderFlags?=?origTransactionBinderFlags;??
  • ??
  • ????????????IF_LOG_TRANSACTIONS()?{??
  • ????????????????TextOutput::Bundle?_b(alog);??
  • ????????????????alog?<<?"BC_REPLY?thr?"?<<?(void*)pthread_self()?<<?"?/?obj?"??
  • ????????????????????<<?tr.target.ptr?<<?":?"?<<?indent?<<?reply?<<?dedent?<<?endl;??
  • ????????????}??
  • ??????????????
  • ????????}??
  • ????????break;??
  • ......??
  • }?????????
  • 上面就是處理各種命令,最后BR_TRANSACTION命令的時候會調用BBinder的transact,最后調用service中的onTransact函數。

    [cpp]?view plaincopy
  • status_t?BBinder::transact(??
  • ????uint32_t?code,?const?Parcel&?data,?Parcel*?reply,?uint32_t?flags)??
  • {??
  • ????data.setDataPosition(0);??
  • ??
  • ????status_t?err?=?NO_ERROR;??
  • ????switch?(code)?{??
  • ????????case?PING_TRANSACTION:??
  • ????????????reply->writeInt32(pingBinder());??
  • ????????????break;??
  • ????????default:??
  • ????????????err?=?onTransact(code,?data,?reply,?flags);//調用onTransact函數??
  • ????????????break;??
  • ????}??
  • ??
  • ????if?(reply?!=?NULL)?{??
  • ????????reply->setDataPosition(0);??
  • ????}??
  • ??
  • ????return?err;??
  • }??


  • 二、不使用Binder線程

    還記得在healthd中,我們沒有使用Binder線程,我們看看代碼是怎么寫的。

    [cpp]?view plaincopy
  • static?void?binder_event(uint32_t?/*epevents*/)?{??
  • ????IPCThreadState::self()->handlePolledCommands();??
  • }??
  • ??
  • void?healthd_mode_android_init(struct?healthd_config*?/*config*/)?{??
  • ????ProcessState::self()->setThreadPoolMaxThreadCount(0);??
  • ????IPCThreadState::self()->disableBackgroundScheduling(true);??
  • ????IPCThreadState::self()->setupPolling(&gBinderFd);??
  • ??
  • ????if?(gBinderFd?>=?0)?{??
  • ????????if?(healthd_register_event(gBinderFd,?binder_event))??
  • ????????????KLOG_ERROR(LOG_TAG,??
  • ???????????????????????"Register?for?binder?events?failed\n");??
  • ????}??
  • ??
  • ????gBatteryPropertiesRegistrar?=?new?BatteryPropertiesRegistrar();??
  • ????gBatteryPropertiesRegistrar->publish();??
  • }??
  • 具體是調用healthd_mode_android_init函數,在這個函數先調用Binder接口,然后將fd 注冊到epoll中去,處理函數就是binder_event函數。


    2.1 ProcessState::setThreadPoolMaxThreadCount函數

    先來看設置Binder最大線程數的函數:

    [cpp]?view plaincopy
  • status_t?ProcessState::setThreadPoolMaxThreadCount(size_t?maxThreads)?{??
  • ????status_t?result?=?NO_ERROR;??
  • ????if?(ioctl(mDriverFD,?BINDER_SET_MAX_THREADS,?&maxThreads)?!=?-1)?{??
  • ????????mMaxThreads?=?maxThreads;??
  • ????}?else?{??
  • ????????result?=?-errno;??
  • ????????ALOGE("Binder?ioctl?to?set?max?threads?failed:?%s",?strerror(-result));??
  • ????}??
  • ????return?result;??
  • }??
  • 最后是通過ioctl設置最大線程數。


    2.2 IPCThreadState::disableBackgroundScheduling函數

    下面我們再來看disableBackgroundScheduling函數,應該是禁止后臺線程的意思

    [cpp]?view plaincopy
  • void?IPCThreadState::disableBackgroundScheduling(bool?disable)??
  • {??
  • ????gDisableBackgroundScheduling?=?disable;??
  • }??
  • 我們再來看看在哪里使用了gDisableBackgroundScheduling 這個變量, 還是在executeCommand函數中處理BR_TRANSACTION命令時有下面這段代碼

    [cpp]?view plaincopy
  • case?BR_TRANSACTION:??
  • ????{??
  • ????????binder_transaction_data?tr;??
  • ????????result?=?mIn.read(&tr,?sizeof(tr));??
  • ????????ALOG_ASSERT(result?==?NO_ERROR,??
  • ????????????"Not?enough?command?data?for?brTRANSACTION");??
  • ????????if?(result?!=?NO_ERROR)?break;??
  • ??????????
  • ????????Parcel?buffer;??
  • ????????buffer.ipcSetDataReference(??
  • ????????????reinterpret_cast<const?uint8_t*>(tr.data.ptr.buffer),??
  • ????????????tr.data_size,??
  • ????????????reinterpret_cast<const?binder_size_t*>(tr.data.ptr.offsets),??
  • ????????????tr.offsets_size/sizeof(binder_size_t),?freeBuffer,?this);??
  • ??????????
  • ????????const?pid_t?origPid?=?mCallingPid;??
  • ????????const?uid_t?origUid?=?mCallingUid;??
  • ????????const?int32_t?origStrictModePolicy?=?mStrictModePolicy;??
  • ????????const?int32_t?origTransactionBinderFlags?=?mLastTransactionBinderFlags;??
  • ??
  • ????????mCallingPid?=?tr.sender_pid;??
  • ????????mCallingUid?=?tr.sender_euid;??
  • ????????mLastTransactionBinderFlags?=?tr.flags;??
  • ??
  • ????????int?curPrio?=?getpriority(PRIO_PROCESS,?mMyThreadId);??
  • ????????if?(gDisableBackgroundScheduling)?{??
  • ????????????if?(curPrio?>?ANDROID_PRIORITY_NORMAL)?{??
  • ????????????????//?We?have?inherited?a?reduced?priority?from?the?caller,?but?do?not??
  • ????????????????//?want?to?run?in?that?state?in?this?process.??The?driver?set?our??
  • ????????????????//?priority?already?(though?not?our?scheduling?class),?so?bounce??
  • ????????????????//?it?back?to?the?default?before?invoking?the?transaction.??
  • ????????????????setpriority(PRIO_PROCESS,?mMyThreadId,?ANDROID_PRIORITY_NORMAL);??
  • ????????????}??
  • ????????}?else?{??
  • ????????????if?(curPrio?>=?ANDROID_PRIORITY_BACKGROUND)?{??
  • ????????????????//?We?want?to?use?the?inherited?priority?from?the?caller.??
  • ????????????????//?Ensure?this?thread?is?in?the?background?scheduling?class,??
  • ????????????????//?since?the?driver?won't?modify?scheduling?classes?for?us.??
  • ????????????????//?The?scheduling?group?is?reset?to?default?by?the?caller??
  • ????????????????//?once?this?method?returns?after?the?transaction?is?complete.??
  • ????????????????set_sched_policy(mMyThreadId,?SP_BACKGROUND);??
  • ????????????}??
  • ????????}??

  • 2.3 IPCThreadState::setupPolling


    下面我們再來看看setupPolling函數

    [cpp]?view plaincopy
  • int?IPCThreadState::setupPolling(int*?fd)??
  • {??
  • ????if?(mProcess->mDriverFD?<=?0)?{??
  • ????????return?-EBADF;??
  • ????}??
  • ??
  • ????mOut.writeInt32(BC_ENTER_LOOPER);??
  • ????*fd?=?mProcess->mDriverFD;??
  • ????return?0;??
  • }??
  • 我們看代碼這個函數只是獲取Binder驅動的fd


    2.4 Binder驅動 有數據

    然后我們把fd加入主線程的epoll進行監聽,當Binder驅動有數據的時候,就會調用binder_event函數

    [cpp]?view plaincopy
  • static?void?binder_event(uint32_t?/*epevents*/)?{??
  • ????IPCThreadState::self()->handlePolledCommands();??
  • }??
  • 我們來看下handlePolledCommands函數:

    [cpp]?view plaincopy
  • status_t?IPCThreadState::handlePolledCommands()??
  • {??
  • ????status_t?result;??
  • ??
  • ????do?{??
  • ????????result?=?getAndExecuteCommand();??
  • ????}?while?(mIn.dataPosition()?<?mIn.dataSize());??
  • ??
  • ????processPendingDerefs();??
  • ????flushCommands();??
  • ????return?result;??
  • }??
  • getAndExecuteCommand函數之前我們分析過,這里再來看下:

    [cpp]?view plaincopy
  • status_t?IPCThreadState::getAndExecuteCommand()??
  • {??
  • ????status_t?result;??
  • ????int32_t?cmd;??
  • ??
  • ????result?=?talkWithDriver();//獲取binder驅動數據??
  • ????if?(result?>=?NO_ERROR)?{??
  • ????????size_t?IN?=?mIn.dataAvail();??
  • ????????if?(IN?<?sizeof(int32_t))?return?result;??
  • ????????cmd?=?mIn.readInt32();??
  • ????????IF_LOG_COMMANDS()?{??
  • ????????????alog?<<?"Processing?top-level?Command:?"??
  • ?????????????????<<?getReturnString(cmd)?<<?endl;??
  • ????????}??
  • ??
  • ????????pthread_mutex_lock(&mProcess->mThreadCountLock);??
  • ????????mProcess->mExecutingThreadsCount++;??
  • ????????pthread_mutex_unlock(&mProcess->mThreadCountLock);??
  • ??
  • ????????result?=?executeCommand(cmd);//執行命令??
  • ??
  • ????????pthread_mutex_lock(&mProcess->mThreadCountLock);??
  • ????????mProcess->mExecutingThreadsCount--;??
  • ????????pthread_cond_broadcast(&mProcess->mThreadCountDecrement);??
  • ????????pthread_mutex_unlock(&mProcess->mThreadCountLock);??
  • ??
  • ????????//?After?executing?the?command,?ensure?that?the?thread?is?returned?to?the??
  • ????????//?foreground?cgroup?before?rejoining?the?pool.??The?driver?takes?care?of??
  • ????????//?restoring?the?priority,?but?doesn't?do?anything?with?cgroups?so?we??
  • ????????//?need?to?take?care?of?that?here?in?userspace.??Note?that?we?do?make??
  • ????????//?sure?to?go?in?the?foreground?after?executing?a?transaction,?but??
  • ????????//?there?are?other?callbacks?into?user?code?that?could?have?changed??
  • ????????//?our?group?so?we?want?to?make?absolutely?sure?it?is?put?back.??
  • ????????set_sched_policy(mMyThreadId,?SP_FOREGROUND);??
  • ????}??
  • ??
  • ????return?result;??
  • }??
  • 先獲取binder驅動數據,然后再執行executeCommand函數,和之前一樣執行到BR_TRANSACTION命令會調用BBinder的transact,最終執行到service的onTransact函數中。

    當然這些數據的處理都是在healthd的主線程中,是epoll在binder驅動有數據的時候執行的。


    2.5 處理完數據后 清理工作

    我們繼續看handlePolledCommands函數

    [cpp]?view plaincopy
  • status_t?IPCThreadState::handlePolledCommands()??
  • {??
  • ????status_t?result;??
  • ??
  • ????do?{??
  • ????????result?=?getAndExecuteCommand();??
  • ????}?while?(mIn.dataPosition()?<?mIn.dataSize());??
  • ??
  • ????processPendingDerefs();??
  • ????flushCommands();??
  • ????return?result;??
  • }??
  • 最后做一些清理工作,在flushCommands函數中將和binder驅動的交互關閉。

    [cpp]?view plaincopy
  • void?IPCThreadState::flushCommands()??
  • {??
  • ????if?(mProcess->mDriverFD?<=?0)??
  • ????????return;??
  • ????talkWithDriver(false);??
  • }??


  • 三、總結

    這篇博客我們主要講了使用binder的demon的binder調用流程,以及不使用binder線程的代碼調用方法,舉例了healthd中的一個例子。

    

    原始地址: http://blog.csdn.net/kc58236582/article/details/51744398

    總結

    以上是生活随笔為你收集整理的Android Binder ProcessState IPCThreadState相关介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。