基本概念
控點是核心結構,可讓使用者模式程式參照核心物件。控點可視為工作階段或與特定核心物件的連線。
一般而言,多個程序會透過不同控點並行存取相同的物件。但是,單一控制代碼只能繫結至單一程序,或繫結至核心。
當該資料集繫結至核心時,我們會說是「傳輸中」。
在使用者模式中,控制代碼只是特定系統呼叫傳回的特定數字。使用者模式只能查看未傳輸中的帳號代碼。
代表帳號代碼的整數對該程序有意義。另一個程序中相同的數字,可能不會對應至任何控制代碼,也可能對應至指向完全不同核心物件的控制代碼。
帳號代碼的整數值是任何 32 位元的數字,但對應 ZX_HANDLE_INVALID 的值一律為 0。除此之外,有效控制代碼的整數值一律至少具有兩個控制點的兩個位元。代表這些位元的遮罩可透過 ZX_HANDLE_FIXED_BITS_MASK 存取
針對核心模式,控制代碼是一個 C++ 物件,其中包含三個邏輯欄位:
- 核心物件的參照
- 具備核心物件的權限
- 繫結至核心的程序 (或繫結至核心時)
「rights」指定允許對核心物件執行哪些作業。單一程序可以為同一個核心物件指派兩種不同的處理方式,同時擁有不同的權限。
圖 1 使用者程序會開始建立帳號代碼。
圖 2. 使用者程序會使用系統呼叫建立核心物件 (例如事件),並保留物件的整數參照。
圖 3. 系統會使用一組基本權限建立帳號代碼,以及該核心物件類型適用的任何其他權利。
圖 4. 帳號代碼可以複製。在此程序中也可以捨棄權限。
使用帳號代碼
許多系統呼叫會建立新的核心物件,並且會傳回控制代碼。例如:
這些呼叫會建立核心物件以及指向該物件的第一個控點。控點會繫結至發出系統呼叫的程序,權利則是該類型核心物件的預設權限。
只有一個 Syscall 可以產生控點副本,而控點指向同一個核心物件,且會繫結至發出系統呼叫的相同程序:
有一個 Syscall 會建立對等的帳號代碼 (權限可能較少),進而使原始控點失效:
有一個系統呼叫只會刪除控點:
有一個 syscall 會接收繫結至呼叫程序的控制代碼,並將其繫結至核心 (納入傳輸中的控制代碼):
有兩個 Syscall 使用傳輸中控點,並將其繫結至呼叫程序:
上述管道和通訊端系統呼叫是用來將控制代碼從一個程序轉移到另一個程序。例如將兩個程序連接至管道。如要轉移控制代碼,請呼叫 zx_channel_write
或 zx_channel_call
,然後目的地程序會呼叫相同管道上的 zx_channel_read
。
最後,系統會透過單一系統呼叫提供新程序,該程序會提供其啟動控點,即用來要求其他控點的控制代碼:
啟動處理控點可以是任何可轉移的核心物件,但最合理的情況是,由於其會指向管道的一端,因此這個初始管道可用於將進一步控制代碼傳送到新程序。
垃圾收集
如果控制代碼有效,代表其指向的核心物件保證有效。因為核心物件會遭到系統拒絕,且每個控點都保留其核心物件的參照,所以可以做到這一點。
相反地,控制代碼遭到刪除時,並不會一併刪除相對應的核心物件。可能還有其他指向物件的控制代碼,或者核心本身可能保留了核心物件的參照。
對核心物件的上次參照發布時,核心物件會遭到刪除,或核心將物件標記為垃圾收集;物件目前的待處理作業組合完成後就會刪除。
詳情請參閱核心物件生命週期頁面。
特殊情況
如果處理中的帳號代碼在傳輸過程中,且寫入該管道或通訊端,該帳號代碼會關閉。
偵錯工作階段 (和偵錯工具) 可能會有特殊的系統呼叫以取得控點的存取權。
無效的帳號代碼和帳號重複使用代碼
傳送至任何 syscall 是錯誤,但 zx_object_get_info
下列值除外:
- 與關閉的帳號代碼對應的帳號代碼值
- ZX_HANDLE_INVALID 值,
zx_handle_close
系統呼叫除外
核心可自由針對新建立的物件重複使用關閉控點的整數值。因此,請務必確實觀察到適當的處理衛生:
不要有一個執行緒關閉指定的控制代碼,而另一個執行緒會以順暢的方式使用同一個控制代碼。即使第二個執行緒也關閉了該執行緒。
請勿忽略 ZX_ERR_BAD_HANDLE 傳回代碼。通常表示程式碼發生邏輯錯誤。
如要偵測無效的帳號代碼使用情形,可以搭配使用 ZX_POL_BAD_HANDLE 工作政策與 ZX_POL_ACTION_EXCEPTION 來產生例外狀況,當這類工作物件下的程序嘗試上述的任何無效情況時,就會產生例外狀況。