[PATCH 10/11] evio: remove exceptions

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Fri Nov 30 18:39:32 MSK 2018


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)




More information about the Tarantool-patches mailing list