laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/libosmocore/+/35910?usp=email )

 (

8 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted 
one.
 )Change subject: osmo_io: Use poll/select to notify socket connection at 
osmo_io_uring.c
......................................................................

osmo_io: Use poll/select to notify socket connection at osmo_io_uring.c

In order to receive a connect notification from SCTP socket,
poll/select event must be used instead of a write notification via
io_uring completion event.

Once the connect notification has been received, subsequent write
notifications via io_uring are used.

Change-Id: I4eca9ea72beb0d6ea4d44cce81ed620033f07270
Related: OS#5751
---
M src/core/osmo_io_internal.h
M src/core/osmo_io_uring.c
2 files changed, 93 insertions(+), 1 deletion(-)

Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified




diff --git a/src/core/osmo_io_internal.h b/src/core/osmo_io_internal.h
index af47a3d..a4b0749 100644
--- a/src/core/osmo_io_internal.h
+++ b/src/core/osmo_io_internal.h
@@ -104,6 +104,8 @@
                        void *read_msghdr;
                        void *write_msghdr;
                        /* TODO: index into array of registered fd's? */
+                       /* osmo_fd for non-blocking connect handling */
+                       struct osmo_fd connect_ofd;
                } uring;
        } u;
 };
diff --git a/src/core/osmo_io_uring.c b/src/core/osmo_io_uring.c
index aa9df85..af1c790 100644
--- a/src/core/osmo_io_uring.c
+++ b/src/core/osmo_io_uring.c
@@ -324,6 +324,11 @@
        }
        io_uring_submit(&g_ring.ring);

+       if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED)) {
+               osmo_fd_unregister(&iofd->u.uring.connect_ofd);
+               IOFD_FLAG_UNSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED);
+       }
+
        return 0;
 }

@@ -334,6 +339,10 @@
        if (iofd->u.uring.write_msghdr)
                return;

+       /* This function is called again, once the socket is connected. */
+       if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED))
+               return;
+
        if (osmo_iofd_txqueue_len(iofd) > 0)
                iofd_uring_submit_tx(iofd);
        else if (iofd->mode == OSMO_IO_FD_MODE_READ_WRITE) {
@@ -379,6 +388,10 @@
        if (iofd->u.uring.read_msghdr)
                return;

+       /* This function is called again, once the socket is connected. */
+       if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED))
+               return;
+
        switch (iofd->mode) {
        case OSMO_IO_FD_MODE_READ_WRITE:
                iofd_uring_submit_recv(iofd, IOFD_ACT_READ);
@@ -407,6 +420,66 @@
        return close(iofd->fd);
 }

+/* called via osmocom poll/select main handling once outbound non-blocking 
connect() completes */
+static int iofd_uring_connected_cb(struct osmo_fd *ofd, unsigned int what)
+{
+       struct osmo_io_fd *iofd = ofd->data;
+
+       LOGPIO(iofd, LOGL_DEBUG, "Socket connected or failed.");
+
+       if (!(what & OSMO_FD_WRITE))
+               return 0;
+
+       /* Unregister from poll/select handling. */
+       osmo_fd_unregister(ofd);
+       IOFD_FLAG_UNSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED);
+
+       /* Notify the application about this via a zero-length write completion 
call-back. */
+       IOFD_FLAG_SET(iofd, IOFD_FLAG_IN_CALLBACK);
+       switch (iofd->mode) {
+       case OSMO_IO_FD_MODE_READ_WRITE:
+               iofd->io_ops.write_cb(iofd, 0, NULL);
+               break;
+       case OSMO_IO_FD_MODE_RECVFROM_SENDTO:
+               iofd->io_ops.sendto_cb(iofd, 0, NULL, NULL);
+               break;
+       case OSMO_IO_FD_MODE_RECVMSG_SENDMSG:
+               iofd->io_ops.sendmsg_cb(iofd, 0, NULL);
+               break;
+       }
+       IOFD_FLAG_UNSET(iofd, IOFD_FLAG_IN_CALLBACK);
+
+       /* If write/read notifications are pending, enable it now. */
+       if (iofd->u.uring.write_enabled && !IOFD_FLAG_ISSET(iofd, 
IOFD_FLAG_CLOSED))
+               iofd_uring_write_enable(iofd);
+       if (iofd->u.uring.read_enabled && !IOFD_FLAG_ISSET(iofd, 
IOFD_FLAG_CLOSED))
+               iofd_uring_read_enable(iofd);
+
+       if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_TO_FREE) && 
!iofd->u.uring.read_msghdr && !iofd->u.uring.write_msghdr)
+               talloc_free(iofd);
+       return 0;
+}
+
+static void iofd_uring_notify_connected(struct osmo_io_fd *iofd)
+{
+       if (iofd->mode == OSMO_IO_FD_MODE_RECVMSG_SENDMSG) {
+               /* Don't call this function after enabling read or write. */
+               OSMO_ASSERT(!iofd->u.uring.write_enabled && 
!iofd->u.uring.read_enabled);
+
+               /* Use a temporary osmo_fd which we can use to notify us once 
the connection is established
+                * or failed (indicated by FD becoming writable).
+                * This is needed as (at least for SCTP sockets) one cannot 
submit a zero-length writev/sendmsg
+                * in order to get notification when the socekt is writable.*/
+               if (!IOFD_FLAG_ISSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED)) {
+                       osmo_fd_setup(&iofd->u.uring.connect_ofd, iofd->fd, 
OSMO_FD_WRITE,
+                                     iofd_uring_connected_cb, iofd, 0);
+                       osmo_fd_register(&iofd->u.uring.connect_ofd);
+                       IOFD_FLAG_SET(iofd, IOFD_FLAG_NOTIFY_CONNECTED);
+               }
+       } else
+               iofd_uring_write_enable(iofd);
+}
+
 const struct iofd_backend_ops iofd_uring_ops = {
        .register_fd = iofd_uring_register,
        .unregister_fd = iofd_uring_unregister,
@@ -415,7 +488,7 @@
        .write_disable = iofd_uring_write_disable,
        .read_enable = iofd_uring_read_enable,
        .read_disable = iofd_uring_read_disable,
-       .notify_connected = iofd_uring_write_enable,
+       .notify_connected = iofd_uring_notify_connected,
 };

 #endif /* defined(__linux__) */

--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35910?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I4eca9ea72beb0d6ea4d44cce81ed620033f07270
Gerrit-Change-Number: 35910
Gerrit-PatchSet: 9
Gerrit-Owner: jolly <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-MessageType: merged

Reply via email to