This mimics the apparent behavior of writes on linux/amd64, in which a
write on an already-closed connection silently succeeds — even if the
connection has already been closed by the remote end — provided that
the packet fits in the kernel's send buffer.
I tested this by patching in CL 557437 and running the test on js/wasm
and wasip1/wasm locally.
Fixes #64317.
Change-Id: I43f6a89e5059115cb61e4ffc33a8371057cb67a1
Reviewed-on: https://go-review.googlesource.com/c/go/+/558915
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
func (pq *packetQueue) closeRead() error {
q := pq.get()
-
- // Discard any unread packets.
- for q.head != nil {
- p := q.head
- q.head = p.next
- p.clear()
- packetPool.Put(p)
- }
- q.nBytes = 0
-
q.readClosed = true
pq.put(q)
return nil
}
if q.writeClosed {
return 0, ErrClosed
- } else if q.readClosed {
+ } else if q.readClosed && q.nBytes >= q.readBufferBytes {
return 0, os.NewSyscallError("send", syscall.ECONNRESET)
}
}
defer func() { pq.put(q) }()
+ if q.readClosed {
+ return 0, nil, ErrClosed
+ }
+
p := q.head
if p == nil {
switch {
- case q.readClosed:
- return 0, nil, ErrClosed
case q.writeClosed:
if q.noLinger {
return 0, nil, os.NewSyscallError("recvfrom", syscall.ECONNRESET)