[tarantool-patches] [PATCH 5/5] swim: explicitly stop old ev_io input/output on rebind

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Wed May 1 01:31:27 MSK 2019


When an input/output file descriptor was changed, SWIM did this:

    swim_ev_io_set(io, new_fd)
    swim_ev_io_start(io)

It worked in an assumption that libev allows to change fd on fly,
and the tests were passing because fake event loop was used, not
real libev.

But it didn't work. Libev requires explicit ev_io_stop() called
on the old descriptor. This patch makes this:

    swim_ev_io_stop(io)
    //do bind ...

    swim_ev_io_set(io, new_fd)
    swim_ev_io_start(io)

Part of #3234
---
 src/lib/swim/swim_io.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/lib/swim/swim_io.c b/src/lib/swim/swim_io.c
index d49900a86..ef2f479eb 100644
--- a/src/lib/swim/swim_io.c
+++ b/src/lib/swim/swim_io.c
@@ -288,15 +288,18 @@ int
 swim_scheduler_bind(struct swim_scheduler *scheduler,
 		    const struct sockaddr_in *addr)
 {
+	swim_ev_io_stop(loop(), &scheduler->input);
+	swim_ev_io_stop(loop(), &scheduler->output);
 	struct swim_transport *t = &scheduler->transport;
-	if (swim_transport_bind(t, (const struct sockaddr *) addr,
-				sizeof(*addr)) != 0)
-		return -1;
-	swim_ev_io_set(&scheduler->output, t->fd, EV_WRITE);
-	swim_ev_io_set(&scheduler->input, t->fd, EV_READ);
-	swim_ev_io_start(loop(), &scheduler->input);
-	swim_ev_io_start(loop(), &scheduler->output);
-	return 0;
+	int rc = swim_transport_bind(t, (const struct sockaddr *) addr,
+				     sizeof(*addr));
+	if (t->fd >= 0) {
+		swim_ev_io_set(&scheduler->output, t->fd, EV_WRITE);
+		swim_ev_io_set(&scheduler->input, t->fd, EV_READ);
+		swim_ev_io_start(loop(), &scheduler->input);
+		swim_ev_io_start(loop(), &scheduler->output);
+	}
+	return rc;
 }
 
 void
-- 
2.20.1 (Apple Git-117)





More information about the Tarantool-patches mailing list