From: Andrei Tatar Date: Wed, 6 Mar 2024 14:42:07 +0000 (+0100) Subject: lib/posix-socket: Add explicitly polled sockets X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=8147a397609bdeb46399d1738197869aa3f0848b;p=unikraft%2Funikraft.git lib/posix-socket: Add explicitly polled sockets 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 Approved-by: Michalis Pappas Reviewed-by: Michalis Pappas GitHub-Closes: #1446 --- diff --git a/lib/posix-socket/Config.uk b/lib/posix-socket/Config.uk index 2f7274133..5b590c32f 100644 --- a/lib/posix-socket/Config.uk +++ b/lib/posix-socket/Config.uk @@ -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 diff --git a/lib/posix-socket/include/uk/socket_driver.h b/lib/posix-socket/include/uk/socket_driver.h index b712b6d36..30fdb542e 100644 --- a/lib/posix-socket/include/uk/socket_driver.h +++ b/lib/posix-socket/include/uk/socket_driver.h @@ -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); } /** diff --git a/lib/posix-socket/socket.c b/lib/posix-socket/socket.c index 641f88834..65189e1c9 100644 --- a/lib/posix-socket/socket.c +++ b/lib/posix-socket/socket.c @@ -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); } diff --git a/lib/posix-unixsocket/unixsock.c b/lib/posix-unixsocket/unixsock.c index 91d3a8113..b279a9b55 100644 --- a/lib/posix-unixsocket/unixsock.c +++ b/lib/posix-unixsocket/unixsock.c @@ -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);