...

Source file src/net/write_unix_test.go

Documentation: net

		 1  // Copyright 2017 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  //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
		 6  // +build darwin dragonfly freebsd linux netbsd openbsd solaris
		 7  
		 8  package net
		 9  
		10  import (
		11  	"bytes"
		12  	"syscall"
		13  	"testing"
		14  	"time"
		15  )
		16  
		17  // Test that a client can't trigger an endless loop of write system
		18  // calls on the server by shutting down the write side on the client.
		19  // Possibility raised in the discussion of https://golang.org/cl/71973.
		20  func TestEndlessWrite(t *testing.T) {
		21  	t.Parallel()
		22  	c := make(chan bool)
		23  	server := func(cs *TCPConn) error {
		24  		cs.CloseWrite()
		25  		<-c
		26  		return nil
		27  	}
		28  	client := func(ss *TCPConn) error {
		29  		// Tell the server to return when we return.
		30  		defer close(c)
		31  
		32  		// Loop writing to the server. The server is not reading
		33  		// anything, so this will eventually block, and then time out.
		34  		b := bytes.Repeat([]byte{'a'}, 8192)
		35  		cagain := 0
		36  		for {
		37  			n, err := ss.conn.fd.pfd.WriteOnce(b)
		38  			if n > 0 {
		39  				cagain = 0
		40  			}
		41  			switch err {
		42  			case nil:
		43  			case syscall.EAGAIN:
		44  				if cagain == 0 {
		45  					// We've written enough data to
		46  					// start blocking. Set a deadline
		47  					// so that we will stop.
		48  					ss.SetWriteDeadline(time.Now().Add(5 * time.Millisecond))
		49  				}
		50  				cagain++
		51  				if cagain > 20 {
		52  					t.Error("looping on EAGAIN")
		53  					return nil
		54  				}
		55  				if err = ss.conn.fd.pfd.WaitWrite(); err != nil {
		56  					t.Logf("client WaitWrite: %v", err)
		57  					return nil
		58  				}
		59  			default:
		60  				// We expect to eventually get an error.
		61  				t.Logf("client WriteOnce: %v", err)
		62  				return nil
		63  			}
		64  		}
		65  	}
		66  	withTCPConnPair(t, client, server)
		67  }
		68  

View as plain text