login

<     >

2023-08-27 14:13:33 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

tcp: must consume all ready data in EPOLLET mode

diff --git a/lib/ludweb/tcp.lua b/lib/ludweb/tcp.lua
index 9f56e4a..88076bb 100644
--- a/lib/ludweb/tcp.lua
+++ b/lib/ludweb/tcp.lua
@@ -122,30 +122,38 @@ function TCP:run()
         -- the loop below will run zero times if nfds < 1, ignoring errors
         for n = 0, nfds-1 do
             if evs[n].data.fd == self.sockfd then
-                local newfd = C.accept(self.sockfd, nil, nil)
-                if newfd < 0 then break end
-                ev[0].events = bit.bor(C.EPOLLIN, C.EPOLLET)
-                ev[0].data.fd = newfd
-                assert(C.epoll_ctl(efd, C.EPOLL_CTL_ADD, newfd, ev) >= 0, "epoll_ctl error")
-                curfds = curfds + 1
+                while true do
+                    local newfd = C.accept(self.sockfd, nil, nil)
+                    if newfd == -1 then break end
+                    set_non_blocking(newfd)
+                    ev[0].events = bit.bor(C.EPOLLIN, C.EPOLLET)
+                    ev[0].data.fd = newfd
+                    assert(C.epoll_ctl(efd, C.EPOLL_CTL_ADD, newfd, ev) >= 0, "epoll_ctl error")
+                    curfds = curfds + 1
+                end
             else
-                local size = C.recv(evs[n].data.fd, buffer, buflen, 0)
                 local can_close = false
-                if size == 0 then
-                    can_close = true
-                elseif size > 0 then
-                    datain[n] = (datain[n] or "") .. ffi.string(buffer, size)
-                    if self:request_ready(datain[n]) then
-                        local dataout, keep_alive = self:process(datain[n])
-                        if dataout == nil then
-                            running = false
-                        else
-                            C.send(evs[n].data.fd, dataout, #dataout, 0)
-                        end
-                        if not keep_alive then
-                            can_close = true
+                while true do
+                    local size = C.recv(evs[n].data.fd, buffer, buflen, 0)
+                    if size == -1 then
+                        break
+                    elseif size == 0 then
+                        can_close = true
+                        break
+                    else
+                        datain[n] = (datain[n] or "") .. ffi.string(buffer, size)
+                        if self:request_ready(datain[n]) then
+                            local dataout, keep_alive = self:process(datain[n])
+                            if dataout == nil then
+                                running = false
+                            else
+                                C.send(evs[n].data.fd, dataout, #dataout, 0)
+                            end
+                            if not keep_alive then
+                                can_close = true
+                            end
+                            datain[n] = ""
                         end
-                        datain[n] = ""
                     end
                 end
                 if can_close then