]> Cypherpunks repositories - gostls13.git/commitdiff
net: unblock UDP Reads upon Close on plan9, add test
authorBrad Fitzpatrick <bradfitz@golang.org>
Mon, 10 Mar 2025 18:45:10 +0000 (11:45 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 11 Mar 2025 15:30:42 +0000 (08:30 -0700)
Fixes #72770

Change-Id: I42be7c7349961188f4b5d73287a3550aba323893
Reviewed-on: https://go-review.googlesource.com/c/go/+/656395
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: David du Colombier <0intro@gmail.com>
Reviewed-by: Russ Cox <rsc@golang.org>
src/net/fd_plan9.go
src/net/net_test.go

index da41bc0c34cac599b0c916b240777084ecc7c402..66a12e7d7dabdc2c886925f6b0486f2413d72fa3 100644 (file)
@@ -126,6 +126,11 @@ func (fd *netFD) Close() error {
                        return err
                }
        }
+       if fd.net == "udp" {
+               // The following line is required to unblock Reads.
+               // See https://go.dev/issue/72770.
+               fd.SetReadDeadline(time.Now().Add(-time.Hour))
+       }
        err := fd.ctl.Close()
        if fd.data != nil {
                if err1 := fd.data.Close(); err1 != nil && err == nil {
index 4a5dc3b73a6b440b0d69ce1562e1841b19d0e9fd..705ac45c6b7bfffa34fafb9fc5e48f14cb1f64f6 100644 (file)
@@ -508,6 +508,32 @@ func TestCloseUnblocksRead(t *testing.T) {
        withTCPConnPair(t, client, server)
 }
 
+// Issue 72770: verify that a blocked UDP read is woken up by a Close.
+func TestCloseUnblocksReadUDP(t *testing.T) {
+       t.Parallel()
+       pc, err := ListenPacket("udp", "127.0.0.1:0")
+       if err != nil {
+               t.Fatal(err)
+       }
+       time.AfterFunc(250*time.Millisecond, func() {
+               t.Logf("closing conn...")
+               pc.Close()
+       })
+       timer := time.AfterFunc(time.Second*10, func() {
+               panic("timeout waiting for Close")
+       })
+       defer timer.Stop()
+
+       n, src, err := pc.(*UDPConn).ReadFromUDPAddrPort([]byte{})
+
+       // Check for n > 0. Checking err == nil alone isn't enough;
+       // on macOS, it returns (n=0, src=0.0.0.0:0, err=nil).
+       if n > 0 {
+               t.Fatalf("unexpected Read success from ReadFromUDPAddrPort; read %d bytes from %v, err=%v", n, src, err)
+       }
+       t.Logf("got expected UDP read error")
+}
+
 // Issue 24808: verify that ECONNRESET is not temporary for read.
 func TestNotTemporaryRead(t *testing.T) {
        t.Parallel()