Drive for better visionIPCThreadStateFebruary, 2012                         Himax Media                         Solutions ...
IPCThreadState 概述             功能                   封裝 /dev/binder ,所有讀寫都透過此 class 來操作             每個 thread 可以有一個實體,類似 ...
class PoolThread             功能                   產生一個新的 thread ,包裝 IPCThreadState             實作                   Po...
IPCThreadState* self()             功能                   創造新的 IPCThreadState 實體,初始化內部資料             實作                 ...
joinThreadPool(bool isMain)             功能 ( 無窮迴圈 )                   talkWithDriver(): 從 /dev/binder 讀取資料到 read        ...
talkWithDriver(bool doReceive)                                                          true                false         ...
executeCommand(cmd) - 1             功能                   根據對方的回應執行命令             實作                   BR_ACQUIRE: read...
executeCommand(cmd) - 2                                  sp<BpBinder> p = new BpBinder(handle);                           ...
executeCommand(cmd) - 3             實作                   BR_ERROR: read<int result> 作為傳回值                   BR_OK: 什麼都不...
executeCommand(cmd) - 4                   BR_TRANSACTION           binder_transaction_data                                ...
executeCommand(cmd) - 5             實作                   BR_DEAD_BINDER: read<BpBinder *proxy>                      pro...
executeCommand(cmd) - 6             實作                   BR_FINISHED: 傳回 TIMED_OUT                   BR_SPAWN_LOOPER: m...
transact (handle, code, Parcel& data,     Parcel* reply, flags)             功能                   將 data 內的資料包裝後,放在 write...
writeTransactionData (cmd, binderFlags,   handle, code, const Parcel& data,   statusBuffer)             功能               ...
waitForResponse(Parcel *reply, *result)             功能                   被 block 等待對方的回應,可能是結果也可能是資料             實作    ...
freeBuffer(parcel, data, dataSize, objects,     objectsSize, cookie)             功能                   釋放 parcel 所占用的資源  ...
threadDestructor(*ipc)             功能                   刪除 IPCThreadState 物件,並清空命令緩衝區             實作                  ...
Identity             clearCallingIdentity()                 重新取得 uid/pid ,並傳回目前的 uid/pid 給呼叫端備份             restoreCall...
Drive for better vision
Upcoming SlideShare
Loading in …5
×

08 ipc thread_state

1,268 views

Published on

Published in: Technology, Business
2 Comments
1 Like
Statistics
Notes
No Downloads
Views
Total views
1,268
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
0
Comments
2
Likes
1
Embeds 0
No embeds

