mirror of https://gerrit.osmocom.org/libosmocore
osmo_io: Add iofd param to segmentation_cb
See related ticket for full rant and historical facts about this callback. Since anyway we are still developing osmo_io stuff and there will be ABI breaks when releasing new version, let's udpate the callback signature too. Related: OS#6437 Change-Id: Ib8d77e30b1ea759ee5ac2a69d704e81ea71e3079
This commit is contained in:
parent
dafdb1181b
commit
99750d5cae
|
@ -100,6 +100,7 @@ struct osmo_io_ops {
|
|||
* \param[in] msg message buffer containing the read data. Ownership is transferred to the
|
||||
* call-back, and it must make sure to msgb_free() it eventually! */
|
||||
void (*read_cb)(struct osmo_io_fd *iofd, int res, struct msgb *msg);
|
||||
|
||||
/*! completion call-back function when write issued via osmo_iofd_write_msgb() has completed
|
||||
* on fd. Only valid in OSMO_IO_FD_MODE_READ_WRITE.
|
||||
* \param[in] iofd on which a write() has completed.
|
||||
|
@ -108,9 +109,14 @@ struct osmo_io_ops {
|
|||
* call-back; it is automatically freed after the call-back terminates! */
|
||||
void (*write_cb)(struct osmo_io_fd *iofd, int res,
|
||||
struct msgb *msg);
|
||||
/*! optional call-back function to segment the data at message boundaries. This is useful when
|
||||
* message boundaries are to be preserved over a SOCK_STREAM transport socket like TCP. Can
|
||||
* be NULL for any application not requiring de-segmentation of received data.
|
||||
|
||||
/*! optional call-back function to segment the data at message boundaries.
|
||||
* \param[in] msg message buffer whose data is to be segmented
|
||||
* \returns See full function description.
|
||||
*
|
||||
* This is useful when message boundaries are to be preserved over a SOCK_STREAM transport
|
||||
* socket like TCP. Can be NULL for any application not requiring de-segmentation of
|
||||
* received data.
|
||||
*
|
||||
* The call-back needs to return the size of the next message. If it returns
|
||||
* -EAGAIN or a value larger than msgb_length() (message is incomplete)
|
||||
|
@ -119,8 +125,26 @@ struct osmo_io_ops {
|
|||
* 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). */
|
||||
* (e.g. setting lxh or msgb->cb).
|
||||
*
|
||||
* Only one (or none) of both segmentation_cb and segmentation_cb2 shall be set.
|
||||
* Having both set will be considered an error during iofd setup. */
|
||||
int (*segmentation_cb)(struct msgb *msg);
|
||||
|
||||
/*! optional call-back function to segment the data at message boundaries.
|
||||
* \param[in] iofd handling msg
|
||||
* \param[in] msg message buffer whose data is to be segmented
|
||||
* \returns See full function description.
|
||||
*
|
||||
* Same as segmentation_cb above, with an extra parameter to have access to the iofd and its
|
||||
* related functionalities (eg data pointer). This is useful for users requiring to store
|
||||
* global state or access external objects while segmenting.
|
||||
*
|
||||
* The provided iofd shall not be freed by the user during the callback.
|
||||
*
|
||||
* Only one (or none) of both segmentation_cb and segmentation_cb2 shall be set.
|
||||
* Having both set will be considered an error during iofd setup. */
|
||||
int (*segmentation_cb2)(struct osmo_io_fd *iofd, struct msgb *msg);
|
||||
};
|
||||
|
||||
/* mode OSMO_IO_FD_MODE_RECVFROM_SENDTO: */
|
||||
|
|
|
@ -267,7 +267,7 @@ struct iofd_msghdr *iofd_txqueue_dequeue(struct osmo_io_fd *iofd)
|
|||
*/
|
||||
static enum iofd_seg_act iofd_handle_segmentation(struct osmo_io_fd *iofd, struct msgb *msg, struct msgb **pending_out)
|
||||
{
|
||||
int extra_len, received_len;
|
||||
int extra_len, received_len, expected_len;
|
||||
struct msgb *msg_pending;
|
||||
|
||||
/* Save the start of message before segmentation_cb (which could change it) */
|
||||
|
@ -275,12 +275,15 @@ static enum iofd_seg_act iofd_handle_segmentation(struct osmo_io_fd *iofd, struc
|
|||
|
||||
received_len = msgb_length(msg);
|
||||
|
||||
if (!iofd->io_ops.segmentation_cb) {
|
||||
if (iofd->io_ops.segmentation_cb2) {
|
||||
expected_len = iofd->io_ops.segmentation_cb2(iofd, msg);
|
||||
} else if (iofd->io_ops.segmentation_cb) {
|
||||
expected_len = iofd->io_ops.segmentation_cb(msg);
|
||||
} else {
|
||||
*pending_out = NULL;
|
||||
return IOFD_SEG_ACT_HANDLE_ONE;
|
||||
}
|
||||
|
||||
int expected_len = iofd->io_ops.segmentation_cb(msg);
|
||||
if (expected_len == -EAGAIN) {
|
||||
goto defer;
|
||||
} else if (expected_len < 0) {
|
||||
|
@ -599,6 +602,9 @@ static int check_mode_callback_compat(enum osmo_io_fd_mode mode, const struct os
|
|||
return false;
|
||||
if (ops->recvmsg_cb || ops->sendmsg_cb)
|
||||
return false;
|
||||
/* Forbid both segementation_cb set, something is wrong: */
|
||||
if (ops->segmentation_cb && ops->segmentation_cb2)
|
||||
return false;
|
||||
break;
|
||||
case OSMO_IO_FD_MODE_RECVFROM_SENDTO:
|
||||
if (ops->read_cb || ops->write_cb)
|
||||
|
|
Loading…
Reference in New Issue