# HG changeset patch # User Kim Alvefur # Date 1626442718 -7200 # Node ID 6c3d8aa3bbd9f2bbf5339b95bbe94bb6db4454d8 # Parent 917eca7be82b6567ecfba850e98d48f8d4dae361 net.server_epoll: Avoid allocating a buffer table for single writes writebuffer is now string | { string } Saves the allocation of a buffer table until the second write, which could be rare, especially with opportunistic writes. diff -r 917eca7be82b -r 6c3d8aa3bbd9 net/server_epoll.lua --- a/net/server_epoll.lua Fri Jul 16 02:28:32 2021 +0200 +++ b/net/server_epoll.lua Fri Jul 16 15:38:38 2021 +0200 @@ -471,11 +471,18 @@ self:onconnect(); if not self.conn then return; end -- could have been closed in onconnect local buffer = self.writebuffer; - local data = #buffer == 1 and buffer[1] or t_concat(buffer); + local data = buffer or ""; + if type(buffer) == "table" then + if buffer[2] then + data = t_concat(data); + else + data = buffer[1] or ""; + end + end local ok, err, partial = self.conn:send(data); if ok then self:set(nil, false); - if cfg.keep_buffers then + if cfg.keep_buffers and type(buffer) == "table" then for i = #buffer, 1, -1 do buffer[i] = nil; end @@ -487,13 +494,13 @@ return ok; elseif partial then self:debug("Sent %d out of %d buffered bytes", partial, #data); - if cfg.keep_buffers then + if cfg.keep_buffers and type(buffer) == "table" then buffer[1] = data:sub(partial+1); for i = #buffer, 2, -1 do buffer[i] = nil; end else - data.writebuffer = { data:sub(partial+1) }; + data.writebuffer = data:sub(partial+1); end self:set(nil, true); self:setwritetimeout(); @@ -517,11 +524,13 @@ -- Add data to write buffer and set flag for wanting to write function interface:write(data) local buffer = self.writebuffer; - if buffer then + if type(buffer) == "table" then t_insert(buffer, data); - else + elseif type(buffer) == "string" then self:noise("Allocating buffer!") - self.writebuffer = { data }; + self.writebuffer = { buffer, data }; + elseif buffer == nil then + self.writebuffer = data; end if not self._write_lock then if cfg.opportunistic_writes and not self._opportunistic_write then @@ -539,7 +548,7 @@ -- Close, possibly after writing is done function interface:close() - if self.writebuffer and self.writebuffer[1] then + if self.writebuffer and (self.writebuffer[1] or type(self.writebuffer) == "string") then self:set(false, true); -- Flush final buffer contents self:setwritetimeout(); self.write, self.send = noop, noop; -- No more writing @@ -578,7 +587,7 @@ function interface:starttls(tls_ctx) if tls_ctx then self.tls_ctx = tls_ctx; end self.starttls = false; - if self.writebuffer and self.writebuffer[1] then + if self.writebuffer and (self.writebuffer[1] or type(self.writebuffer) == "string") then self:debug("Start TLS after write"); self.ondrain = interface.starttls; self:set(nil, true); -- make sure wantwrite is set @@ -687,7 +696,7 @@ created = realtime(); listeners = listeners; read_size = read_size or (server and server.read_size); - writebuffer = {}; + writebuffer = nil; tls_ctx = tls_ctx or (server and server.tls_ctx); tls_direct = server and server.tls_direct; id = conn_id; @@ -811,7 +820,7 @@ end self:noise("Resume writes"); self._write_lock = nil; - if self.writebuffer[1] then + if self.writebuffer and (self.writebuffer[1] or type(self.writebuffer) == "string") then self:setwritetimeout(); self:set(nil, true); end