[PATCH 06/11] evio: make on_accept be nothrow
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Fri Nov 30 18:39:38 MSK 2018
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 | 15 ++++++++-------
4 files changed, 27 insertions(+), 31 deletions(-)
diff --git a/src/box/iproto.cc b/src/box/iproto.cc
index 07ef23cac..dd76e28bd 100644
--- a/src/box/iproto.cc
+++ b/src/box/iproto.cc
@@ -1791,7 +1791,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)
{
@@ -1800,26 +1800,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 b69f5e31a..49ac10b70 100644
--- a/src/coio.cc
+++ b/src/coio.cc
@@ -596,7 +596,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)
{
@@ -612,14 +612,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
@@ -631,6 +629,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 401e71155..4b7d37281 100644
--- a/src/evio.cc
+++ b/src/evio.cc
@@ -196,8 +196,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);
@@ -304,11 +306,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..f6c3a3a3e 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. */
@@ -83,8 +88,7 @@ struct evio_service
* when it happens, the exception is logged, and the
* accepted socket is closed.
*/
- 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 +98,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)
More information about the Tarantool-patches
mailing list