From 7e7f0a96f5816c2c47ef716af6e64fd17eac7881 Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 16 Aug 2023 16:48:39 +0200 Subject: [PATCH] wind+libos+libui: Handle interrupted reads properly --- libos/include/os/IPC.h | 6 +++--- libos/src/IPC.cpp | 4 ++++ libui/src/App.cpp | 17 +++++++++++++++-- wind/IPC.cpp | 7 +++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/libos/include/os/IPC.h b/libos/include/os/IPC.h index 260d9c3f..fe185a15 100644 --- a/libos/include/os/IPC.h +++ b/libos/include/os/IPC.h @@ -102,7 +102,7 @@ namespace os { u8 response_id; auto rc = client.recv_typed(response_id); - if (rc.has_error() && rc.error() == EAGAIN) continue; + if (rc.has_error() && (rc.error() == EAGAIN || rc.error() == EINTR)) continue; if (response_id == 0) // Error result { @@ -110,7 +110,7 @@ namespace os { int code; rc = client.recv_typed(code); - if (rc.has_error() && rc.error() == EAGAIN) continue; + if (rc.has_error() && (rc.error() == EAGAIN || rc.error() == EINTR)) continue; return err(code); } } @@ -126,7 +126,7 @@ namespace os { ResponseType response; rc = client.recv_typed(response); - if (rc.has_error() && rc.error() == EAGAIN) continue; + if (rc.has_error() && (rc.error() == EAGAIN || rc.error() == EINTR)) continue; return response; } } diff --git a/libos/src/IPC.cpp b/libos/src/IPC.cpp index fbe6b164..b0be457d 100644 --- a/libos/src/IPC.cpp +++ b/libos/src/IPC.cpp @@ -18,6 +18,8 @@ namespace os::IPC if (rc.has_error()) { if (rc.error() == EAGAIN) return {}; // No messages, and the caller does not want us to block. + if (rc.error() == EINTR) + return {}; // Let the caller check for anything having happened because a signal handler ran. return rc.release_error(); } @@ -31,6 +33,8 @@ namespace os::IPC if (rc.has_error()) { if (rc.error() == EAGAIN) return {}; // No messages, and the caller does not want us to block. + if (rc.error() == EINTR) + return {}; // Let the caller check for anything having happened because a signal handler ran. return rc.release_error(); } diff --git a/libui/src/App.cpp b/libui/src/App.cpp index eb067312..78e5f8e5 100644 --- a/libui/src/App.cpp +++ b/libui/src/App.cpp @@ -88,13 +88,26 @@ namespace ui return window->ptr(); } +#define READ_MESSAGE(request) \ + do { \ + auto rc = m_client->recv_typed(request); \ + if (rc.has_error()) \ + { \ + if (rc.error() == EAGAIN) { continue; } \ + if (rc.error() == EINTR) { continue; } \ + else \ + return rc.release_error(); \ + } \ + break; \ + } while (true) + Result App::handle_ipc_event(u8 id) { switch (id) { case WINDOW_CLOSE_REQUEST_ID: { WindowCloseRequest request; - TRY(m_client->recv_typed(request)); + READ_MESSAGE(request); os::eprintln("ui: Window close request from server! Shall comply."); auto* window = find_window(request.window); window->close(); @@ -102,7 +115,7 @@ namespace ui } case MOUSE_EVENT_REQUEST_ID: { MouseEventRequest request; - TRY(m_client->recv_typed(request)); + READ_MESSAGE(request); auto* window = find_window(request.window); window->handle_mouse_move(request.position); window->handle_mouse_buttons(request.position, request.buttons); diff --git a/wind/IPC.cpp b/wind/IPC.cpp index dbec731f..3a4e5e59 100644 --- a/wind/IPC.cpp +++ b/wind/IPC.cpp @@ -68,6 +68,12 @@ static Result create_shm_region(const char* path, int* outfd, ui::Rect rec client.rpc_id = decltype(request)::ID; \ return {}; \ } \ + if (rc.error() == EINTR) \ + { \ + client.rpc_in_progress = true; \ + client.rpc_id = decltype(request)::ID; \ + return {}; \ + } \ else \ return rc.release_error(); \ } \ @@ -202,6 +208,7 @@ namespace wind if (rc.has_error()) { if (rc.error() == EAGAIN) { return {}; } + if (rc.error() == EINTR) { return {}; } else return rc.release_error(); }