* [PATCH 1/1] evio: allow not only SOCK_STREAM servers
@ 2018-12-17 11:55 Vladislav Shpilevoy
2018-12-18 10:08 ` Vladimir Davydov
0 siblings, 1 reply; 4+ messages in thread
From: Vladislav Shpilevoy @ 2018-12-17 11:55 UTC (permalink / raw)
To: tarantool-patches; +Cc: vdavydov.dev
evio is a useful tool for creating servers. Evio sets
all necessary flags, retries bind, parses URI. But it
does not work with SOCK_DGRAM sockets - SOCK_STREAM is
hardcoded. SWIM is going to use SOCK_DGRAM, and this
patch makes it possible to bind datagram sockets.
Needed for #3234
---
https://github.com/tarantool/tarantool/tree/gerold103/gh-3234-swim-second-preparation
https://github.com/tarantool/tarantool/issues/3234
src/box/iproto.cc | 4 ++--
src/coio.cc | 4 ++--
src/evio.c | 48 +++++++++++++++++++++++++++++++++++------------
src/evio.h | 19 ++++++++++++++++---
4 files changed, 56 insertions(+), 19 deletions(-)
diff --git a/src/box/iproto.cc b/src/box/iproto.cc
index 223469f22..157789384 100644
--- a/src/box/iproto.cc
+++ b/src/box/iproto.cc
@@ -1873,8 +1873,8 @@ net_cord_f(va_list /* ap */)
mempool_create(&iproto_connection_pool, &cord()->slabc,
sizeof(struct iproto_connection));
- evio_service_init(loop(), &binary, "binary",
- iproto_on_accept, NULL);
+ evio_service_init_tcp(loop(), &binary, "binary", iproto_on_accept,
+ NULL);
/* Init statistics counter */
diff --git a/src/coio.cc b/src/coio.cc
index 6b94cf2a6..30d18ab3c 100644
--- a/src/coio.cc
+++ b/src/coio.cc
@@ -632,8 +632,8 @@ void
coio_service_init(struct coio_service *service, const char *name,
fiber_func handler, void *handler_param)
{
- evio_service_init(loop(), &service->evio_service, name,
- coio_service_on_accept, service);
+ evio_service_init_tcp(loop(), &service->evio_service, name,
+ coio_service_on_accept, service);
service->handler = handler;
service->handler_param = handler_param;
}
diff --git a/src/evio.c b/src/evio.c
index 9ca14c45c..c16fc99db 100644
--- a/src/evio.c
+++ b/src/evio.c
@@ -209,7 +209,8 @@ evio_service_accept_cb(ev_loop *loop, ev_io *watcher, int events)
static int
evio_service_reuse_addr(struct evio_service *service, int fd)
{
- if ((service->addr.sa_family != AF_UNIX) || (errno != EADDRINUSE)) {
+ if (service->addr.sa_family != AF_UNIX || errno != EADDRINUSE ||
+ service->sock_type != SOCK_STREAM) {
diag_set(SocketError, sio_socketname(fd),
"evio_service_reuse_addr");
return -1;
@@ -248,13 +249,13 @@ evio_service_bind_addr(struct evio_service *service)
say_debug("%s: binding to %s...", evio_service_name(service),
sio_strfaddr(&service->addr, service->addr_len));
/* Create a socket. */
- int fd = sio_socket(service->addr.sa_family,
- SOCK_STREAM, IPPROTO_TCP);
+ int fd = sio_socket(service->addr.sa_family, service->sock_type,
+ service->sock_protocol);
if (fd < 0)
return -1;
if (evio_setsockopt_server(fd, service->addr.sa_family,
- SOCK_STREAM) != 0)
+ service->sock_type) != 0)
goto error;
if (sio_bind(fd, &service->addr, service->addr_len)) {
@@ -282,6 +283,12 @@ error:
return -1;
}
+void
+evio_service_start(struct evio_service *service)
+{
+ ev_io_start(service->loop, &service->ev);
+}
+
/**
* Listen on bounded port.
*
@@ -306,30 +313,47 @@ evio_service_listen(struct evio_service *service)
}
return -1;
}
- ev_io_start(service->loop, &service->ev);
+ evio_service_start(service);
return 0;
}
-void
+static void
evio_service_init(ev_loop *loop, struct evio_service *service, const char *name,
- evio_accept_f on_accept, void *on_accept_param)
+ int sock_type, int sock_protocol)
{
memset(service, 0, sizeof(struct evio_service));
snprintf(service->name, sizeof(service->name), "%s", name);
service->loop = loop;
-
- service->on_accept = on_accept;
- service->on_accept_param = on_accept_param;
+ service->sock_type = sock_type;
+ service->sock_protocol = sock_protocol;
/*
* Initialize libev objects to be able to detect if they
* are active or not in evio_service_stop().
*/
- ev_init(&service->ev, evio_service_accept_cb);
ev_io_set(&service->ev, -1, 0);
service->ev.data = service;
}
+void
+evio_service_init_udp(ev_loop *loop, struct evio_service *service,
+ const char *name, evio_input_f on_input)
+{
+ evio_service_init(loop, service, name, SOCK_DGRAM, IPPROTO_UDP);
+ ev_init(&service->ev, on_input);
+}
+
+void
+evio_service_init_tcp(ev_loop *loop, struct evio_service *service,
+ const char *name, evio_accept_f on_accept,
+ void *on_accept_param)
+{
+ evio_service_init(loop, service, name, SOCK_STREAM, IPPROTO_TCP);
+ service->on_accept = on_accept;
+ service->on_accept_param = on_accept_param;
+ ev_init(&service->ev, evio_service_accept_cb);
+}
+
/**
* Try to bind.
*/
@@ -366,7 +390,7 @@ evio_service_bind(struct evio_service *service, const char *uri)
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
+ hints.ai_socktype = service->sock_type;
hints.ai_flags = AI_PASSIVE|AI_ADDRCONFIG;
/* make no difference between empty string and NULL for host */
diff --git a/src/evio.h b/src/evio.h
index 69d641a60..826b6bb31 100644
--- a/src/evio.h
+++ b/src/evio.h
@@ -72,6 +72,8 @@ struct evio_service;
typedef int (*evio_accept_f)(struct evio_service *, int, struct sockaddr *,
socklen_t);
+typedef void (*evio_input_f)(struct ev_loop *, struct ev_io *, int);
+
struct evio_service
{
/** Service name. E.g. 'primary', 'secondary', etc. */
@@ -86,7 +88,9 @@ struct evio_service
struct sockaddr_storage addrstorage;
};
socklen_t addr_len;
-
+ /** Socket type (STREAM/DGRAM) and protocol (TCP/UDP). */
+ int sock_type;
+ int sock_protocol;
/**
* A callback invoked on every accepted client socket.
* If a callback returned != 0, the accepted socket is
@@ -102,8 +106,13 @@ 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,
- evio_accept_f on_accept, void *on_accept_param);
+evio_service_init_tcp(ev_loop *loop, struct evio_service *service,
+ const char *name, evio_accept_f on_accept,
+ void *on_accept_param);
+
+void
+evio_service_init_udp(ev_loop *loop, struct evio_service *service,
+ const char *name, evio_input_f on_input);
/** Bind service to specified uri */
int
@@ -117,6 +126,10 @@ evio_service_bind(struct evio_service *service, const char *uri);
int
evio_service_listen(struct evio_service *service);
+/** Run IO event loop. */
+void
+evio_service_start(struct evio_service *service);
+
/** If started, stop event flow and close the acceptor socket. */
void
evio_service_stop(struct evio_service *service);
--
2.17.2 (Apple Git-113)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] evio: allow not only SOCK_STREAM servers
2018-12-17 11:55 [PATCH 1/1] evio: allow not only SOCK_STREAM servers Vladislav Shpilevoy
@ 2018-12-18 10:08 ` Vladimir Davydov
2018-12-18 10:18 ` [tarantool-patches] " Vladislav Shpilevoy
2018-12-27 12:03 ` Konstantin Osipov
0 siblings, 2 replies; 4+ messages in thread
From: Vladimir Davydov @ 2018-12-18 10:08 UTC (permalink / raw)
To: Vladislav Shpilevoy; +Cc: tarantool-patches
On Mon, Dec 17, 2018 at 02:55:44PM +0300, Vladislav Shpilevoy wrote:
> evio is a useful tool for creating servers. Evio sets
> all necessary flags, retries bind, parses URI. But it
> does not work with SOCK_DGRAM sockets - SOCK_STREAM is
> hardcoded. SWIM is going to use SOCK_DGRAM, and this
> patch makes it possible to bind datagram sockets.
>
> Needed for #3234
> ---
> https://github.com/tarantool/tarantool/tree/gerold103/gh-3234-swim-second-preparation
> https://github.com/tarantool/tarantool/issues/3234
>
> src/box/iproto.cc | 4 ++--
> src/coio.cc | 4 ++--
> src/evio.c | 48 +++++++++++++++++++++++++++++++++++------------
> src/evio.h | 19 ++++++++++++++++---
> 4 files changed, 56 insertions(+), 19 deletions(-)
I don't think it's a good idea to reuse evio_service_bind() for SWIM
configuration as it's blocking (it uses getaddrinfo). Anyway, do we
really need this extra level of abstraction? Wouldn't it be more
straightforward to use sio/ev/coio directly instead?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [tarantool-patches] Re: [PATCH 1/1] evio: allow not only SOCK_STREAM servers
2018-12-18 10:08 ` Vladimir Davydov
@ 2018-12-18 10:18 ` Vladislav Shpilevoy
2018-12-27 12:03 ` Konstantin Osipov
1 sibling, 0 replies; 4+ messages in thread
From: Vladislav Shpilevoy @ 2018-12-18 10:18 UTC (permalink / raw)
To: tarantool-patches, Vladimir Davydov
On 18/12/2018 13:08, Vladimir Davydov wrote:
> On Mon, Dec 17, 2018 at 02:55:44PM +0300, Vladislav Shpilevoy wrote:
>> evio is a useful tool for creating servers. Evio sets
>> all necessary flags, retries bind, parses URI. But it
>> does not work with SOCK_DGRAM sockets - SOCK_STREAM is
>> hardcoded. SWIM is going to use SOCK_DGRAM, and this
>> patch makes it possible to bind datagram sockets.
>>
>> Needed for #3234
>> ---
>> https://github.com/tarantool/tarantool/tree/gerold103/gh-3234-swim-second-preparation
>> https://github.com/tarantool/tarantool/issues/3234
>>
>> src/box/iproto.cc | 4 ++--
>> src/coio.cc | 4 ++--
>> src/evio.c | 48 +++++++++++++++++++++++++++++++++++------------
>> src/evio.h | 19 ++++++++++++++++---
>> 4 files changed, 56 insertions(+), 19 deletions(-)
>
> I don't think it's a good idea to reuse evio_service_bind() for SWIM
> configuration as it's blocking (it uses getaddrinfo). Anyway, do we
> really need this extra level of abstraction? Wouldn't it be more
> straightforward to use sio/ev/coio directly instead?
>
Evio will allow UNIX sockets in future. But as you wish.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [tarantool-patches] Re: [PATCH 1/1] evio: allow not only SOCK_STREAM servers
2018-12-18 10:08 ` Vladimir Davydov
2018-12-18 10:18 ` [tarantool-patches] " Vladislav Shpilevoy
@ 2018-12-27 12:03 ` Konstantin Osipov
1 sibling, 0 replies; 4+ messages in thread
From: Konstantin Osipov @ 2018-12-27 12:03 UTC (permalink / raw)
To: tarantool-patches; +Cc: Vladislav Shpilevoy
* Vladimir Davydov <vdavydov.dev@gmail.com> [18/12/18 13:09]:
> On Mon, Dec 17, 2018 at 02:55:44PM +0300, Vladislav Shpilevoy wrote:
> > evio is a useful tool for creating servers. Evio sets
> > all necessary flags, retries bind, parses URI. But it
> > does not work with SOCK_DGRAM sockets - SOCK_STREAM is
> > hardcoded. SWIM is going to use SOCK_DGRAM, and this
> > patch makes it possible to bind datagram sockets.
> >
> > Needed for #3234
It's high time we integrated c-ares dns resolver. We haven't had
time before.
--
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32
http://tarantool.io - www.twitter.com/kostja_osipov
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-12-27 12:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-17 11:55 [PATCH 1/1] evio: allow not only SOCK_STREAM servers Vladislav Shpilevoy
2018-12-18 10:08 ` Vladimir Davydov
2018-12-18 10:18 ` [tarantool-patches] " Vladislav Shpilevoy
2018-12-27 12:03 ` Konstantin Osipov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox