zx_channel_call

摘要

傳送訊息給管道,等待對方回覆。

宣告

#include <zircon/syscalls.h>

zx_status_t zx_channel_call(zx_handle_t handle,
                            uint32_t options,
                            zx_time_t deadline,
                            const zx_channel_call_args_t* args,
                            uint32_t* actual_bytes,
                            uint32_t* actual_handles);

說明

zx_channel_call() 就像是 zx_channel_write()zx_object_wait_one() 的合併 和 zx_channel_read(),此外還添加了一項功能,交易 ID 位於 訊息酬載正面 bytes 的用途,是將回覆訊息與 訊息,讓多個通話執行緒共用一個管道,而無需額外的 使用者空間簿記

這項作業的寫入和讀取階段行為如下:zx_channel_write()zx_channel_read() 搭配透過 zx_channel_call_args_t 結構。

系統會將寫入和讀取回訊息的前 4 個位元組視為 「zx_txid_t」類型的交易 ID。核心會為 撰寫訊息,將訊息的這個部分替換為從使用者空間讀取的。 核心產生的 txid 介於 0x80000000 至 0xFFFFFFFF 之間, 不與該正在進行的任何其他 zx_channel_call() 的 txid 衝突 管道端點如果寫入訊息的長度少於 4 個字元 個位元組,就會回報錯誤。

寫入外寄郵件時,系統會同時登錄興趣 以尋找符合 txid 的內送郵件。

期限可能會根據工作的計時器滑桿自動調整 政策。

雖然內部訊息調整後的期限並未經過, 抵達時會有相符的 txid,而不會被加到一般的尾端 傳入訊息佇列,則會直接傳送到等待的執行緒, zx_channel_call()

如果收到這類回覆,但折扣調整後的期限已過, 進入一般內送訊息佇列,導致 ZX_CHANNEL_READABLE 產生 信號等

內送郵件過大,無法容納 rd_num_bytesrd_num_handles 就會遭到捨棄,並ZX_ERR_BUFFER_TOO_SMALL

zx_channel_write() 相同,帳號代碼中的控制代碼一律會使用 zx_channel_call() 並不再於呼叫程序中。

ZX_CHANNEL_WRITE_USE_IOVEC 選項

如果指定 ZX_CHANNEL_WRITE_USE_IOVEC 選項,系統會為 wr_bytes 會解讀為 zx_channel_iovec_t 的陣列,並指定至 並按照順序複製到訊息中num_wr_bytes 會指定數字 wr_bytes 中的 zx_channel_iovec_t 陣列元素。

typedef struct zx_channel_iovec {
  const void* buffer;      // User-space bytes.
  uint32_t capacity;       // Number of bytes.
  uint32_t reserved;       // Reserved.
} zx_channel_iovec_t;

最多只能有 ZX_CHANNEL_MAX_MSG_IOVEC8192 wr_bytes 陣列的 zx_channel_iovec_t 元素,加總 所有zx_channel_iovec_tcapacity,未超過 ZX_CHANNEL_MAX_MSG_BYTES65536 個位元組。buffer不得對齊 如果 capacity 為 0,則只有 NULL。「reserved」必須設為零。

系統會複製所有zx_channel_iovec_t並傳送訊息,或是完全不傳送 而且訊息不會傳送。傳送帳號代碼的使用方式維持不變。

權限

handle 必須是 ZX_OBJ_TYPE_CHANNEL 類型,且具有 ZX_RIGHT_READ 且包含 ZX_RIGHT_WRITE

args 的所有 wr_handles 都必須擁有 ZX_RIGHT_TRANSFER

傳回值

zx_channel_call()會在成功及指定的位元組數ZX_OK的情況下傳回 回覆訊息中的帳號代碼會透過 actual_bytes 傳回。 actual_handles

錯誤

ZX_ERR_BAD_HANDLE 帳號代碼不是有效的帳號代碼, handles 不是有效的帳號代碼,或是帳號代碼重複 handles 陣列中)。

ZX_ERR_WRONG_TYPE 帳號代碼不是管道帳號代碼。

ZX_ERR_INVALID_ARGS 提供的任何指標無效或空值, 或 wr_num_bytes 小於 4,或者 options 為非零。 如果已指定 ZX_CHANNEL_WRITE_USE_IOVEC 選項, ZX_ERR_INVALID_ARGS如果緩衝區欄位含有 指標無效,或是保留欄位不是零。

ZX_ERR_ACCESS_DENIED 帳號代碼沒有 ZX_RIGHT_WRITE帳號代碼中的任何元素都沒有 ZX_RIGHT_TRANSFER

ZX_ERR_PEER_CLOSED管道另一側關閉或變成 在等待回應期間關閉。

ZX_ERR_CANCELED 帳號代碼在等候回覆期間無效 (例如關閉)。

ZX_ERR_NO_MEMORY 因記憶體不足而失敗。 使用者空間無法妥善處理這種 (異常) 錯誤。 在日後的版本中不會再發生這個錯誤。

ZX_ERR_OUT_OF_RANGE wr_num_byteswr_num_handles 大於 管道訊息的允許大小上限。 如果已指定 ZX_CHANNEL_WRITE_USE_IOVEC 選項, 如果num_bytes大於ZX_ERR_OUT_OF_RANGE ZX_CHANNEL_MAX_MSG_IOVEC 或生物容量的總和超過 ZX_CHANNEL_MAX_MSG_BYTES

ZX_ERR_BUFFER_TOO_SMALL rd_num_bytesrd_num_handles 過小 以包含回覆訊息。

ZX_ERR_NOT_SUPPORTED 帳號代碼的其中一個帳號代碼為「帳號代碼」 (寫入管道的帳號代碼)。

附註

zx_channel_call() 提供的設施可與訊息調度工具互通 直接使用 zx_channel_read()zx_channel_write(),前提是必須遵守下列規則 觀察到的:

  1. 透過 zx_channel_read() 接收同步訊息的伺服器應確保 傳入訊息的 txid 會退回透過 zx_channel_write() 在傳出的回覆中 ,讓使用 zx_channel_call() 的用戶端能正確轉送回覆。

  2. 透過 zx_channel_write() 傳送訊息的客戶,應確保 只使用介於 0 到 0x7FFFFFFF 之間的 txids,以免與其他執行緒衝突 透過 zx_channel_call() 進行通訊。

如果 zx_channel_call()ZX_ERR_TIMED_OUT 而傳回,如果伺服器最終回應 日後的某個時間點,回覆「可能」與另一項傳出要求相符 (假設 自原始要求後發生了 2^31 個 zx_channel_call()。此系統呼叫的設計 逾時情況通常為嚴重嚴重錯誤,而用戶端不會繼續預期 例如,

另請參閱