diff --git a/src/coeio.cc b/src/coeio.cc index c9ee8635f9020d223f02104979d294a5d526aee0..c15cfabf232a97112f512dc7fe7e36862a42a174 100644 --- a/src/coeio.cc +++ b/src/coeio.cc @@ -174,8 +174,7 @@ coio_task(struct coio_task *task, coio_task_cb func, if (fiber_yield_timeout(timeout) && !task->complete) { /* timed out. */ task->fiber = NULL; - errno = ETIMEDOUT; - return -1; + tnt_raise(TimedOut); } return task->base.result; @@ -334,11 +333,8 @@ coio_getaddrinfo(const char *host, const char *port, /* do resolving */ /* coio_task() don't throw. */ if (coio_task(&task->base, getaddrinfo_cb, getaddrinfo_free_cb, - timeout) == -1) { - /* timed out */ - errno = ETIMEDOUT; - return rc; - } + timeout) == -1) + tnt_raise(TimedOut); rc = task->rc; *res = task->result; diff --git a/src/coio.cc b/src/coio.cc index b9e60eeb6dc44b3d1efb8484d7354cc4d21063b0..7ebce0994ffdaf8d85939903f715ca48d4897e94 100644 --- a/src/coio.cc +++ b/src/coio.cc @@ -96,10 +96,8 @@ coio_connect_addr(struct ev_io *coio, struct sockaddr *addr, bool is_timedout = coio_fiber_yield_timeout(coio, timeout); ev_io_stop(loop, coio); fiber_testcancel(); - if (is_timedout) { - errno = ETIMEDOUT; - return -1; - } + if (is_timedout) + tnt_raise(TimedOut); int error = EINPROGRESS; socklen_t sz = sizeof(error); sio_getsockopt(coio->fd, SOL_SOCKET, SO_ERROR, @@ -203,12 +201,8 @@ coio_connect_timeout(struct ev_io *coio, struct uri *uri, struct sockaddr *addr, hints.ai_flags = AI_ADDRCONFIG|AI_NUMERICSERV|AI_PASSIVE; hints.ai_protocol = 0; int rc = coio_getaddrinfo(host, service, &hints, &ai, delay); - if (rc != 0) { - if (errno == ETIMEDOUT) - return -1; /* timeout */ + if (rc != 0) tnt_raise(SocketError, -1, "getaddrinfo"); - } - } auto addrinfo_guard = make_scoped_guard([=] { if (!uri->host_hint) freeaddrinfo(ai); @@ -275,10 +269,8 @@ coio_accept(struct ev_io *coio, struct sockaddr *addr, */ bool is_timedout = coio_fiber_yield_timeout(coio, delay); fiber_testcancel(); - if (is_timedout) { - errno = ETIMEDOUT; - tnt_raise(SocketError, coio->fd, "accept"); - } + if (is_timedout) + tnt_raise(TimedOut); coio_timeout_update(start, &delay); } } @@ -290,7 +282,7 @@ coio_accept(struct ev_io *coio, struct sockaddr *addr, * and sets errno to 0. * Can read up to bufsiz bytes. * - * @retval the number of bytes read, sets the errno to ETIMEDOUT or 0. + * @retval the number of bytes read. */ ssize_t coio_read_ahead_timeout(struct ev_io *coio, void *buf, size_t sz, @@ -335,10 +327,8 @@ coio_read_ahead_timeout(struct ev_io *coio, void *buf, size_t sz, bool is_timedout = coio_fiber_yield_timeout(coio, delay); fiber_testcancel(); - if (is_timedout) { - errno = ETIMEDOUT; - return sz - to_read; - } + if (is_timedout) + tnt_raise(TimedOut); coio_timeout_update(start, &delay); } } @@ -430,10 +420,8 @@ coio_write_timeout(struct ev_io *coio, const void *buf, size_t sz, delay); fiber_testcancel(); - if (is_timedout) { - errno = ETIMEDOUT; - return sz - towrite; - } + if (is_timedout) + tnt_raise(TimedOut); coio_timeout_update(start, &delay); } } @@ -502,10 +490,8 @@ coio_writev_timeout(struct ev_io *coio, struct iovec *iov, int iovcnt, bool is_timedout = coio_fiber_yield_timeout(coio, delay); fiber_testcancel(); - if (is_timedout) { - errno = ETIMEDOUT; - return total; - } + if (is_timedout) + tnt_raise(TimedOut); coio_timeout_update(start, &delay); } return total; @@ -515,7 +501,6 @@ coio_writev_timeout(struct ev_io *coio, struct iovec *iov, int iovcnt, * Send up to sz bytes to a UDP socket. * Return the number of bytes sent. * - * @retval 0, errno = ETIMEDOUT timeout * @retval n the number of bytes written */ ssize_t @@ -549,10 +534,8 @@ coio_sendto_timeout(struct ev_io *coio, const void *buf, size_t sz, int flags, bool is_timedout = coio_fiber_yield_timeout(coio, delay); fiber_testcancel(); - if (is_timedout) { - errno = ETIMEDOUT; - return 0; - } + if (is_timedout) + tnt_raise(TimedOut); coio_timeout_update(start, &delay); } } @@ -561,7 +544,6 @@ coio_sendto_timeout(struct ev_io *coio, const void *buf, size_t sz, int flags, * Read a datagram up to sz bytes from a socket, with a timeout. * * @retval 0, errno = 0 eof - * @retval 0, errno = ETIMEDOUT timeout * @retvl n number of bytes read */ ssize_t @@ -596,10 +578,8 @@ coio_recvfrom_timeout(struct ev_io *coio, void *buf, size_t sz, int flags, bool is_timedout = coio_fiber_yield_timeout(coio, delay); fiber_testcancel(); - if (is_timedout) { - errno = ETIMEDOUT; - return 0; - } + if (is_timedout) + tnt_raise(TimedOut); coio_timeout_update(start, &delay); } } diff --git a/src/exception.cc b/src/exception.cc index c3e8a38b187e54ec751a84d8d92b32259fcc9885..8cee67ea5d1abb6bc2117b41d383b8eacddac8ef 100644 --- a/src/exception.cc +++ b/src/exception.cc @@ -165,3 +165,12 @@ OutOfMemory::OutOfMemory(const char *file, unsigned line, "Failed to allocate %u bytes in %s for %s", (unsigned) amount, allocator, object); } + +const struct type type_TimedOut = + make_type("TimedOut", &type_SystemError); + +TimedOut::TimedOut(const char *file, unsigned line) + : SystemError(&type_OutOfMemory, file, line) +{ + m_errno = ETIMEDOUT; +} diff --git a/src/exception.h b/src/exception.h index 4497f75ac45c8b255f3caa83d453d9b894c312dc..6cb1b8c7b51f3968fd403bde845d7af830c7f083 100644 --- a/src/exception.h +++ b/src/exception.h @@ -138,6 +138,12 @@ class OutOfMemory: public SystemError { const char *object); }; +extern const struct type type_TimedOut; +class TimedOut: public SystemError { +public: + TimedOut(const char *file, unsigned line); +}; + /** * Diagnostics Area - a container for errors and warnings */ diff --git a/src/latch.h b/src/latch.h index 2d56399126c476fd6c649d209d9882096c1a6125..449ce3e4b8d730c6270b9f1b22c51b9714231d5b 100644 --- a/src/latch.h +++ b/src/latch.h @@ -110,7 +110,6 @@ latch_lock_timeout(struct latch *l, ev_tstamp timeout) } timeout -= ev_now(loop()) - start; if (timeout <= 0) { - errno = ETIMEDOUT; result = 1; break; } diff --git a/src/lua/bsdsocket.cc b/src/lua/bsdsocket.cc index ae4bbcb2484bdc90ffd6539fcf070602276c6ce3..75c9fa4b7b56af7050263dd95040e2595c62bae3 100644 --- a/src/lua/bsdsocket.cc +++ b/src/lua/bsdsocket.cc @@ -665,7 +665,12 @@ lbox_bsdsocket_getaddrinfo(struct lua_State *L) lua_pop(L, 1); } - int dns_res = coio_getaddrinfo(host, port, &hints, &result, timeout); + int dns_res = 0; + try { + dns_res = coio_getaddrinfo(host, port, &hints, &result, timeout); + } catch (TimedOut *e) { + dns_res = 1; + } lua_pop(L, 2); /* host, port */ if (dns_res != 0) {