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)
next prev 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