[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:
Dmitrii Kuvaiskii
2019-07-19 01:03:41 -07:00
parent 61be1b2e40
commit 9dea9384ee
2 changed files with 22 additions and 12 deletions
+17 -8
View File
@@ -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;
}
+5 -4
View File
@@ -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);
}