github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/testdata/testprognet/waiters.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "io" 10 "log" 11 "net" 12 "runtime/internal/atomic" 13 "sync" 14 "time" 15 _ "unsafe" // for go:linkname 16 ) 17 18 // The bug is that netpollWaiters increases monotonically. 19 // This doesn't cause a problem until it overflows. 20 // Use linkname to see the value. 21 // 22 //go:linkname netpollWaiters runtime.netpollWaiters 23 var netpollWaiters atomic.Uint32 24 25 func init() { 26 register("NetpollWaiters", NetpollWaiters) 27 } 28 29 func NetpollWaiters() { 30 listener, err := net.Listen("tcp", "127.0.0.1:0") 31 if err != nil { 32 log.Fatal(err) 33 } 34 35 var wg sync.WaitGroup 36 wg.Add(1) 37 go func() { 38 defer wg.Done() 39 conn, err := listener.Accept() 40 if err != nil { 41 log.Fatal(err) 42 } 43 defer conn.Close() 44 if _, err := io.Copy(io.Discard, conn); err != nil { 45 log.Fatal(err) 46 } 47 }() 48 49 wg.Add(1) 50 go func() { 51 defer wg.Done() 52 conn, err := net.Dial("tcp", listener.Addr().String()) 53 if err != nil { 54 log.Fatal(err) 55 } 56 defer conn.Close() 57 for i := 0; i < 10; i++ { 58 fmt.Fprintf(conn, "%d\n", i) 59 time.Sleep(time.Millisecond) 60 } 61 }() 62 63 wg.Wait() 64 if v := netpollWaiters.Load(); v != 0 { 65 log.Fatalf("current waiters %v", v) 66 } 67 68 fmt.Println("OK") 69 }