From 40340509d9245694bf46e60604c0fb262f668465 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 12 Nov 2021 18:50:50 +0100 Subject: [PATCH] Add interruptor utilities Expose wrapper functions for interrupting blocking calls, for process and sockets. --- app/meson.build | 2 + app/src/util/net_intr.c | 97 +++++++++++++++++++++++++++++++++++++ app/src/util/net_intr.h | 35 +++++++++++++ app/src/util/process_intr.c | 16 ++++++ app/src/util/process_intr.h | 13 +++++ 5 files changed, 163 insertions(+) create mode 100644 app/src/util/net_intr.c create mode 100644 app/src/util/net_intr.h create mode 100644 app/src/util/process_intr.c create mode 100644 app/src/util/process_intr.h diff --git a/app/meson.build b/app/meson.build index 8240dd16..09c79f21 100644 --- a/app/meson.build +++ b/app/meson.build @@ -28,7 +28,9 @@ src = [ 'src/util/intr.c', 'src/util/log.c', 'src/util/net.c', + 'src/util/net_intr.c', 'src/util/process.c', + 'src/util/process_intr.c', 'src/util/strbuf.c', 'src/util/str_util.c', 'src/util/term.c', diff --git a/app/src/util/net_intr.c b/app/src/util/net_intr.c new file mode 100644 index 00000000..b9443e2f --- /dev/null +++ b/app/src/util/net_intr.c @@ -0,0 +1,97 @@ +#include "net_intr.h" + +bool +net_connect_intr(struct sc_intr *intr, sc_socket socket, uint32_t addr, + uint16_t port) { + if (!sc_intr_set_socket(intr, socket)) { + // Already interrupted + return false; + } + + bool ret = net_connect(socket, addr, port); + + sc_intr_set_socket(intr, SC_INVALID_SOCKET); + return ret; +} + +bool +net_listen_intr(struct sc_intr *intr, sc_socket socket, uint32_t addr, + uint16_t port, int backlog) { + if (!sc_intr_set_socket(intr, socket)) { + // Already interrupted + return false; + } + + bool ret = net_listen(socket, addr, port, backlog); + + sc_intr_set_socket(intr, SC_INVALID_SOCKET); + return ret; +} + +sc_socket +net_accept_intr(struct sc_intr *intr, sc_socket server_socket) { + if (!sc_intr_set_socket(intr, server_socket)) { + // Already interrupted + return SC_INVALID_SOCKET; + } + + sc_socket socket = net_accept(server_socket); + + sc_intr_set_socket(intr, SC_INVALID_SOCKET); + return socket; +} + +ssize_t +net_recv_intr(struct sc_intr *intr, sc_socket socket, void *buf, size_t len) { + if (!sc_intr_set_socket(intr, socket)) { + // Already interrupted + return -1; + } + + ssize_t r = net_recv(socket, buf, len); + + sc_intr_set_socket(intr, SC_INVALID_SOCKET); + return r; +} + +ssize_t +net_recv_all_intr(struct sc_intr *intr, sc_socket socket, void *buf, + size_t len) { + if (!sc_intr_set_socket(intr, socket)) { + // Already interrupted + return -1; + } + + ssize_t r = net_recv_all(socket, buf, len); + + sc_intr_set_socket(intr, SC_INVALID_SOCKET); + return r; +} + +ssize_t +net_send_intr(struct sc_intr *intr, sc_socket socket, const void *buf, + size_t len) { + if (!sc_intr_set_socket(intr, socket)) { + // Already interrupted + return -1; + } + + ssize_t w = net_send(socket, buf, len); + + sc_intr_set_socket(intr, SC_INVALID_SOCKET); + return w; +} + +ssize_t +net_send_all_intr(struct sc_intr *intr, sc_socket socket, const void *buf, + size_t len) { + if (!sc_intr_set_socket(intr, socket)) { + // Already interrupted + return -1; + } + + ssize_t w = net_send_all(socket, buf, len); + + sc_intr_set_socket(intr, SC_INVALID_SOCKET); + return w; +} diff --git a/app/src/util/net_intr.h b/app/src/util/net_intr.h new file mode 100644 index 00000000..a83fadda --- /dev/null +++ b/app/src/util/net_intr.h @@ -0,0 +1,35 @@ +#ifndef SC_NET_INTR_H +#define SC_NET_INTR_H + +#include "common.h" + +#include "intr.h" +#include "net.h" + +bool +net_connect_intr(struct sc_intr *intr, sc_socket socket, uint32_t addr, + uint16_t port); + +bool +net_listen_intr(struct sc_intr *intr, sc_socket socket, uint32_t addr, + uint16_t port, int backlog); + +sc_socket +net_accept_intr(struct sc_intr *intr, sc_socket server_socket); + +ssize_t +net_recv_intr(struct sc_intr *intr, sc_socket socket, void *buf, size_t len); + +ssize_t +net_recv_all_intr(struct sc_intr *intr, sc_socket socket, void *buf, + size_t len); + +ssize_t +net_send_intr(struct sc_intr *intr, sc_socket socket, const void *buf, + size_t len); + +ssize_t +net_send_all_intr(struct sc_intr *intr, sc_socket socket, const void *buf, + size_t len); + +#endif diff --git a/app/src/util/process_intr.c b/app/src/util/process_intr.c new file mode 100644 index 00000000..bb483123 --- /dev/null +++ b/app/src/util/process_intr.c @@ -0,0 +1,16 @@ +#include "process_intr.h" + +bool +sc_process_check_success_intr(struct sc_intr *intr, sc_pid pid, + const char *name) { + if (!sc_intr_set_process(intr, pid)) { + // Already interrupted + return false; + } + + // Always pass close=false, interrupting would be racy otherwise + bool ret = sc_process_check_success(pid, name, false); + + sc_intr_set_process(intr, SC_PROCESS_NONE); + return ret; +} diff --git a/app/src/util/process_intr.h b/app/src/util/process_intr.h new file mode 100644 index 00000000..ff0dfc76 --- /dev/null +++ b/app/src/util/process_intr.h @@ -0,0 +1,13 @@ +#ifndef SC_PROCESS_INTR_H +#define SC_PROCESS_INTR_H + +#include "common.h" + +#include "intr.h" +#include "process.h" + +bool +sc_process_check_success_intr(struct sc_intr *intr, sc_pid pid, + const char *name); + +#endif