daniel has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/35079?usp=email )
Change subject: osmo_io: Remove union in struct osmo_io_ops ......................................................................
osmo_io: Remove union in struct osmo_io_ops
This allows us to check that the correct callbacks are set and log an error or assert otherwise.
Change-Id: I138d57843edc29000530bb7896bcb239002ecbec Related: #OS6263 --- M TODO-RELEASE M include/osmocom/core/osmo_io.h M src/core/osmo_io.c 3 files changed, 57 insertions(+), 32 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/79/35079/1
diff --git a/TODO-RELEASE b/TODO-RELEASE index b67161d..5e7a00c 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -9,3 +9,4 @@ #library what description / commit summary line core ADD osmo_sock_multiaddr_{add,del}_local_addr() core ADD gsmtap_inst_fd2() core, DEPRECATE gsmtap_inst_fd() +core MODIFY remove union from struct osmo_io_ops diff --git a/include/osmocom/core/osmo_io.h b/include/osmocom/core/osmo_io.h index b3d248f..8433e1b 100644 --- a/include/osmocom/core/osmo_io.h +++ b/include/osmocom/core/osmo_io.h @@ -35,38 +35,33 @@ { return get_value_string(osmo_io_backend_names, val); }
struct osmo_io_ops { - union { - /* mode OSMO_IO_FD_MODE_READ_WRITE: */ - struct { - /*! call-back function when something was read from fd */ - void (*read_cb)(struct osmo_io_fd *iofd, int res, struct msgb *msg); - /*! call-back function when write has completed on fd */ - void (*write_cb)(struct osmo_io_fd *iofd, int res, - struct msgb *msg); - /*! call-back function to segment the data at message boundaries. - * Needs to return the size of the next message. If it returns - * -EAGAIN or a value larger than msgb_length() (message is incomplete) - * osmo_io will wait for more data to be read. Other negative values - * cause the msg to be discarded. - * If a full message was received (segmentation_cb() returns a value <= msgb_length()) - * the msgb will be trimmed to size by osmo_io and forwarded to the read call-back. Any - * parsing done to the msgb by segmentation_cb() will be preserved for the read_cb() - * (e.g. setting lxh or msgb->cb). */ - int (*segmentation_cb)(struct msgb *msg); - }; + /* mode OSMO_IO_FD_MODE_READ_WRITE: */ + /*! call-back function when something was read from fd */ + void (*read_cb)(struct osmo_io_fd *iofd, int res, struct msgb *msg); + /*! call-back function when write has completed on fd */ + void (*write_cb)(struct osmo_io_fd *iofd, int res, + struct msgb *msg); + /*! call-back function to segment the data at message boundaries. + * Needs to return the size of the next message. If it returns + * -EAGAIN or a value larger than msgb_length() (message is incomplete) + * osmo_io will wait for more data to be read. Other negative values + * cause the msg to be discarded. + * If a full message was received (segmentation_cb() returns a value <= msgb_length()) + * the msgb will be trimmed to size by osmo_io and forwarded to the read call-back. Any + * parsing done to the msgb by segmentation_cb() will be preserved for the read_cb() + * (e.g. setting lxh or msgb->cb). */ + int (*segmentation_cb)(struct msgb *msg);
- /* mode OSMO_IO_FD_MODE_RECVFROM_SENDTO: */ - struct { - /*! call-back function emulating recvfrom */ - void (*recvfrom_cb)(struct osmo_io_fd *iofd, int res, - struct msgb *msg, - const struct osmo_sockaddr *saddr); - /*! call-back function emulating sendto */ - void (*sendto_cb)(struct osmo_io_fd *iofd, int res, - struct msgb *msg, - const struct osmo_sockaddr *daddr); - }; - }; + /* mode OSMO_IO_FD_MODE_RECVFROM_SENDTO: */ + /*! call-back function emulating recvfrom */ + void (*recvfrom_cb)(struct osmo_io_fd *iofd, int res, + struct msgb *msg, + const struct osmo_sockaddr *saddr); + /*! call-back function emulating sendto */ + void (*sendto_cb)(struct osmo_io_fd *iofd, int res, + struct msgb *msg, + const struct osmo_sockaddr *daddr); + };
void osmo_iofd_init(void); diff --git a/src/core/osmo_io.c b/src/core/osmo_io.c index 68c7233..8a36628 100644 --- a/src/core/osmo_io.c +++ b/src/core/osmo_io.c @@ -462,6 +462,18 @@ return 0; }
+bool iofd_verify_ioops(const struct osmo_io_fd *iofd, const struct osmo_io_ops *ops) { + switch (iofd->mode) { + case OSMO_IO_FD_MODE_READ_WRITE: + return ops->read_cb || ops->write_cb; + case OSMO_IO_FD_MODE_RECVFROM_SENDTO: + return ops->recvfrom_cb || ops->sendto_cb; + case OSMO_IO_FD_MODE_SCTP_RECVMSG_SENDMSG: + default: + return false; + } +} + /*! Allocate and setup a new iofd. * \param[in] ctx the parent context from which to allocate * \param[in] fd the underlying system file descriptor @@ -485,8 +497,10 @@ if (name) iofd->name = talloc_strdup(iofd, name);
- if (ioops) + if (ioops) { + OSMO_ASSERT(iofd_verify_ioops(iofd, ioops)); iofd->io_ops = *ioops; + }
iofd->pending = NULL;
@@ -702,6 +716,8 @@ * \param[in] ioops osmo_io_ops structure to be set */ void osmo_iofd_set_ioops(struct osmo_io_fd *iofd, const struct osmo_io_ops *ioops) { + OSMO_ASSERT(iofd_verify_ioops(iofd, ioops)); + iofd->io_ops = *ioops;
switch (iofd->mode) {