Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: vdavydov.dev@gmail.com
Subject: [PATCH v2 06/11] evio: make on_accept be nothrow
Date: Wed,  5 Dec 2018 00:28:53 +0300	[thread overview]
Message-ID: <0adca8111fe006f8b6e6ca1bffb4d33657536f78.1543958698.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1543958698.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1543958698.git.v.shpilevoy@tarantool.org>

Evio is going to be C, because it is needed in SWIM to
1) support UNIX sockets in future;
2) do not care about setting SocketError directly. It
is not possible via bare sio, because sio_bind ignores
EADDRINUSE.

A first step to make evio C - eliminate exceptions
from its callbacks available to other modules. The
only callback it has - on_accept.

Needed for #3234
---
 src/box/iproto.cc | 17 +++++++----------
 src/coio.cc       | 13 ++++++-------
 src/evio.cc       | 13 ++++++-------
 src/evio.h        | 20 ++++++++++----------
 4 files changed, 29 insertions(+), 34 deletions(-)

diff --git a/src/box/iproto.cc b/src/box/iproto.cc
index fe42bb250..f4051e791 100644
--- a/src/box/iproto.cc
+++ b/src/box/iproto.cc
@@ -1795,7 +1795,7 @@ static const struct cmsg_hop connect_route[] = {
 /**
  * Create a connection and start input.
  */
-static void
+static int
 iproto_on_accept(struct evio_service * /* service */, int fd,
 		 struct sockaddr *addr, socklen_t addrlen)
 {
@@ -1804,26 +1804,23 @@ iproto_on_accept(struct evio_service * /* service */, int fd,
 	struct iproto_msg *msg;
 	struct iproto_connection *con = iproto_connection_new(fd);
 	if (con == NULL)
-		goto error_conn;
+		return -1;
 	/*
 	 * Ignore msg allocation failure - the queue size is
 	 * fixed so there is a limited number of msgs in
 	 * use, all stored in just a few blocks of the memory pool.
 	 */
 	msg = iproto_msg_new(con);
-	if (msg == NULL)
-		goto error_msg;
+	if (msg == NULL) {
+		mempool_free(&iproto_connection_pool, con);
+		return -1;
+	}
 	cmsg_init(&msg->base, connect_route);
 	msg->p_ibuf = con->p_ibuf;
 	msg->wpos = con->wpos;
 	msg->close_connection = false;
 	cpipe_push(&tx_pipe, &msg->base);
-	return;
-error_msg:
-	mempool_free(&iproto_connection_pool, con);
-error_conn:
-	close(fd);
-	return;
+	return 0;
 }
 
 static struct evio_service binary; /* iproto binary listener */
diff --git a/src/coio.cc b/src/coio.cc
index a546f647d..9b9c71c79 100644
--- a/src/coio.cc
+++ b/src/coio.cc
@@ -589,7 +589,7 @@ coio_recvfrom_timeout(struct ev_io *coio, void *buf, size_t sz, int flags,
 	}
 }
 
-void
+static int
 coio_service_on_accept(struct evio_service *evio_service,
 		       int fd, struct sockaddr *addr, socklen_t addrlen)
 {
@@ -605,14 +605,12 @@ coio_service_on_accept(struct evio_service *evio_service,
 		 "%s/%s", evio_service->name, sio_strfaddr(addr, addrlen));
 
 	/* Create the worker fiber. */
-	struct fiber *f;
-	try {
-		f = fiber_new_xc(fiber_name, service->handler);
-	} catch (struct error *e) {
-		error_log(e);
+	struct fiber *f = fiber_new(fiber_name, service->handler);
+	if (f == NULL) {
+		diag_log();
 		say_error("can't create a handler fiber, dropping client connection");
 		evio_close(loop(), &coio);
-		throw;
+		return -1;
 	}
 	/*
 	 * The coio is passed into the created fiber, reset the
@@ -624,6 +622,7 @@ coio_service_on_accept(struct evio_service *evio_service,
 	 * and will have to close it and free before termination.
 	 */
 	fiber_start(f, coio, addr, addrlen, service->handler_param);
+	return 0;
 }
 
 void
diff --git a/src/evio.cc b/src/evio.cc
index 32aece0f0..1d906db8e 100644
--- a/src/evio.cc
+++ b/src/evio.cc
@@ -195,8 +195,10 @@ evio_service_accept_cb(ev_loop * /* loop */, ev_io *watcher,
 			 * Invoke the callback and pass it the accepted
 			 * socket.
 			 */
-			service->on_accept(service, fd, (struct sockaddr *)&addr, addrlen);
-
+			if (service->on_accept(service, fd,
+					       (struct sockaddr *)&addr,
+					       addrlen) != 0)
+				diag_raise();
 		} catch (Exception *e) {
 			if (fd >= 0)
 				close(fd);
@@ -305,11 +307,8 @@ evio_service_listen(struct evio_service *service)
 }
 
 void
-evio_service_init(ev_loop *loop,
-		  struct evio_service *service, const char *name,
-		  void (*on_accept)(struct evio_service *, int,
-				    struct sockaddr *, socklen_t),
-		  void *on_accept_param)
+evio_service_init(ev_loop *loop, struct evio_service *service, const char *name,
+		  evio_accept_f on_accept, void *on_accept_param)
 {
 	memset(service, 0, sizeof(struct evio_service));
 	snprintf(service->name, sizeof(service->name), "%s", name);
diff --git a/src/evio.h b/src/evio.h
index e91ba11fc..e56e2b8a7 100644
--- a/src/evio.h
+++ b/src/evio.h
@@ -62,6 +62,11 @@
  * If a service is not started, but only initialized, no
  * dedicated cleanup/destruction is necessary.
  */
+struct evio_service;
+
+typedef int (*evio_accept_f)(struct evio_service *, int, struct sockaddr *,
+			      socklen_t);
+
 struct evio_service
 {
 	/** Service name. E.g. 'primary', 'secondary', etc. */
@@ -79,12 +84,10 @@ 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 a callback returned != 0, the accepted socket is
+	 * closed and the error is logged.
 	 */
-	void (*on_accept)(struct evio_service *, int,
-			  struct sockaddr *, socklen_t);
+	evio_accept_f on_accept;
 	void *on_accept_param;
 
 	/** libev io object for the acceptor socket. */
@@ -94,11 +97,8 @@ struct evio_service
 
 /** Initialize the service. Don't bind to the port yet. */
 void
-evio_service_init(ev_loop *loop,
-		  struct evio_service *service, const char *name,
-		  void (*on_accept)(struct evio_service *,
-				    int, struct sockaddr *, socklen_t),
-		  void *on_accept_param);
+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
-- 
2.17.2 (Apple Git-113)

  parent reply	other threads:[~2018-12-04 21:28 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-04 21:28 [PATCH v2 00/11] SWIM preparation Vladislav Shpilevoy
2018-12-04 21:28 ` [PATCH v2 01/11] sio: remove unused functions Vladislav Shpilevoy
2018-12-09 12:10   ` Vladimir Davydov
2018-12-04 21:28 ` [PATCH v2 10/11] evio: make code C compatible Vladislav Shpilevoy
2018-12-05  8:56   ` Vladimir Davydov
2018-12-05 20:07     ` [tarantool-patches] " Vladislav Shpilevoy
2018-12-04 21:28 ` [PATCH v2 11/11] evio: turn nto c Vladislav Shpilevoy
2018-12-04 21:28 ` [PATCH v2 02/11] sio: treat EADDRINUSE in sio_listen as error Vladislav Shpilevoy
2018-12-09 12:57   ` Vladimir Davydov
2018-12-10 15:36     ` [tarantool-patches] " Vladislav Shpilevoy
2018-12-04 21:28 ` [PATCH v2 03/11] sio: remove exceptions Vladislav Shpilevoy
2018-12-09 12:54   ` Vladimir Davydov
2018-12-10 15:37     ` [tarantool-patches] " Vladislav Shpilevoy
2018-12-11  8:44       ` Vladimir Davydov
2018-12-04 21:28 ` [PATCH v2 04/11] sio: make code compatible with C Vladislav Shpilevoy
2018-12-05  8:57   ` Vladimir Davydov
2018-12-05 20:07     ` [tarantool-patches] " Vladislav Shpilevoy
2018-12-04 21:28 ` [PATCH v2 05/11] sio: turn into C Vladislav Shpilevoy
2018-12-04 21:28 ` Vladislav Shpilevoy [this message]
2018-12-04 21:28 ` [PATCH v2 07/11] coio: fix double close of a file descriptor Vladislav Shpilevoy
2018-12-04 21:28 ` [PATCH v2 08/11] evio: remove exceptions Vladislav Shpilevoy
2018-12-04 21:28 ` [PATCH v2 09/11] coio: fix file descriptor leak on accept Vladislav Shpilevoy
2018-12-11  8:47 ` [PATCH v2 00/11] SWIM preparation Vladimir Davydov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0adca8111fe006f8b6e6ca1bffb4d33657536f78.1543958698.git.v.shpilevoy@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=vdavydov.dev@gmail.com \
    --subject='Re: [PATCH v2 06/11] evio: make on_accept be nothrow' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox