pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/41914?usp=email )
Change subject: osmo_io: Propagate segment_cb errors to the read_cb ......................................................................
osmo_io: Propagate segment_cb errors to the read_cb
Change-Id: I572e68df6799b903507229a9beee6fa7d7d6d652 --- M src/core/osmo_io.c 1 file changed, 19 insertions(+), 12 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/14/41914/1
diff --git a/src/core/osmo_io.c b/src/core/osmo_io.c index 5805970..d1cdb8e 100644 --- a/src/core/osmo_io.c +++ b/src/core/osmo_io.c @@ -297,8 +297,11 @@ }
/*! Handle segmentation of the msg. If this function returns *_HANDLE_ONE or MORE then the data in msg will contain - * one complete message. - * If there are bytes left over, *pending_out will point to a msgb with the remaining data. + * one complete message. + * If there are bytes left over, *pending_out will point to a msgb with the remaining data. + * Upon IOFD_SEG_ACT_DEFER is returned, errno is set to error value providing reason: + * EAGAIN is returned when data is still missing to fill the segment; other error codes are + * propagated through read_cb(). */ static enum iofd_seg_act iofd_handle_segmentation(struct osmo_io_fd *iofd, struct msgb *msg, struct msgb **pending_out) { @@ -319,15 +322,12 @@ return IOFD_SEG_ACT_HANDLE_ONE; }
- if (expected_len == -EAGAIN) { + if (expected_len < 0) { + if (expected_len != -EAGAIN) + LOGPIO(iofd, LOGL_ERROR, "segmentation_cb returned error (%d), skipping msg of size %d\n", + expected_len, received_len); + errno = -expected_len; goto defer; - } else if (expected_len < 0) { - /* Something is wrong, skip this msgb */ - LOGPIO(iofd, LOGL_ERROR, "segmentation_cb returned error (%d), skipping msg of size %d\n", - expected_len, received_len); - *pending_out = NULL; - msgb_free(msg); - return IOFD_SEG_ACT_DEFER; }
extra_len = received_len - expected_len; @@ -335,8 +335,11 @@ if (extra_len == 0) { *pending_out = NULL; return IOFD_SEG_ACT_HANDLE_ONE; + } + /* segment is incomplete */ - } else if (extra_len < 0) { + if (extra_len < 0) { + errno = EAGAIN; goto defer; }
@@ -455,7 +458,11 @@ if (!IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED)) return;
- } else { + } else { /* IOFD_SEG_ACT_DEFER */ + if (OSMO_UNLIKELY(errno != EAGAIN)) { + _call_read_cb(iofd, -errno, msg); + return; + } if (OSMO_UNLIKELY(msgb_length(msg) == iofd_msgb_length_max(iofd))) { LOGPIO(iofd, LOGL_ERROR, "Rx segment msgb of > %" PRIu16 " bytes (headroom %u bytes) is unsupported, check your segment_cb!\n",