daniel has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/35078?usp=email )
Change subject: osmo_io: Factor out and use common send function from backend ......................................................................
osmo_io: Factor out and use common send function from backend
This handles reenqueuing a message on EAGAIN and incomplete write
Change-Id: I6da2653d32aedd0e7872be0cf90a841b56462e59 --- M src/core/osmo_io.c M src/core/osmo_io_internal.h M src/core/osmo_io_poll.c M src/core/osmo_io_uring.c 4 files changed, 50 insertions(+), 57 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/35078/1
diff --git a/src/core/osmo_io.c b/src/core/osmo_io.c index f23986f..68c7233 100644 --- a/src/core/osmo_io.c +++ b/src/core/osmo_io.c @@ -340,6 +340,39 @@ } }
+void iofd_handle_send(struct osmo_io_fd *iofd, int rc, struct iofd_msghdr *msghdr) +{ + struct msgb *msg = msghdr->msg; + + /* Incomplete write */ + if (rc > 0 && rc < msgb_length(msg)) { + /* Re-enqueue remaining data */ + msgb_pull(msg, rc); + msghdr->iov[0].iov_len = msgb_length(msg); + iofd_txqueue_enqueue_front(iofd, msghdr); + return; + } + + if (rc == -EAGAIN) { + iofd_txqueue_enqueue_front(iofd, msghdr); + return; + } + + switch (msghdr->action) { + case IOFD_ACT_WRITE: + iofd->io_ops.write_cb(iofd, rc, msg); + break; + case IOFD_ACT_SENDTO: + iofd->io_ops.sendto_cb(iofd, rc, msg, &msghdr->osa); + break; + default: + OSMO_ASSERT(0); + } + + msgb_free(msghdr->msg); + iofd_msghdr_free(msghdr); +} + /* Public functions */
/*! Send a message through a connected socket. diff --git a/src/core/osmo_io_internal.h b/src/core/osmo_io_internal.h index 5b7ab90..359dc3e 100644 --- a/src/core/osmo_io_internal.h +++ b/src/core/osmo_io_internal.h @@ -138,6 +138,7 @@ struct msgb *iofd_msgb_pending_or_alloc(struct osmo_io_fd *iofd);
void iofd_handle_recv(struct osmo_io_fd *iofd, struct msgb *msg, int rc, struct iofd_msghdr *msghdr); +void iofd_handle_send(struct osmo_io_fd *iofd, int rc, struct iofd_msghdr *msghdr); void iofd_handle_segmented_read(struct osmo_io_fd *iofd, struct msgb *msg, int rc);
int iofd_txqueue_enqueue(struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr); diff --git a/src/core/osmo_io_poll.c b/src/core/osmo_io_poll.c index a9aaea4..a211ce7 100644 --- a/src/core/osmo_io_poll.c +++ b/src/core/osmo_io_poll.c @@ -78,33 +78,8 @@ if (what & OSMO_FD_WRITE) { struct iofd_msghdr *msghdr = iofd_txqueue_dequeue(iofd); if (msghdr) { - msg = msghdr->msg; - rc = sendmsg(ofd->fd, &msghdr->hdr, msghdr->flags); - if (rc > 0 && rc < msgb_length(msg)) { - msgb_pull(msg, rc); - iofd_txqueue_enqueue_front(iofd, msghdr); - return; - } - if (rc == -EAGAIN) { - iofd_txqueue_enqueue_front(iofd, msghdr); - return; - } - - switch (iofd->mode) { - case OSMO_IO_FD_MODE_READ_WRITE: - iofd->io_ops.write_cb(iofd, rc, msg); - break; - case OSMO_IO_FD_MODE_RECVFROM_SENDTO: - iofd->io_ops.sendto_cb(iofd, rc, msg, &msghdr->osa); - break; - case OSMO_IO_FD_MODE_SCTP_RECVMSG_SENDMSG: - OSMO_ASSERT(false); - break; - } - - talloc_free(msghdr); - msgb_free(msg); + iofd_handle_send(iofd, rc, msghdr); } else { if (iofd->mode == OSMO_IO_FD_MODE_READ_WRITE) /* Socket is writable, but we have no data to send. A non-blocking/async diff --git a/src/core/osmo_io_uring.c b/src/core/osmo_io_uring.c index a6395fe..c35bc29 100644 --- a/src/core/osmo_io_uring.c +++ b/src/core/osmo_io_uring.c @@ -182,41 +182,14 @@ static void iofd_uring_handle_tx(struct iofd_msghdr *msghdr, int rc) { struct osmo_io_fd *iofd = msghdr->iofd; - struct msgb *msg = msghdr->msg;
- if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_CLOSED)) - goto out_free; - - /* Error during write */ - if (rc < 0) { - if (msghdr->action == IOFD_ACT_WRITE) - iofd->io_ops.write_cb(iofd, rc, msg); - else if (msghdr->action == IOFD_ACT_SENDTO) - iofd->io_ops.sendto_cb(iofd, rc, msg, &msghdr->osa); - else - OSMO_ASSERT(0); - goto out_free; - } - - /* Incomplete write */ - if (rc < msgb_length(msg)) { - /* Re-enqueue remaining data */ - msgb_pull(msg, rc); - msghdr->iov[0].iov_len = msgb_length(msg); - iofd_txqueue_enqueue_front(iofd, msghdr); + if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_CLOSED)) { + msgb_free(msghdr->msg); + iofd_msghdr_free(msghdr); goto out; }
- if (msghdr->action == IOFD_ACT_WRITE) - iofd->io_ops.write_cb(iofd, rc, msg); - else if (msghdr->action == IOFD_ACT_SENDTO) - iofd->io_ops.sendto_cb(iofd, rc, msg, &msghdr->osa); - else - OSMO_ASSERT(0); - -out_free: - msgb_free(msghdr->msg); - iofd_msghdr_free(msghdr); + iofd_handle_send(iofd, rc, msghdr);
out: iofd->u.uring.write_msghdr = NULL;