LGTM On Wednesday, June 19, 2019 3:54:57 PM MSK Maria K wrote: > Receive function behaved inconsistently for the cases where > first we use an integer as a pattern as to tell the function > a specific number of elements we want to read, and then > perform another receive call using '*a' as a pattern. > The latter should have denoted that we want to get all there > is to get, but instead it was possible to get only a part of > data and also in non-sequential order. > > Closes #4118 > --- > Branch: > https://github.com/tarantool/tarantool/tree/eljashm/gh-4118-socket_tcp_now_c > onsistent > > Issue: > https://github.com/tarantool/tarantool/issues/4118 > > src/lua/socket.lua | 15 ++++++++++++- > test/app/socket.result | 48 ++++++++++++++++++++++++++++++++++++++++ > test/app/socket.test.lua | 16 ++++++++++++++ > 3 files changed, 78 insertions(+), 1 deletion(-) > > diff --git a/src/lua/socket.lua b/src/lua/socket.lua > index 2dba0a8d2..a334ad45b 100644 > --- a/src/lua/socket.lua > +++ b/src/lua/socket.lua > @@ -637,6 +637,19 @@ local function check_limit(self, limit) > return nil > end > > +local function check_infinity(self, limit) > + if limit == 0 then > + return 0 > + end > + > + local rbuf = self.rbuf > + if rbuf:size() == 0 then > + return nil > + end > + > + return rbuf:size() > +end > + > local function check_delimiter(self, limit, eols) > if limit == 0 then > return 0 > @@ -1454,7 +1467,7 @@ local function lsocket_tcp_receive(self, pattern, > prefix) > local result = { prefix } > local deadline = fiber.clock() + (self.timeout or TIMEOUT_INFINITY) > repeat > - local data = socket_sysread(self) > + local data = read(self, LIMIT_INFINITY, timeout, > check_infinity) > if data == nil then > if not errno_is_transient[self._errno] then > return nil, socket_error(self) > diff --git a/test/app/socket.result b/test/app/socket.result > index 0d029039a..77eff7370 100644 > --- a/test/app/socket.result > +++ b/test/app/socket.result > @@ -2874,3 +2874,51 @@ test_run:cmd("clear filter") > --- > - true > ... > +-- case: sicket receive inconsistent behavior > +chan = fiber.channel() > +--- > +... > +counter = 0 > +--- > +... > +fn = function(s) counter = 0; while true do > s:write((tostring(counter)):rep(chan:get())); counter = counter + 1 end end > +--- > +... > +srv = socket.tcp_server('0.0.0.0', 8888, fn) > +--- > +... > +s = socket.connect('localhost', 8888) > +--- > +... > +chan:put(5) > +--- > +- true > +... > +chan:put(5) > +--- > +- true > +... > +s:receive(5) > +--- > +- '00000' > +... > +chan:put(5) > +--- > +- true > +... > +s:settimeout(1) > +--- > +- 1 > +... > +s:receive('*a') > +--- > +- '1111122222' > +... > +s:close() > +--- > +- 1 > +... > +srv:close() > +--- > +- true > +... > diff --git a/test/app/socket.test.lua b/test/app/socket.test.lua > index dab168f90..7ae9a98aa 100644 > --- a/test/app/socket.test.lua > +++ b/test/app/socket.test.lua > @@ -983,3 +983,19 @@ client:read(1, 5) == '' > server:close() > > test_run:cmd("clear filter") > + > +-- case: sicket receive inconsistent behavior > +chan = fiber.channel() > +counter = 0 > +fn = function(s) counter = 0; while true do > s:write((tostring(counter)):rep(chan:get())); counter = counter + 1 end end > +srv = socket.tcp_server('0.0.0.0', 8888, fn) > +s = socket.connect('localhost', 8888) > +chan:put(5) > +chan:put(5) > +s:receive(5) > +chan:put(5) > +s:settimeout(1) > +s:receive('*a') > +s:close() > +srv:close() > +