]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/posix-socket: Add explicitly polled sockets
authorAndrei Tatar <andrei@unikraft.io>
Wed, 6 Mar 2024 14:42:07 +0000 (15:42 +0100)
committerUnikraft Bot <monkey@unikraft.io>
Fri, 14 Feb 2025 02:16:14 +0000 (02:16 +0000)
This change adds support for socket drivers that maintain events
internally and provide an explicit callback for fetching current events.

This contains breaking API changes.

Signed-off-by: Andrei Tatar <andrei@unikraft.io>
Approved-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
GitHub-Closes: #1446

lib/posix-socket/Config.uk
lib/posix-socket/include/uk/socket_driver.h
lib/posix-socket/socket.c
lib/posix-unixsocket/unixsock.c

index 2f7274133cc595f321e57ef091299a5454304c3b..5b590c32f991a3b5ccdefa5b72d7a1c52ba26541 100644 (file)
@@ -31,4 +31,10 @@ config LIBPOSIX_SOCKET_EVENTS
                - ACCEPT: An incoming connection request is accepted
                - CONNECT: A connection to a remote endpoint is established
                - CLOSE: A connection or listener is closed
+
+# Hidden; enabled by components when required
+config LIBPOSIX_SOCKET_POLLED
+       bool
+       select LIBUKFILE_POLLED
+
 endif
index b712b6d36f3aa63bee56c8764a6e1de2463f2057..30fdb542ed1a817a559cc7c1f3bec1f4acf69fba 100644 (file)
@@ -435,15 +435,35 @@ typedef int (*posix_socket_ioctl_func_t)(posix_sock *sock,
                int request, void *argp);
 
 /**
- * Poll the socket, updating `sock` with the currently set events.
+ * (OPTIONAL) Retrieve the events in `mask` on socket `sock`.
+ *
+ * Enabled with LIBPOSIX_SOCKET_POLLED.
+ *
+ * Drivers need not provide this callback.
+ * If the driver does not provide the poll callback, it is responsible for
+ * notifying the rising and falling edges of events in line with I/O operations
+ * using the `posix_socket_event_*` functions.
+ * If the driver provides the poll callback it must only notify rising edges
+ * of events using `posix_socket_event_set`.
+ *
+ * @param sock Reference to the socket
+ * @param mask Bitmask of events to be retrieved
+ *
+ * @return Bitwise AND of events on `sock` and those in `mask`
+ */
+typedef unsigned int (*posix_socket_poll_func_t)(posix_sock *sock,
+                                                unsigned int mask);
+
+/**
  * This is guaranteed to be called exactly once on initialization,
  * allowing the driver to set up any data structures required by callbacks.
- * The driver from that point responsible for updating the events on every
- * operation using the `posix_socket_event_*` functions.
+ * If the driver does not provide the poll callback, it must update the socket
+ * state with the current events.
+ * After this function returns, the driver is responsible for notifying events.
  *
  * @param sock Reference to the socket
  */
-typedef void (*posix_socket_poll_func_t)(posix_sock *sock);
+typedef void (*posix_socket_poll_setup_func_t)(posix_sock *sock);
 
 /**
  * A structure containing the functions exported by a Unikraft socket driver
@@ -473,7 +493,10 @@ struct posix_socket_ops {
        posix_socket_read_func_t        read;
        posix_socket_close_func_t       close;
        posix_socket_ioctl_func_t       ioctl;
+#if CONFIG_LIBPOSIX_SOCKET_POLLED
        posix_socket_poll_func_t        poll;
+#endif /* CONFIG_LIBPOSIX_SOCKET_POLLED */
+       posix_socket_poll_setup_func_t  poll_setup;
 };
 
 static inline void *
@@ -676,13 +699,26 @@ posix_socket_ioctl(posix_sock *sock, int request, void *argp)
        return d->ops->ioctl(sock, request, argp);
 }
 
+#if CONFIG_LIBPOSIX_SOCKET_POLLED
+static inline unsigned int
+posix_socket_poll(posix_sock *sock, unsigned int mask)
+{
+       struct posix_socket_driver *d = posix_sock_get_driver(sock);
+
+       if (d->ops->poll)
+               return d->ops->poll(sock, mask);
+       else
+               return 0;
+}
+#endif /* CONFIG_LIBPOSIX_SOCKET_POLLED */
+
 static inline void
-posix_socket_poll(posix_sock *sock)
+posix_socket_poll_setup(posix_sock *sock)
 {
        struct posix_socket_driver *d = posix_sock_get_driver(sock);
 
-       UK_ASSERT(d->ops->poll);
-       d->ops->poll(sock);
+       UK_ASSERT(d->ops->poll_setup);
+       d->ops->poll_setup(sock);
 }
 
 /**
index 641f88834a17efb1e806c569a0956aed9103754f..65189e1c99915cf0fe95a89a34c3354f76819553 100644 (file)
@@ -232,7 +232,13 @@ static void _socket_init(struct socket_alloc *al,
                .sock_data = sock_data,
                .driver = d
        };
-       al->fstate = UK_FILE_STATE_INIT_VALUE(al->fstate);
+#if CONFIG_LIBPOSIX_SOCKET_POLLED
+       if (d->ops->poll)
+               al->fstate = UK_FILE_POLLED_STATE_INIT_VALUE(al->fstate,
+                                                            d->ops->poll);
+       else
+#endif /* CONFIG_LIBPOSIX_SOCKET_POLLED */
+               al->fstate = UK_FILE_STATE_INIT_VALUE(al->fstate);
        al->fref = UK_FILE_REFCNT_INIT_VALUE(al->fref);
        al->f = (struct uk_file){
                .vol = POSIX_SOCKET_VOLID,
@@ -242,7 +248,7 @@ static void _socket_init(struct socket_alloc *al,
                .state = &al->fstate,
                ._release = socket_release
        };
-       posix_socket_poll(&al->f);
+       posix_socket_poll_setup(&al->f);
 }
 
 
index 91d3a81137b9d0e286e81acb5087c398e32561cd..b279a9b55d8a7ef36cb37437fae6c176b0c09daf 100644 (file)
@@ -230,7 +230,7 @@ void *unix_socket_create(struct posix_socket_driver *d,
 }
 
 static
-void unix_socket_poll(posix_sock *file)
+void unix_socket_poll_setup(posix_sock *file)
 {
        struct unix_sock_data *data = posix_sock_get_data(file);
        struct uk_pollq *sockq = &file->state->pollq;
@@ -628,7 +628,7 @@ int unix_sock_connect_stream(posix_sock *file, posix_sock *target)
        data->remote = target;
        data->flags |= UNIXSOCK_CONN;
        /* Poll self (to register events & mark connected) */
-       unix_socket_poll(file);
+       unix_socket_poll_setup(file);
 
        return 0;
 
@@ -1032,7 +1032,7 @@ static struct posix_socket_ops unix_posix_socket_ops = {
        .write          = unix_socket_write,
        .close          = unix_socket_close,
        .ioctl          = unix_socket_ioctl,
-       .poll           = unix_socket_poll,
+       .poll_setup     = unix_socket_poll_setup,
 };
 
 POSIX_SOCKET_FAMILY_REGISTER(AF_UNIX, &unix_posix_socket_ops);