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