[tarantool-patches] [PATCH 10/11] evio: remove exceptions

  • From: Vladislav Shpilevoy <v.shpilevoy@xxxxxxxxxxxxx>
  • To: tarantool-patches@xxxxxxxxxxxxx
  • Date: Fri, 30 Nov 2018 18:39:32 +0300

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 <stdio.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
-
 #include <trivia/util.h>
 #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)


Other related posts:

  • » [tarantool-patches] [PATCH 10/11] evio: remove exceptions - Vladislav Shpilevoy