# HG changeset patch # User Kim Alvefur # Date 1637248903 -3600 # Node ID ff4e34c448a44d8bb6bc459f9a4c6e8ec80c43e8 # Parent fae5441fc6cf4b1109d8cf9fd239424733911663 net.server_epoll: Try harder to avoid reentrant opportunistic writes Opportunistic writes sure do complicate things. This is especially intended to avoid opportunistic_writes from within the onpredrain callback. diff -r fae5441fc6cf -r ff4e34c448a4 net/server_epoll.lua --- a/net/server_epoll.lua Thu Nov 18 01:57:21 2021 +0100 +++ b/net/server_epoll.lua Thu Nov 18 16:21:43 2021 +0100 @@ -487,6 +487,7 @@ -- Called when socket is writable function interface:onwritable() + self._writing = true; -- prevent reentrant writes etc self:onconnect(); if not self.conn then return; end -- could have been closed in onconnect self:on("predrain"); @@ -514,6 +515,7 @@ end self:setwritetimeout(false); self:ondrain(); -- Be aware of writes in ondrain + self._writing = nil; return ok; elseif partial then self:debug("Sent %d out of %d buffered bytes", partial, #data); @@ -528,6 +530,7 @@ self:set(nil, true); self:setwritetimeout(); end + self._writing = nil; if err == "wantwrite" or err == "timeout" then self:set(nil, true); self:setwritetimeout(); @@ -557,7 +560,7 @@ elseif buffer == nil then self.writebuffer = data; end - if not self._write_lock then + if not self._write_lock and not self._writing then if self._writable and cfg.opportunistic_writes and not self._opportunistic_write then self._opportunistic_write = true; local ret, err = self:onwritable();