pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/39071?usp=email )
Change subject: osmo_io: Track IOFD_FLAG_FD_REGISTERED in all backends ......................................................................
osmo_io: Track IOFD_FLAG_FD_REGISTERED in all backends
This will be used in common segmentation handling code to figure out whether the iofd is still registered or was unregistered by the user during the read cb, in order to know whether to continue submitting read events upwards or to discard the handling.
Change-Id: Id5e92aa22ce1c5d76028c539784118be227b9d5a --- M src/core/osmo_io.c M src/core/osmo_io_poll.c 2 files changed, 21 insertions(+), 15 deletions(-)
Approvals: Jenkins Builder: Verified osmith: Looks good to me, but someone else must approve pespin: Looks good to me, approved fixeria: Looks good to me, but someone else must approve
diff --git a/src/core/osmo_io.c b/src/core/osmo_io.c index 387cefb..c61c8e9 100644 --- a/src/core/osmo_io.c +++ b/src/core/osmo_io.c @@ -737,19 +737,29 @@ { int rc = 0;
- if (fd >= 0) - iofd->fd = fd; - else if (iofd->fd < 0) { + if (fd < 0 && iofd->fd < 0) { /* this might happen if both osmo_iofd_setup() and osmo_iofd_register() are called with -1 */ LOGPIO(iofd, LOGL_ERROR, "Cannot register io_fd using invalid fd == %d\n", iofd->fd); return -EBADF; } + if (fd < 0) + fd = iofd->fd; + else if (iofd->fd < 0) + iofd->fd = fd; + + if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED)) { + /* If re-registering same fd, handle as NO-OP. + * New FD should go through unregister() first. */ + return iofd->fd == fd ? 0 : -ENOTSUP; + }
rc = osmo_iofd_ops.register_fd(iofd); if (rc) return rc;
IOFD_FLAG_UNSET(iofd, IOFD_FLAG_CLOSED); + IOFD_FLAG_SET(iofd, IOFD_FLAG_FD_REGISTERED); + if ((iofd->mode == OSMO_IO_FD_MODE_READ_WRITE && iofd->io_ops.read_cb) || (iofd->mode == OSMO_IO_FD_MODE_RECVFROM_SENDTO && iofd->io_ops.recvfrom_cb) || (iofd->mode == OSMO_IO_FD_MODE_RECVMSG_SENDMSG && iofd->io_ops.recvmsg_cb)) { @@ -772,7 +782,14 @@ */ int osmo_iofd_unregister(struct osmo_io_fd *iofd) { - return osmo_iofd_ops.unregister_fd(iofd); + int rc; + + if (!IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED)) + return 0; + + rc = osmo_iofd_ops.unregister_fd(iofd); + IOFD_FLAG_UNSET(iofd, IOFD_FLAG_FD_REGISTERED); + return rc; }
/*! Retrieve the number of messages pending in the transmit queue. diff --git a/src/core/osmo_io_poll.c b/src/core/osmo_io_poll.c index 92f03f8..bf0291e 100644 --- a/src/core/osmo_io_poll.c +++ b/src/core/osmo_io_poll.c @@ -128,29 +128,18 @@ struct osmo_fd *ofd = &iofd->u.poll.ofd; int rc;
- if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED)) - return 0; - osmo_fd_setup(ofd, iofd->fd, 0, &iofd_poll_ofd_cb_dispatch, iofd, 0); if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED)) osmo_fd_write_enable(&iofd->u.poll.ofd);
rc = osmo_fd_register(ofd); - if (!rc) - IOFD_FLAG_SET(iofd, IOFD_FLAG_FD_REGISTERED); - return rc; }
static int iofd_poll_unregister(struct osmo_io_fd *iofd) { struct osmo_fd *ofd = &iofd->u.poll.ofd; - - if (!IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED)) - return 0; osmo_fd_unregister(ofd); - IOFD_FLAG_UNSET(iofd, IOFD_FLAG_FD_REGISTERED); - return 0; }