From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Vladislav Shpilevoy Subject: [PATCH 10/11] evio: remove exceptions Date: Fri, 30 Nov 2018 18:39:32 +0300 Message-Id: In-Reply-To: References: In-Reply-To: References: To: tarantool-patches@freelists.org Cc: vdavydov.dev@gmail.com List-ID: Remove them to be able to convert evio to C - final step to make it usable in swim. Needed for #3234 --- src/box/iproto.cc | 41 ++++++++++------------ src/coio.cc | 8 +++-- src/evio.cc | 87 ++++++++++++++++++++++++----------------------- src/evio.h | 13 ++++--- 4 files changed, 73 insertions(+), 76 deletions(-) diff --git a/src/box/iproto.cc b/src/box/iproto.cc index dd76e28bd..7e5110848 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -2014,29 +2014,24 @@ iproto_do_cfg_f(struct cbus_call_msg *m) { struct iproto_cfg_msg *cfg_msg = (struct iproto_cfg_msg *) m; int old; - try { - switch (cfg_msg->op) { - case IPROTO_CFG_MSG_MAX: - cpipe_set_max_input(&tx_pipe, - cfg_msg->iproto_msg_max / 2); - old = iproto_msg_max; - iproto_msg_max = cfg_msg->iproto_msg_max; - if (old < iproto_msg_max) - iproto_resume(); - break; - case IPROTO_CFG_LISTEN: - if (evio_service_is_active(&binary)) - evio_service_stop(&binary); - if (cfg_msg->uri != NULL) { - evio_service_bind(&binary, cfg_msg->uri); - evio_service_listen(&binary); - } - break; - default: - unreachable(); - } - } catch (Exception *e) { - return -1; + switch (cfg_msg->op) { + case IPROTO_CFG_MSG_MAX: + cpipe_set_max_input(&tx_pipe, cfg_msg->iproto_msg_max / 2); + old = iproto_msg_max; + iproto_msg_max = cfg_msg->iproto_msg_max; + if (old < iproto_msg_max) + iproto_resume(); + break; + case IPROTO_CFG_LISTEN: + if (evio_service_is_active(&binary)) + evio_service_stop(&binary); + if (cfg_msg->uri != NULL && + (evio_service_bind(&binary, cfg_msg->uri) != 0 || + evio_service_listen(&binary) != 0)) + return -1; + break; + default: + unreachable(); } return 0; } diff --git a/src/coio.cc b/src/coio.cc index a888a54dd..1615d075a 100644 --- a/src/coio.cc +++ b/src/coio.cc @@ -77,7 +77,8 @@ coio_connect_addr(struct ev_io *coio, struct sockaddr *addr, socklen_t len, ev_tstamp timeout) { ev_loop *loop = loop(); - evio_socket(coio, addr->sa_family, SOCK_STREAM, 0); + if (evio_socket(coio, addr->sa_family, SOCK_STREAM, 0) != 0) + diag_raise(); if (sio_connect(coio->fd, addr, len) == 0) return 0; auto coio_guard = make_scoped_guard([=]{ evio_close(loop, coio); }); @@ -646,8 +647,9 @@ coio_service_init(struct coio_service *service, const char *name, void coio_service_start(struct evio_service *service, const char *uri) { - evio_service_bind(service, uri); - evio_service_listen(service); + if (evio_service_bind(service, uri) != 0 || + evio_service_listen(service) != 0) + diag_raise(); } void diff --git a/src/evio.cc b/src/evio.cc index 166ba7f95..2bfd0a2e5 100644 --- a/src/evio.cc +++ b/src/evio.cc @@ -29,14 +29,12 @@ * SUCH DAMAGE. */ #include "evio.h" -#include "scoped_guard.h" #include #include #include #include #include #include - #include #include "exception.h" @@ -51,18 +49,19 @@ evio_close(ev_loop *loop, struct ev_io *evio) } } -void +int evio_socket(struct ev_io *evio, int domain, int type, int protocol) { assert(! evio_has_fd(evio)); evio->fd = sio_socket(domain, type, protocol); if (evio->fd < 0) - diag_raise(); + return -1; if (evio_setsockopt_client(evio->fd, domain, type) != 0) { close(evio->fd); ev_io_set(evio, -1, 0); - diag_raise(); + return -1; } + return 0; } static int @@ -121,14 +120,14 @@ evio_setsockopt_client(int fd, int family, int type) } /** Set options for server sockets. */ -static void +static int evio_setsockopt_server(int fd, int family, int type) { int on = 1; if (sio_setfl(fd, O_NONBLOCK) != 0) - diag_raise(); + return -1; if (sio_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) - diag_raise(); + return -1; /* * Send all buffered messages on socket before take @@ -137,10 +136,11 @@ evio_setsockopt_server(int fd, int family, int type) struct linger linger = { 0, 0 }; if (sio_setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) != 0) - diag_raise(); + return -1; if (type == SOCK_STREAM && family != AF_UNIX && evio_setsockopt_keeping(fd) != 0) - diag_raise(); + return -1; + return 0; } /** @@ -220,12 +220,8 @@ err: return -1; } -/** - * Try to bind on the configured port. - * - * Throws an exception if error. - */ -static void +/** Try to bind on the configured port. */ +static int evio_service_bind_addr(struct evio_service *service) { say_debug("%s: binding to %s...", service->name, @@ -233,23 +229,22 @@ evio_service_bind_addr(struct evio_service *service) /* Create a socket. */ int fd = sio_socket(service->addr.sa_family, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) - diag_raise(); - - auto fd_guard = make_scoped_guard([=]{ close(fd); }); - - evio_setsockopt_server(fd, service->addr.sa_family, SOCK_STREAM); + return -1; + if (evio_setsockopt_server(fd, service->addr.sa_family, + SOCK_STREAM) != 0) + goto error; if (sio_bind(fd, &service->addr, service->addr_len)) { if (errno != EADDRINUSE) - diag_raise(); + goto error; if (evio_service_reuse_addr(service, fd)) - diag_raise(); + goto error; if (sio_bind(fd, &service->addr, service->addr_len)) { if (errno == EADDRINUSE) { diag_set(SocketError, sio_socketname(fd), "bind"); } - diag_raise(); + goto error; } } @@ -258,11 +253,13 @@ evio_service_bind_addr(struct evio_service *service) /* Register the socket in the event loop. */ ev_io_set(&service->ev, fd, EV_READ); - - fd_guard.is_active = false; + return 0; +error: + close(fd); + return -1; } -void +int evio_service_listen(struct evio_service *service) { say_debug("%s: listening on %s...", service->name, @@ -270,8 +267,9 @@ evio_service_listen(struct evio_service *service) int fd = service->ev.fd; if (sio_listen(fd) < 0) - diag_raise(); + return -1; ev_io_start(service->loop, &service->ev); + return 0; } void @@ -294,13 +292,14 @@ evio_service_init(ev_loop *loop, struct evio_service *service, const char *name, service->ev.data = service; } -void +int evio_service_bind(struct evio_service *service, const char *uri) { struct uri u; if (uri_parse(&u, uri) || u.service == NULL) { - tnt_raise(SocketError, sio_socketname(-1), - "invalid uri for bind: %s", uri); + diag_set(SocketError, sio_socketname(-1), + "invalid uri for bind: %s", uri); + return -1; } snprintf(service->serv, sizeof(service->serv), "%.*s", @@ -334,25 +333,27 @@ evio_service_bind(struct evio_service *service, const char *uri) */ if (getaddrinfo(*service->host ? service->host : NULL, service->serv, &hints, &res) != 0 || res == NULL) { - tnt_raise(SocketError, sio_socketname(-1), - "can't resolve uri for bind"); + diag_set(SocketError, sio_socketname(-1), + "can't resolve uri for bind"); + return -1; } - auto addrinfo_guard = make_scoped_guard([=]{ freeaddrinfo(res); }); for (struct addrinfo *ai = res; ai != NULL; ai = ai->ai_next) { memcpy(&service->addr, ai->ai_addr, ai->ai_addrlen); service->addr_len = ai->ai_addrlen; - try { - return evio_service_bind_addr(service); - } catch (SocketError *e) { - say_error("%s: failed to bind on %s: %s", service->name, - sio_strfaddr(ai->ai_addr, ai->ai_addrlen), - e->get_errmsg()); - /* ignore */ + if (evio_service_bind_addr(service) == 0) { + freeaddrinfo(res); + return 0; } + struct error *e = diag_last_error(diag_get()); + say_error("%s: failed to bind on %s: %s", service->name, + sio_strfaddr(ai->ai_addr, ai->ai_addrlen), e->errmsg); + /* ignore */ } - tnt_raise(SocketError, sio_socketname(-1), "%s: failed to bind", - service->name); + freeaddrinfo(res); + diag_set(SocketError, sio_socketname(-1), "%s: failed to bind", + service->name); + return -1; } void diff --git a/src/evio.h b/src/evio.h index ae2b9b9a8..1446a5617 100644 --- a/src/evio.h +++ b/src/evio.h @@ -39,7 +39,7 @@ #include "sio.h" #include "uri.h" /** - * Exception-aware way to add a socket to the event loop. + * A way to add a socket to the event loop. * * Coroutines/fibers are not used for port listeners since * listener's job is usually simple and only involves creating a @@ -80,9 +80,8 @@ struct evio_service /** * A callback invoked on every accepted client socket. - * It's OK to throw an exception in the callback: - * when it happens, the exception is logged, and the - * accepted socket is closed. + * If returns != 0, the error is logged, and the accepted + * socket is closed. */ evio_accept_f on_accept; void *on_accept_param; @@ -98,11 +97,11 @@ evio_service_init(ev_loop *loop, struct evio_service *service, const char *name, evio_accept_f on_accept, void *on_accept_param); /** Bind service to specified uri. */ -void +int evio_service_bind(struct evio_service *service, const char *uri); /** Listen on bounded socket. */ -void +int evio_service_listen(struct evio_service *service); /** If started, stop event flow and close the acceptor socket. */ @@ -113,7 +112,7 @@ evio_service_stop(struct evio_service *service); * Create a client socket. Sets keepalive, nonblock and nodelay * options. */ -void +int evio_socket(struct ev_io *coio, int domain, int type, int protocol); /** Close evio service socket and detach from event loop. */ -- 2.17.2 (Apple Git-113)