ProcessState以及IPCThreadState

ProcessState是負責打開Binder節點並做mmap映射,IPCThreadState是負責與Binder驅動進行具體的命令交互。
ProcessState
- 實現ProcessState的主要關鍵點有以下幾個:
 
- 保證同一進程只有一個ProcessState實例,且只有在ProcessState對象建立時才打開Binder設備以及做內存映射
 - 向上層提供IPc服務
 - 與IPCThreadState分工
 
- 首先分析第一個點:
源碼位置:/frameworks/native/libs/binder/ProcessState.cpp http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/binder/ProcessState.cpp 
sp<ProcessState> ProcessState::self() { if (gProcess != NULL) return gProcess; AutoMutex _l(gProcessMutex); if (gProcess == NULL) gProcess = new ProcessState; return gProcess; }
可以看到,在這里也是先檢查是否存在一個已經實例化的prosessstate,否則創建一個,所以獲取ProcessState對象,需要通過這個self方法。
接下來需要一步步的觀察這個新建的過程當中實現的原理。
- 分析構造函數:
 
ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) { if (mDriverFD >= 0) { mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); close(mDriverFD); mDriverFD = -1; } #else mDriverFD = -1; #endif } if (mDriverFD < 0) { // Need to run without the driver, starting our own thread pool. } }
可以看到有兩個之前學習的時候了解到了,與Binder驅動緊密相關的方法:
 一個是open_driver(),另一個是下面的mmap(),也就是最終打開了Binder結點以及進行了內存塊的映射。
- 接下來分析在之前用到的獲取IBinder的對象時的一個方法:getContextObject
在這個方法中,傳入了一個handel,最終得到了一個BpBinder,而這個BpBinder是Binder在Native層的代理。 
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) { return getStrongProxyForHandle(0); }
ProcessState::getStrongProxyForHandle 
           sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { ...... IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { if (handle == 0) { ...... Parcel data; status_t status = IPCThreadState::self()->transact( 0, IBinder::PING_TRANSACTION, data, NULL, 0); if (status == DEAD_OBJECT) return NULL; } b = new BpBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { // This little bit of nastyness is to allow us to add a primary // reference to the remote proxy when this team doesn't have one // but another team is sending the handle to us. result.force_set(b); e->refs->decWeak(this); } } return result; }
ProcessState::lookupHandleLocked
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle) { const size_t N=mHandleToObject.size(); if (N <= (size_t)handle) { handle_entry e; e.binder = NULL; e.refs = NULL; status_t err = mHandleToObject.insertAt(e, N, handle+1-N); if (err < NO_ERROR) return NULL; } return &mHandleToObject.editItemAt(handle); }
從這兒看,先調用lookupHandleLocked方法,由於是第一次調用,因此新建一個handle_entry,並返回,而且其binder和refs為NULL
那么getStrongProxyForHandle方法接着往下走,由於binder為NULL,mHandle傳入的是0,因此進入判斷條件中,最后new BpBinder,且參數為0
因此,返回的是new BpBinder(0)
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
IPCThreadState
代碼位置:/frameworks/native/libs/binder/IPCThreadState.cpp
http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/binder/IPCThreadState.cpp
- 單實例構造函數:
 
IPCThreadState* IPCThreadState::self() { if (gHaveTLS) { //當執行完第一次之后,再次運行的時候就已經有IPCThreadState實例,只需要獲取就可以使用 restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); if (st) return st; return new IPCThreadState; } if (gShutdown) { ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n"); return NULL; } pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { //初始的gHaveTLS的值false,所以第一次調用的時候,會執行這里的代碼 //隨后將gHaveTLS設置為true int key_create_value = pthread_key_create(&gTLS, threadDestructor); if (key_create_value != 0) { pthread_mutex_unlock(&gTLSMutex); ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n", strerror(key_create_value)); return NULL; } gHaveTLS = true; } pthread_mutex_unlock(&gTLSMutex); goto restart; }
通過上面的方法,就能保證“線程單實例”的目的
- 現有的調用分析順序是:
getService@ServiceManagerProxy-->transact@BinderProxy-->transact@BpBinder-->transact@IPCThreadState - 不管是讀取還是寫入,Binder驅動都只是發揮中間人的作用,真正處理請求的還是Binder Client以及Binder Server雙方。
 - 真正與Binder打交道的地方時talkWithDriver中的ioctl()
 
