From 68b7783f32500396e53c28baa63f12c79f087e86 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 15 Mar 2026 09:43:22 +0000 Subject: [PATCH] lib: xpc: implement non-blocking msg receive function --- lib/libxpc/include/xpc/msg.h | 1 + lib/libxpc/msg.c | 43 ++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/libxpc/include/xpc/msg.h b/lib/libxpc/include/xpc/msg.h index 6bcae28..3ae443e 100644 --- a/lib/libxpc/include/xpc/msg.h +++ b/lib/libxpc/include/xpc/msg.h @@ -29,6 +29,7 @@ extern void xpc_msg_header_init( unsigned short func); extern bool xpc_msg_header_validate(const xpc_msg_header_t *msg); extern kern_status_t xpc_msg_recv(kern_handle_t channel, xpc_msg_t *out); +extern kern_status_t xpc_msg_recv_nowait(kern_handle_t channel, xpc_msg_t *out); extern kern_status_t xpc_msg_read( const xpc_msg_t *msg, size_t offset, diff --git a/lib/libxpc/msg.c b/lib/libxpc/msg.c index 6d92428..ec4b7d2 100644 --- a/lib/libxpc/msg.c +++ b/lib/libxpc/msg.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include @@ -20,8 +22,25 @@ bool xpc_msg_header_validate(const xpc_msg_header_t *msg) return msg->hdr_magic == XPC_MSG_MAGIC; } -kern_status_t xpc_msg_recv(kern_handle_t channel, xpc_msg_t *out) +static kern_status_t __msg_recv( + kern_handle_t channel, + xpc_msg_t *out, + bool nowait) { + kern_status_t status = KERN_OK; + + if (!nowait) { + kern_wait_item_t wait = { + .w_handle = channel, + .w_waitfor = CHANNEL_SIGNAL_MSG_RECEIVED, + }; + + status = kern_object_wait(&wait, 1); + if (status != KERN_OK) { + return status; + } + } + kern_iovec_t iov = IOVEC(&out->msg_header, sizeof out->msg_header); kern_msg_t msg = { .msg_data = &iov, @@ -29,7 +48,8 @@ kern_status_t xpc_msg_recv(kern_handle_t channel, xpc_msg_t *out) .msg_handles = out->msg_handles, .msg_handles_count = KERN_MSG_MAX_HANDLES, }; - kern_status_t status = msg_recv(channel, &msg); + + status = msg_recv(channel, &msg); if (status != KERN_OK) { return status; } @@ -46,6 +66,25 @@ kern_status_t xpc_msg_recv(kern_handle_t channel, xpc_msg_t *out) return KERN_OK; } +kern_status_t xpc_msg_recv(kern_handle_t channel, xpc_msg_t *out) +{ + kern_status_t status = KERN_OK; + while (1) { + status = __msg_recv(channel, out, false); + + if (status != KERN_NO_ENTRY) { + break; + } + } + + return status; +} + +kern_status_t xpc_msg_recv_nowait(kern_handle_t channel, xpc_msg_t *out) +{ + return __msg_recv(channel, out, true); +} + kern_status_t xpc_msg_read( const xpc_msg_t *msg, size_t offset,