[Backport] Fixes callbacks being dropped on Linux/macOS/BSD. (#15012)

Fixes #15003.

This is a serious bug which occurs when data cannot be read/sent
immediately and there are a bunch of other read/write events
pending. What happens is that the new events are dropped which
results in the case of the reported bug resulted in some data not
being sent (!).
This commit is contained in:
Dominik Picheta 2020-07-19 07:41:36 +01:00 • committed by GitHub
commit 1e3a0ef1e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 1 deletions

View file

@ -1228,14 +1228,19 @@ else:
let newLength = max(len(curList), InitCallbackListSize)
var newList = newSeqOfCap[Callback](newLength)
var eventsExtinguished = false
for cb in curList:
if eventsExtinguished:
newList.add(cb)
continue
if not cb(fd):
# Callback wants to be called again.
newList.add(cb)
# This callback has returned with EAGAIN, so we don't need to
# call any other callbacks as they are all waiting for the same event
# on the same fd.
break
# We do need to ensure they are called again though.
eventsExtinguished = true
withData(selector, fd.int, fdData) do:
# Descriptor is still present in the queue.