No notes for slide
  • 1. 所有送出的 command 都由 BC_ 開頭,回來的都由 BR_ 開頭 2. 當 BpBinder 第一次被 strong pointer 參考時,會發出 BC_ACQUIRE ,對方則會回應 BBinder 指標,我們就可以使 BBinder 的 strong ref 加 1
  • 只有 dump, ping, getdescriptor 是真正的 transaction ,其他都不算
  • 08 ipc thread_state

    1. 1. Drive for better visionIPCThreadStateFebruary, 2012 Himax Media Solutions 承景科技股份有限公司
    2. 2. IPCThreadState 概述  功能  封裝 /dev/binder ,所有讀寫都透過此 class 來操作  每個 thread 可以有一個實體,類似 singleton patternHimax Media Solutions Proprietary & Confidential 2
    3. 3. class PoolThread  功能  產生一個新的 thread ,包裝 IPCThreadState  實作  PoolThread 繼承 Thread ,要實作 threadLoop() 作為執行緒的主 程式,只要呼叫 PoolThread.run() ,這個執行緒就會開始執行  virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain); return false; }  先呼叫 IPCThreadState::self() 產生一個 IPCThreadState 物件  呼叫 threadLoop 只會執行一次就結束,但 joinThreadPool() 本 身是無窮迴圈Himax Media Solutions Proprietary & Confidential 3
    4. 4. IPCThreadState* self()  功能  創造新的 IPCThreadState 實體,初始化內部資料  實作  thread key 每個 process 只需要創造一次,無論 IPCThreadState 是否存在, key 都會一直存在  呼叫 constructor ,將 IPCThreadState 指標設為 thread- specific  準備兩個 Parcel mIn,mOut ,大小皆為 256 bytes process  記錄目前的 pid/uid IPCThreadState A thread A key thread B IPCThreadState C thread C threadDestructor( )Himax Media Solutions Proprietary & Confidential 4
    5. 5. joinThreadPool(bool isMain)  功能 ( 無窮迴圈 )  talkWithDriver(): 從 /dev/binder 讀取資料到 read buffer ,從 write buffer 寫入資料到 /dev/binder  executeCommand(cmd): 根據讀到的資料執行對應的命令  當 read buffer 資料已處理完畢,處理未執行的 dereference  mPendingWeakDerefs, mPendingStrongDerefs  結束 thread 的條件  對方沒回應而且目前不是在 main thread  對方拒絕連線  /dev/binder 讀寫錯誤  迴圈開始前會加入 BC_ENTER_LOOPER 命令  結束 thread 前會加入 BC_EXIT_LOOPER 命令Himax Media Solutions Proprietary & Confidential 5
    6. 6. talkWithDriver(bool doReceive) true false 允許讀取 不允許讀取  功能 read buf write=1 write=1  將 read/write buffer 送到 /dev/binder 有資料 read=0 read=0  參數 read buf write=0 write=1  doReceive: 是否允許接收資料 處理完畢 read=1 read=0  實作  read buffer 有資料未處理,就只會作寫入的動作  read buffer 資料處理完畢,由 doReceive 決定是讀或寫  使用 ioctl 送出命令 BINDER_WRITE_READ ,要讀寫的資料送出  mIn: dataSize 會設為實際讀到的長度, dataPos 會設為 0  mOut: dataSize=dataPos 會設為實際寫入的長度 mIn mOut dataPos dataSize dataSize =dataPosHimax Media Solutions Proprietary & Confidential 6
    7. 7. executeCommand(cmd) - 1  功能  根據對方的回應執行命令  實作  BR_ACQUIRE: read<weakref_type *refs, BBinder *obj>  BBinder* 指標的 strong reference 加一  write<BC_ACQUIRE_DONE, refs, obj>  BR_RELEASE: read<weakref_type *refs, BBinder *obj>  將 obj 放入 mPendingStrongDerefs 中,等待有空時解除 reference  BR_INCREFS: read<weakref_type *refs, BBinder *obj>  BBinder* 指標的 weak reference 加一  write<BC_INCREFS_DONE, refs, obj>  BR_DECREFS: read<weakref_type *refs, BBinder *obj>  將 obj 放入 mPendingWeakDerefs 中,等待有空時解除 reference  BR_ATTEMPT_ACQUIRE: read<weakref_type *refs, BBinder *obj>  obj 不確定是否存在,試著將 strong ref 加一,如果 obj 仍存在則 result=true  write<BC_ACQUIRE_RESULT, result>Himax Media Solutions Proprietary & Confidential 7
    8. 8. executeCommand(cmd) - 2 sp<BpBinder> p = new BpBinder(handle); BpBinder.onFirstRef() IPCThreadState.transact() (BBinder *obj)->incStrong() sp<BpBinder> mStrong++ mWeak++ BpBinder mStrong++ BBinder mWeak++ transact() BC_ACQUIRE, handle /dev/binder IPCThreadState BR_ACQUIRE, BBinder *objHimax Media Solutions Proprietary & Confidential 8
    9. 9. executeCommand(cmd) - 3  實作  BR_ERROR: read<int result> 作為傳回值  BR_OK: 什麼都不作  BR_NOOP: 什麼都不作  BR_TRANSACTION: read<binder_transaction_data tr>  將 tr 的資料放到暫時的 Parcel buffer 中  tr.cookie 轉換為 BBinder* b  用對方的 pid/uid 來執行 b.transact(...)  write<BC_REPLY, binder_transaction_data tr>Himax Media Solutions Proprietary & Confidential 9
    10. 10. executeCommand(cmd) - 4 BR_TRANSACTION binder_transaction_data binder_transaction_data handle cookie code flags pid uid data offset buffer offset size size handle BBinder code ??? sender sender parcel parcel parcel parcel *bb pid uid data object data object size size array array IPCThreadState Parcel buffer bb.transact(tr.code, buffer, &reply, tr.flags) ≠0 BC_REPLY binder_transaction_data =0 the_context_objects.transact(tr.code, buffer, &reply, tr.flags)Himax Media Solutions Proprietary & Confidential 10
    11. 11. executeCommand(cmd) - 5  實作  BR_DEAD_BINDER: read<BpBinder *proxy>  proxy->sendObituary() 送出訃聞  write<BC_DEAD_BINDER_DONE, proxy>  BR_CLEAR_DEATH_NOTIFICATION_DONE: read<BpBinder *proxy>  proxy 的 weak reference 減一  linkToDeath() BC_REQUEST_DEATH_NOTIFICATION BpBinder BR_DEAD_BINDER, proxy BBinder  sendObituary() BC_CLEAR_DEATH_NOTIFICATION BC_DEAD_BINDER_DONEHimax Media Solutions Proprietary & Confidential 11
    12. 12. executeCommand(cmd) - 6  實作  BR_FINISHED: 傳回 TIMED_OUT  BR_SPAWN_LOOPER: mProcess->spawnPooledThread(false) ProcessState BR_SPAWN_LOOPER BC_ENTER_LOOP IPCThreadState (main) BC_REGISTER_LOOP BBinder BR_FINISHED IPCThreadState BC_EXIT_LOOPERHimax Media Solutions Proprietary & Confidential 12
    13. 13. transact (handle, code, Parcel& data, Parcel* reply, flags)  功能  將 data 內的資料包裝後,放在 write buffer 後立即送出,並等待 對方回應  對於呼叫端來說,送出資料後會被 block ,等同於呼叫本地端的 function  實作  writeTransactionData(...): 包裝資料放在 write buffer  waitForResponse(reply, result): 會 block 直到對方回應Himax Media Solutions Proprietary & Confidential 13
    14. 14. writeTransactionData (cmd, binderFlags, handle, code, const Parcel& data, statusBuffer)  功能  因為 BC_TRANSACTION 只接受 binder_transaction_data 結構的資 料,需要準備 tr 結構,將指標指向 Parcel 的內容 BC_TRANSACTION binder_transaction_data binder_transaction_data handle cookie code flags pid uid data offset buffer offset size size handle 0 code 0x10 0 0 parcel parcel parcel parcel data object data object size size array arrayHimax Media Solutions Proprietary & Confidential 14
    15. 15. waitForResponse(Parcel *reply, *result)  功能  被 block 等待對方的回應,可能是結果也可能是資料  實作  讀到的第一個 integer 代表命令,程式根據命令作不同的行為  BR_TRANSACTION_COMPLETE: 什麼都不作  BR_DEAD_REPLY: result = DEAD_OBJECT  對 IPCThreadState 沒有影響,但會造成 BpBinder 死亡  BR_FAILED_REPLY: result = FAILED_TRANSACTION  BR_ACQUIRE_RESULT: 再讀一個 integer 作為 result  BR_REPLY: 讀出 binder_transaction_data 結構  reply==NULL 或有錯誤 : write<BC_FREE_BUFFER, data>  reply!=NULL: 將 reply 內部指標指向 data  default: executeCommand(cmd) 執行對方要求的指令Himax Media Solutions Proprietary & Confidential 15
    16. 16. freeBuffer(parcel, data, dataSize, objects, objectsSize, cookie)  功能  釋放 parcel 所占用的資源  實作  將 parcel 所包含的 file descriptor 關閉  送出 <BC_FREE_BUFFER, data> 命令 BR_TRANSACTION BR_REPLY Parcel Parcel BpBinder data BBinder Owner=FreeBuffer() BC_FREE_BUFFERHimax Media Solutions Proprietary & Confidential 16
    17. 17. threadDestructor(*ipc)  功能  刪除 IPCThreadState 物件,並清空命令緩衝區  實作  清空緩衝區,將準備寫入的資料送出,但不要管對方的回應  使用 ioctl 送出 BINDER_THREAD_EXIT 命令給 /dev/binder  刪除物件Himax Media Solutions Proprietary & Confidential 17
    18. 18. Identity  clearCallingIdentity()  重新取得 uid/pid ,並傳回目前的 uid/pid 給呼叫端備份  restoreCallingIdentity(int64_t token)  將 token 內的 uid/pid 還原  getCallingPid()  傳回 pid 值  getCallingUid()  傳回 uid 值 system server Client ActivityManagerService PackageManagerServiceHimax Media Solutions Proprietary & Confidential 18
    19. 19. Drive for better vision

    ×