mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-06 05:41:37 +00:00
[LibOS] Handle corner-cases during {send,receive}_ipc_message
This commit adds additional logic around DkStreamWrite() and DkStreamRead() in send_ipc_message() and receive_ipc_message() respectively: interrupts and partial reads/writes are handled correctly.
This commit is contained in:
@@ -257,15 +257,24 @@ int send_ipc_message(struct shim_ipc_msg* msg, struct shim_ipc_port* port) {
|
||||
msg->src = cur_process.vmid;
|
||||
debug("Sending ipc message to port %p (handle %p)\n", port, port->pal_handle);
|
||||
|
||||
/* TODO: Handle benign EINTR case? */
|
||||
/* TODO: Add while-loop to send all msg */
|
||||
int ret = DkStreamWrite(port->pal_handle, 0, msg->size, msg, NULL);
|
||||
size_t total_bytes = msg->size;
|
||||
size_t bytes = 0;
|
||||
|
||||
if (ret == 0 && PAL_NATIVE_ERRNO) {
|
||||
debug("Port %p (handle %p) was removed during sending\n", port, port->pal_handle);
|
||||
del_ipc_port_fini(port, -ECHILD);
|
||||
return -PAL_ERRNO;
|
||||
}
|
||||
do {
|
||||
size_t ret = DkStreamWrite(port->pal_handle, 0, total_bytes - bytes,
|
||||
(void *)msg + bytes, NULL);
|
||||
|
||||
if (!ret) {
|
||||
if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN || PAL_ERRNO == EWOULDBLOCK)
|
||||
continue;
|
||||
|
||||
debug("Port %p (handle %p) was removed during sending\n", port, port->pal_handle);
|
||||
del_ipc_port_fini(port, -ECHILD);
|
||||
return -PAL_ERRNO;
|
||||
}
|
||||
|
||||
bytes += ret;
|
||||
} while (bytes < total_bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -495,12 +495,13 @@ static int receive_ipc_message(struct shim_ipc_port* port) {
|
||||
msg = tmp_buf;
|
||||
}
|
||||
|
||||
/* TODO: Add while-loop to receive all msg */
|
||||
int read = DkStreamRead(port->pal_handle, /*offset*/ 0, expected_size - bytes + readahead,
|
||||
(void *) msg + bytes, NULL, 0);
|
||||
|
||||
if (read == 0) {
|
||||
/* TODO: Handle benign EINTR case? */
|
||||
if (!read) {
|
||||
if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN || PAL_ERRNO == EWOULDBLOCK)
|
||||
continue;
|
||||
|
||||
debug("Port %p (handle %p) closed while receiving IPC message\n", port, port->pal_handle);
|
||||
del_ipc_port_fini(port, -ECHILD);
|
||||
ret = -PAL_ERRNO;
|
||||
@@ -639,7 +640,7 @@ noreturn static void shim_ipc_helper(void* dummy) {
|
||||
if (DkStreamAttributesQueryByHandle(polled_port->pal_handle, &attr)) {
|
||||
/* can read on this port, so receive messages */
|
||||
if (attr.readable) {
|
||||
/* TODO: IPC helper thread does not handle failures currently */
|
||||
/* NOTE: IPC helper thread does not handle failures currently */
|
||||
receive_ipc_message(polled_port);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user