"net/internal/socktest"
"os"
"runtime"
- "sync"
"testing"
"time"
)
}
}
-func TestListenCloseListen(t *testing.T) {
- if testing.Short() {
- t.Parallel()
- }
-
- ln := newLocalListener(t, "tcp")
- addr := ln.Addr().String()
-
- var wg sync.WaitGroup
- wg.Add(1)
- go func() {
- for {
- c, err := ln.Accept()
- if err != nil {
- wg.Done()
- return
- }
- wg.Add(1)
- go func() {
- io.Copy(io.Discard, c)
- c.Close()
- wg.Done()
- }()
- }
- }()
- defer wg.Wait()
-
- // Keep a connection alive while we close the listener to try to discourage
- // the kernel from reusing the listener's port for some other process.
- //
- // TODO(bcmills): This empirically seems to work, and we also rely on it in
- // TestDialClosedPortFailFast, but I can't find a reference documenting this
- // port-reuse behavior.
- c, err := Dial("tcp", addr)
- defer c.Close()
-
- if err := ln.Close(); err != nil {
- if perr := parseCloseError(err, false); perr != nil {
- t.Error(perr)
- }
- t.Fatal(err)
- }
-
- if !testing.Short() {
- // Burn through some ephemeral ports (without actually accepting any
- // connections on them) to try to encourage the kernel to reuse the address
- // if it is going to.
- lns := make(chan []Listener, 1)
- lns <- nil
- for i := 0; i < 4000; i++ {
- ln := newLocalListener(t, "tcp")
- lns <- append(<-lns, ln)
- }
- defer func() {
- for _, ln := range <-lns {
- ln.Close()
- }
- }()
- }
-
- ln, err = Listen("tcp", addr)
- if err == nil {
- // Success. (This test didn't always make it here earlier.)
- ln.Close()
- return
- }
- t.Fatalf("failed to listen/close/listen on same address")
-}
-
// See golang.org/issue/6163, golang.org/issue/6987.
func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
switch runtime.GOOS {