diff --git a/src/coio.cc b/src/coio.cc index 48fca73e42246acf6205c6a595c8113fb4476de5..09a3f18cf29adde151fe5cf4f81e424dd6d67cba 100644 --- a/src/coio.cc +++ b/src/coio.cc @@ -442,13 +442,14 @@ coio_flush(int fd, struct iovec *iov, ssize_t offset, int iovcnt) } ssize_t -coio_writev(struct ev_io *coio, struct iovec *iov, int iovcnt, - size_t size_hint) +coio_writev_timeout(struct ev_io *coio, struct iovec *iov, int iovcnt, + size_t size_hint, ev_tstamp timeout) { ssize_t total = 0; size_t iov_len = 0; struct iovec *end = iov + iovcnt; - + ev_tstamp start, delay; + coio_timeout_init(&start, &delay, timeout); CoioGuard coio_guard(coio); /* Avoid a syscall in case of 0 iovcnt. */ @@ -476,8 +477,20 @@ coio_writev(struct ev_io *coio, struct iovec *iov, int iovcnt, ev_io_start(loop(), coio); } /* Yield control to other fibers. */ - coio_fiber_yield(coio); fiber_testcancel(); + /* + * Yield control to other fibers until the + * timeout is reached or the socket is + * ready. + */ + bool is_timedout = coio_fiber_yield_timeout(coio, delay); + fiber_testcancel(); + + if (is_timedout) { + errno = ETIMEDOUT; + return total; + } + coio_timeout_update(start, &delay); } return total; } diff --git a/src/coio.h b/src/coio.h index 702602ca126b29990d91a829a9b269dce20c0bac..46edc8a8e712298d729fad0aa321baeb0903d30b 100644 --- a/src/coio.h +++ b/src/coio.h @@ -132,7 +132,14 @@ coio_write(struct ev_io *coio, const void *buf, size_t sz) } ssize_t -coio_writev(struct ev_io *coio, struct iovec *iov, int iovcnt, size_t size); +coio_writev_timeout(struct ev_io *coio, struct iovec *iov, int iovcnt, + size_t size, ev_tstamp timeout); + +static inline ssize_t +coio_writev(struct ev_io *coio, struct iovec *iov, int iovcnt, size_t size) +{ + return coio_writev_timeout(coio, iov, iovcnt, size, TIMEOUT_INFINITY); +} ssize_t coio_sendto_timeout(struct ev_io *coio, const void *buf, size_t sz, int flags,