From d2f79c3aed2904570e0a161d2f949f57b4652e3f Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov@tarantool.org> Date: Thu, 11 Nov 2021 15:06:16 +0300 Subject: [PATCH] coio: don't raise in I/O functions There are just a few places outside coio.cc and coio_buf.h where these functions are used directly (most users use helpers from coio_buf.h or xrow_io.h): popen, console, applier. This is a step towards conversion of coio to C. --- src/box/applier.cc | 3 +- src/box/lua/console.c | 3 +- src/box/xrow_io.cc | 3 +- src/lib/core/coio.cc | 94 +++++++++++++++++------------------------ src/lib/core/coio.h | 43 +------------------ src/lib/core/coio_buf.h | 9 ++++ src/lib/core/popen.c | 7 ++- 7 files changed, 56 insertions(+), 106 deletions(-) diff --git a/src/box/applier.cc b/src/box/applier.cc index 0f214d965a..47304820b6 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -350,7 +350,8 @@ applier_connect(struct applier *applier) if (fd < 0) diag_raise(); iostream_create(io, fd); - coio_readn(io, greetingbuf, IPROTO_GREETING_SIZE); + if (coio_readn(io, greetingbuf, IPROTO_GREETING_SIZE) < 0) + diag_raise(); applier->last_row_time = ev_monotonic_now(loop()); /* Decode instance version and name from greeting */ diff --git a/src/box/lua/console.c b/src/box/lua/console.c index bcda392572..eacf086446 100644 --- a/src/box/lua/console.c +++ b/src/box/lua/console.c @@ -576,8 +576,7 @@ console_session_push(struct session *session, struct port *port) return -1; struct iostream io; iostream_create(&io, session_fd(session)); - int ret = coio_write_timeout_noxc(&io, text, text_len, - TIMEOUT_INFINITY); + int ret = coio_write_timeout(&io, text, text_len, TIMEOUT_INFINITY); iostream_destroy(&io); return ret >= 0 ? 0 : -1; } diff --git a/src/box/xrow_io.cc b/src/box/xrow_io.cc index bfe335c9dc..20e3272394 100644 --- a/src/box/xrow_io.cc +++ b/src/box/xrow_io.cc @@ -100,6 +100,7 @@ coio_write_xrow(struct iostream *io, const struct xrow_header *row) { struct iovec iov[XROW_IOVMAX]; int iovcnt = xrow_to_iovec_xc(row, iov); - coio_writev(io, iov, iovcnt, 0); + if (coio_writev(io, iov, iovcnt, 0) < 0) + diag_raise(); } diff --git a/src/lib/core/coio.cc b/src/lib/core/coio.cc index c5f41c17fb..3fde60e866 100644 --- a/src/lib/core/coio.cc +++ b/src/lib/core/coio.cc @@ -258,6 +258,7 @@ coio_accept(int sfd, struct sockaddr *addr, socklen_t addrlen, * Can read up to bufsiz bytes. * * @retval the number of bytes read. + * @retval -1 error. */ ssize_t coio_read_ahead_timeout(struct iostream *io, void *buf, size_t sz, @@ -284,7 +285,7 @@ coio_read_ahead_timeout(struct iostream *io, void *buf, size_t sz, } else if (nrd == 0) { return sz - to_read; } else if (nrd == IOSTREAM_ERROR) { - diag_raise(); + return -1; } /* * Yield control to other fibers until the @@ -292,9 +293,14 @@ coio_read_ahead_timeout(struct iostream *io, void *buf, size_t sz, */ int revents = coio_wait(io->fd, iostream_status_to_events(nrd), delay); - fiber_testcancel(); - if (revents == 0) - tnt_raise(TimedOut); + if (fiber_is_cancelled()) { + diag_set(FiberIsCancelled); + return -1; + } + if (revents == 0) { + diag_set(TimedOut); + return -1; + } coio_timeout_update(&start, &delay); } } @@ -305,15 +311,17 @@ coio_read_ahead_timeout(struct iostream *io, void *buf, size_t sz, * Treats EOF as an error, and throws an exception. * * @retval the number of bytes read, > 0. + * @retval -1 error. */ ssize_t coio_readn_ahead(struct iostream *io, void *buf, size_t sz, size_t bufsiz) { ssize_t nrd = coio_read_ahead(io, buf, sz, bufsiz); - if (nrd < (ssize_t)sz) { + if (nrd >= 0 && nrd < (ssize_t)sz) { errno = EPIPE; - tnt_raise(SocketError, sio_socketname(io->fd), - "unexpected EOF when reading from socket"); + diag_set(SocketError, sio_socketname(io->fd), + "unexpected EOF when reading from socket"); + return -1; } return nrd; } @@ -324,6 +332,7 @@ coio_readn_ahead(struct iostream *io, void *buf, size_t sz, size_t bufsiz) * Treats EOF as an error, and throws an exception. * * @retval the number of bytes read, > 0. + * @retval -1 error. */ ssize_t coio_readn_ahead_timeout(struct iostream *io, void *buf, size_t sz, @@ -332,32 +341,13 @@ coio_readn_ahead_timeout(struct iostream *io, void *buf, size_t sz, ssize_t nrd = coio_read_ahead_timeout(io, buf, sz, bufsiz, timeout); if (nrd >= 0 && nrd < (ssize_t)sz) { /* EOF. */ errno = EPIPE; - tnt_raise(SocketError, sio_socketname(io->fd), - "unexpected EOF when reading from socket"); + diag_set(SocketError, sio_socketname(io->fd), + "unexpected EOF when reading from socket"); + return -1; } return nrd; } -/* - * FIXME: Rewrite coio_read_ahead_timeout() w/o C++ exceptions and - * drop this function. - */ -ssize_t -coio_read_ahead_timeout_noxc(struct iostream *io, void *buf, size_t sz, - size_t bufsiz, ev_tstamp timeout) -{ - try { - return coio_read_ahead_timeout(io, buf, sz, bufsiz, timeout); - } catch (Exception *) { - /* - * The exception is already in the diagnostics - * area. Nothing to do. - */ - } - return -1; -} - - /** * Write sz bytes to socket. * @@ -368,6 +358,7 @@ coio_read_ahead_timeout_noxc(struct iostream *io, void *buf, size_t sz, * * @retval the number of bytes written. Always * equal to @a sz. + * @retval -1 error. */ ssize_t coio_write_timeout(struct iostream *io, const void *buf, size_t sz, @@ -390,7 +381,7 @@ coio_write_timeout(struct iostream *io, const void *buf, size_t sz, buf = (char *) buf + nwr; continue; } else if (nwr == IOSTREAM_ERROR) { - diag_raise(); + return -1; } /* * Yield control to other fibers until the @@ -399,32 +390,18 @@ coio_write_timeout(struct iostream *io, const void *buf, size_t sz, */ int revents = coio_wait(io->fd, iostream_status_to_events(nwr), delay); - fiber_testcancel(); - if (revents == 0) - tnt_raise(TimedOut); + if (fiber_is_cancelled()) { + diag_set(FiberIsCancelled); + return -1; + } + if (revents == 0) { + diag_set(TimedOut); + return -1; + } coio_timeout_update(&start, &delay); } } -/* - * FIXME: Rewrite coio_write_timeout() w/o C++ exceptions and drop - * this function. - */ -ssize_t -coio_write_timeout_noxc(struct iostream *io, const void *buf, size_t sz, - ev_tstamp timeout) -{ - try { - return coio_write_timeout(io, buf, sz, timeout); - } catch (Exception *) { - /* - * The exception is already in the diagnostics - * area. Nothing to do. - */ - } - return -1; -} - /* * Write iov using iostream API. * Put in an own function to workaround gcc bug with @finally @@ -468,7 +445,7 @@ coio_writev_timeout(struct iostream *io, struct iovec *iov, int iovcnt, } continue; } else if (nwr == IOSTREAM_ERROR) { - diag_raise(); + return -1; } /* * Yield control to other fibers until the @@ -477,9 +454,14 @@ coio_writev_timeout(struct iostream *io, struct iovec *iov, int iovcnt, */ int revents = coio_wait(io->fd, iostream_status_to_events(nwr), delay); - fiber_testcancel(); - if (revents == 0) - tnt_raise(TimedOut); + if (fiber_is_cancelled()) { + diag_set(FiberIsCancelled); + return -1; + } + if (revents == 0) { + diag_set(TimedOut); + return -1; + } coio_timeout_update(&start, &delay); } return total; diff --git a/src/lib/core/coio.h b/src/lib/core/coio.h index 3a54289b39..84b741603b 100644 --- a/src/lib/core/coio.h +++ b/src/lib/core/coio.h @@ -92,7 +92,7 @@ coio_timeout_update(ev_tstamp *start, ev_tstamp *delay) /** * Reat at least sz bytes, with readahead. * - * Returns 0 in case of EOF. + * Returns 0 in case of EOF, -1 in case of error. */ static inline ssize_t coio_read_ahead(struct iostream *io, void *buf, size_t sz, size_t bufsiz) @@ -115,29 +115,6 @@ coio_read_timeout(struct iostream *io, void *buf, size_t sz, ev_tstamp timeout) return coio_read_ahead_timeout(io, buf, sz, sz, timeout); } -/** - * Read data with timeout. - * - * Yield until some data will be available for read. - * - * Returns amount of read bytes at success, otherwise returns -1 - * and set a diag. - * - * Zero return value means EOF. - * - * Note: Less then @a count bytes may be available for read at a - * moment, so a return value less then @a count does not mean EOF. - * - * Possible errors: - * - * - SocketError: an IO error occurs at read(). - * - TimedOut: @a timeout quota is exceeded. - * - FiberIsCancelled: cancelled by an outside code. - */ -ssize_t -coio_read_ahead_timeout_noxc(struct iostream *io, void *buf, size_t sz, - size_t bufsiz, ev_tstamp timeout); - static inline ssize_t coio_readn(struct iostream *io, void *buf, size_t sz) { @@ -152,24 +129,6 @@ ssize_t coio_write_timeout(struct iostream *io, const void *buf, size_t sz, ev_tstamp timeout); -/** - * Write @a count bytes with timeout. - * - * Yield until all @a count bytes will be written. - * - * Returns @a count at success, otherwise returns -1 and set a - * diag. - * - * Possible errors: - * - * - SocketError: an IO error occurs at write(). - * - TimedOut: @a timeout quota is exceeded. - * - FiberIsCancelled: cancelled by an outside code. - */ -ssize_t -coio_write_timeout_noxc(struct iostream *io, const void *buf, size_t sz, - ev_tstamp timeout); - static inline void coio_write(struct iostream *io, const void *buf, size_t sz) { diff --git a/src/lib/core/coio_buf.h b/src/lib/core/coio_buf.h index 4a840c974e..fabe54cfc0 100644 --- a/src/lib/core/coio_buf.h +++ b/src/lib/core/coio_buf.h @@ -31,6 +31,7 @@ * SUCH DAMAGE. */ #include "coio.h" +#include "diag.h" #include <small/ibuf.h> struct iostream; @@ -47,6 +48,8 @@ coio_bread(struct iostream *io, struct ibuf *buf, size_t sz) { ibuf_reserve_xc(buf, sz); ssize_t n = coio_read_ahead(io, buf->wpos, sz, ibuf_unused(buf)); + if (n < 0) + diag_raise(); buf->wpos += n; return n; } @@ -63,6 +66,8 @@ coio_bread_timeout(struct iostream *io, struct ibuf *buf, size_t sz, ibuf_reserve_xc(buf, sz); ssize_t n = coio_read_ahead_timeout(io, buf->wpos, sz, ibuf_unused(buf), timeout); + if (n < 0) + diag_raise(); buf->wpos += n; return n; } @@ -73,6 +78,8 @@ coio_breadn(struct iostream *io, struct ibuf *buf, size_t sz) { ibuf_reserve_xc(buf, sz); ssize_t n = coio_readn_ahead(io, buf->wpos, sz, ibuf_unused(buf)); + if (n < 0) + diag_raise(); buf->wpos += n; return n; } @@ -90,6 +97,8 @@ coio_breadn_timeout(struct iostream *io, struct ibuf *buf, size_t sz, ibuf_reserve_xc(buf, sz); ssize_t n = coio_readn_ahead_timeout(io, buf->wpos, sz, ibuf_unused(buf), timeout); + if (n < 0) + diag_raise(); buf->wpos += n; return n; } diff --git a/src/lib/core/popen.c b/src/lib/core/popen.c index 73609b60fc..baf65b7ee6 100644 --- a/src/lib/core/popen.c +++ b/src/lib/core/popen.c @@ -395,8 +395,7 @@ popen_write_timeout(struct popen_handle *handle, const void *buf, handle->pid, stdX_str(idx), idx, buf, count, handle->ios[idx].fd, timeout); - ssize_t rc = coio_write_timeout_noxc(&handle->ios[idx], buf, - count, timeout); + ssize_t rc = coio_write_timeout(&handle->ios[idx], buf, count, timeout); assert(rc < 0 || rc == (ssize_t)count); return rc; } @@ -460,8 +459,8 @@ popen_read_timeout(struct popen_handle *handle, void *buf, handle->pid, stdX_str(idx), idx, buf, count, handle->ios[idx].fd, timeout); - return coio_read_ahead_timeout_noxc(&handle->ios[idx], buf, 1, count, - timeout); + return coio_read_ahead_timeout(&handle->ios[idx], buf, 1, count, + timeout); } /** -- GitLab