From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Vladislav Shpilevoy Subject: [PATCH 06/11] evio: make on_accept be nothrow Date: Fri, 30 Nov 2018 18:39:38 +0300 Message-Id: <5aa67f292cac37f8b9d2f77b97221b81b1513195.1543590433.git.v.shpilevoy@tarantool.org> In-Reply-To: References: In-Reply-To: References: To: tarantool-patches@freelists.org Cc: vdavydov.dev@gmail.com List-ID: 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)