From 858deaf7c064cb2bc839f48c5f7eca35880019db Mon Sep 17 00:00:00 2001 From: Alexandr <a.lyapunov@corp.mail.ru> Date: Wed, 5 Feb 2014 20:02:02 +0400 Subject: [PATCH] fixed GH-183 https://github.com/tarantool/tarantool/issues/183 --- src/coio.cc | 53 ++++++++++++++++++++++++------------------ test/box/socket.result | 18 +++++++++++++- test/box/socket.test | 31 +++++++++++++++++++++++- 3 files changed, 77 insertions(+), 25 deletions(-) diff --git a/src/coio.cc b/src/coio.cc index 3d143d9a2f..eea2b53d25 100644 --- a/src/coio.cc +++ b/src/coio.cc @@ -172,30 +172,37 @@ coio_accept(struct ev_io *coio, struct sockaddr_in *addr, { ev_tstamp start, delay; evio_timeout_init(&start, &delay, timeout); - while (true) { - /* Assume that there are waiting clients - * available */ - int fd = sio_accept(coio->fd, addr, &addrlen); - if (fd >= 0) { - evio_setsockopt_tcp(fd); - return fd; - } - /* The socket is not ready, yield */ - if (! ev_is_active(coio)) { - ev_io_set(coio, coio->fd, EV_READ); - ev_io_start(coio); - } - /* - * Yield control to other fibers until the - * timeout is reached. - */ - bool is_timedout = coio_fiber_yield_timeout(coio, delay); - fiber_testcancel(); - if (is_timedout) { - errno = ETIMEDOUT; - tnt_raise(SocketError, coio->fd, "accept"); + + { + auto scoped_guard = make_scoped_guard([=] { + ev_io_stop(coio); + }); + + while (true) { + /* Assume that there are waiting clients + * available */ + int fd = sio_accept(coio->fd, addr, &addrlen); + if (fd >= 0) { + evio_setsockopt_tcp(fd); + return fd; + } + /* The socket is not ready, yield */ + if (! ev_is_active(coio)) { + ev_io_set(coio, coio->fd, EV_READ); + ev_io_start(coio); + } + /* + * Yield control to other fibers until the + * timeout is reached. + */ + bool is_timedout = coio_fiber_yield_timeout(coio, delay); + fiber_testcancel(); + if (is_timedout) { + errno = ETIMEDOUT; + tnt_raise(SocketError, coio->fd, "accept"); + } + evio_timeout_update(start, &delay); } - evio_timeout_update(start, &delay); } } diff --git a/test/box/socket.result b/test/box/socket.result index 9fe4147b6e..0d01a4bfbb 100644 --- a/test/box/socket.result +++ b/test/box/socket.result @@ -933,9 +933,25 @@ lua reps --- - 3 ... -lua function server() ms = box.socket.tcp() ms:bind('127.0.0.1', 8181) ms:listen() while true do local s = ms:accept( .5 ) if s ~= 'timeout' then print("accepted connection ", s) s:send('Hello world') s:shutdown(box.socket.SHUT_RDWR) end end end box.fiber.wrap(server) +lua function server() ms = box.socket.tcp() ms:bind('127.0.0.1', 8181) ms:listen() while true do local s = ms:accept( .5 ) if s ~= 'timeout' then print("accepted connection ", s) s:send('Hello world') s:shutdown(box.socket.SHUT_RDWR) end end end fbr = box.fiber.wrap(server) --- ... Hello world Hello world Hello world +lua box.fiber.cancel(fbr) +--- +... +lua ms:close() +--- +... +lua a = '127.0.0.1' p = 12345 function srv() ms = box.socket.tcp() ms:bind(a, p) ms:listen() ms:accept() end fbr = box.fiber.wrap(srv) box.socket.tcp():connect(a, p) box.socket.tcp():connect(a, p) +--- +... +lua box.fiber.cancel(fbr) +--- +error: 'fiber.resume(): the fiber is dead' +... +lua ms:close() +--- +... diff --git a/test/box/socket.test b/test/box/socket.test index d544fc117e..93d84681ca 100644 --- a/test/box/socket.test +++ b/test/box/socket.test @@ -580,7 +580,7 @@ function server() end end -box.fiber.wrap(server) +fbr = box.fiber.wrap(server) """ exec admin "lua " + test.replace('\n', ' ') @@ -602,3 +602,32 @@ s.connect(('127.0.0.1', 8181)) data = s.recv(1024) s.close() print data + +#cleanup +exec admin "lua box.fiber.cancel(fbr)" +exec admin "lua ms:close()" + + +# GH-183 bug test. Tarantool must not crash after the code below: +test=""" +a = '127.0.0.1' +p = 12345 +function srv() + ms = box.socket.tcp() + ms:bind(a, p) + ms:listen() + ms:accept() +end + +fbr = box.fiber.wrap(srv) + +box.socket.tcp():connect(a, p) +box.socket.tcp():connect(a, p) +""" + +exec admin "lua " + test.replace('\n', ' ') + +#cleanup +exec admin "lua box.fiber.cancel(fbr)" +exec admin "lua ms:close()" + -- GitLab