From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 531B9301FD for ; Wed, 19 Jun 2019 08:55:10 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cvhfCegsUWh6 for ; Wed, 19 Jun 2019 08:55:10 -0400 (EDT) Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 0BF823018A for ; Wed, 19 Jun 2019 08:55:09 -0400 (EDT) Received: by mail-wr1-f45.google.com with SMTP id n4so3225278wrw.13 for ; Wed, 19 Jun 2019 05:55:09 -0700 (PDT) MIME-Version: 1.0 From: Maria K Date: Wed, 19 Jun 2019 15:54:57 +0300 Message-ID: Subject: [tarantool-patches] [PATCH] lua: lsocket_tcp_receive behavior fixed Content-Type: multipart/alternative; boundary="00000000000034d895058bacbd7a" Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: g.kirichenko@corp.mail.ru --00000000000034d895058bacbd7a Content-Type: text/plain; charset="UTF-8" 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_consistent 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() + -- 2.20.1 --00000000000034d895058bacbd7a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Receive function behaved inconsistently for the cases wher= e
first we use an integer as a pattern as to tell the function
a spec= ific number of elements we want to read, and then
perform another receiv= e call using '*a' as a pattern.
The latter should have denoted t= hat we want to get all there
is to get, but instead it was possible to g= et only a part of
data and also in non-sequential order.

Closes #= 4118
---
Branch:
https://github.com/taranto= ol/tarantool/tree/eljashm/gh-4118-socket_tcp_now_consistent

Issu= e:
https= ://github.com/tarantool/tarantool/issues/4118

=C2=A0src/lua/soc= ket.lua =C2=A0 =C2=A0 =C2=A0 | 15 ++++++++++++-
=C2=A0test/app/socket.re= sult =C2=A0 | 48 ++++++++++++++++++++++++++++++++++++++++
=C2=A0test/app= /socket.test.lua | 16 ++++++++++++++
=C2=A03 files changed, 78 insertion= s(+), 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(s= elf, limit)
=C2=A0 =C2=A0 =C2=A0return nil
=C2=A0end
=C2=A0
+lo= cal function check_infinity(self, limit)
+ =C2=A0 =C2=A0if limit =3D=3D = 0 then
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0
+ =C2=A0 =C2=A0end
+<= br>+ =C2=A0 =C2=A0local rbuf =3D self.rbuf
+ =C2=A0 =C2=A0if rbuf:size()= =3D=3D 0 then
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0return nil
+ =C2=A0 =C2= =A0end
+
+ =C2=A0 =C2=A0return rbuf:size()
+end
+
=C2=A0loca= l function check_delimiter(self, limit, eols)
=C2=A0 =C2=A0 =C2=A0if lim= it =3D=3D 0 then
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0
@@ -1454,= 7 +1467,7 @@ local function lsocket_tcp_receive(self, pattern, prefix)
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0local result =3D { prefix }
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0local deadline =3D fiber.clock() + (self.timeout or= TIMEOUT_INFINITY)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0repeat
- =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0local data =3D socket_sysread(self)
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0local data =3D read(self, LIMIT_IN= FINITY, timeout, check_infinity)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if data =3D=3D nil then
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0if not errno_is_transient[self._errno] then
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0re= turn nil, socket_error(self)
diff --git a/test/app/socket.result b/test/= app/socket.result
index 0d029039a..77eff7370 100644
--- a/test/app/so= cket.result
+++ b/test/app/socket.result
@@ -2874,3 +2874,51 @@ test_= run:cmd("clear filter")
=C2=A0---
=C2=A0- true
=C2=A0...=
+-- case: sicket receive inconsistent behavior
+chan =3D fiber.chann= el()
+---
+...
+counter =3D 0
+---
+...
+fn =3D function(= s) counter =3D 0; while true do s:write((tostring(counter)):rep(chan:get())= ); counter =3D counter + 1 end end
+---
+...
+srv =3D socket.tcp_s= erver('0.0.0.0', 8888, fn)
+---
+...
+s =3D socket.connect= ('localhost', 8888)
+---
+...
+chan:put(5)
+---
+- t= rue
+...
+chan:put(5)
+---
+- true
+...
+s:receive(5)
= +---
+- '00000'
+...
+chan:put(5)
+---
+- true
+.= ..
+s:settimeout(1)
+---
+- 1
+...
+s:receive('*a')<= br>+---
+- '1111122222'
+...
+s:close()
+---
+- 1+...
+srv:close()
+---
+- true
+...
diff --git a/test/app/s= ocket.test.lua b/test/app/socket.test.lua
index dab168f90..7ae9a98aa 100= 644
--- a/test/app/socket.test.lua
+++ b/test/app/socket.test.lua
= @@ -983,3 +983,19 @@ client:read(1, 5) =3D=3D ''
=C2=A0server:cl= ose()
=C2=A0
=C2=A0test_run:cmd("clear filter")
+
+--= case: sicket receive inconsistent behavior
+chan =3D fiber.channel()+counter =3D 0
+fn =3D function(s) counter =3D 0; while true do s:write= ((tostring(counter)):rep(chan:get())); counter =3D counter + 1 end end
+= srv =3D socket.tcp_server('0.0.0.0', 8888, fn)
+s =3D socket.con= nect('localhost', 8888)
+chan:put(5)
+chan:put(5)
+s:recei= ve(5)
+chan:put(5)
+s:settimeout(1)
+s:receive('*a')
+s= :close()
+srv:close()
+
--
2.20.1
--00000000000034d895058bacbd7a--