Skip to content

Commit 368f73b

Browse files
committed
net: unblock plan9 TCP Read calls after socket close
Fixes #7782 Fixes #9554 Updates #7237 (original metabug, before we switched to specific bugs) Updates #11932 (plan9 still doesn't have net I/O deadline support) Change-Id: I96f311b88b1501d884ebc008fd31ad2cf1e16d75 Reviewed-on: https://go-review.googlesource.com/15941 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: David du Colombier <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 7d86d57 commit 368f73b

File tree

5 files changed

+37
-16
lines changed

5 files changed

+37
-16
lines changed

src/net/dial_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,9 @@ func TestDialerFallbackDelay(t *testing.T) {
509509
}
510510

511511
func TestDialSerialAsyncSpuriousConnection(t *testing.T) {
512+
if runtime.GOOS == "plan9" {
513+
t.Skip("skipping on plan9; no deadline support, golang.org/issue/11932")
514+
}
512515
ln, err := newLocalListener("tcp")
513516
if err != nil {
514517
t.Fatal(err)

src/net/fd_plan9.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ func (fd *netFD) Close() error {
171171
if !fd.ok() {
172172
return syscall.EINVAL
173173
}
174+
if fd.net == "tcp" {
175+
// The following line is required to unblock Reads.
176+
// For some reason, WriteString returns an error:
177+
// "write /net/tcp/39/listen: inappropriate use of fd"
178+
// But without it, Reads on dead conns hang forever.
179+
// See Issue 9554.
180+
fd.ctl.WriteString("hangup")
181+
}
174182
err := fd.ctl.Close()
175183
if fd.data != nil {
176184
if err1 := fd.data.Close(); err1 != nil && err == nil {

src/net/http/httputil/reverseproxy_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"net/http/httptest"
1515
"net/url"
1616
"reflect"
17-
"runtime"
1817
"strings"
1918
"testing"
2019
"time"
@@ -226,9 +225,6 @@ func TestReverseProxyFlushInterval(t *testing.T) {
226225
}
227226

228227
func TestReverseProxyCancelation(t *testing.T) {
229-
if runtime.GOOS == "plan9" {
230-
t.Skip("skipping test; see https://golang.org/issue/9554")
231-
}
232228
const backendResponse = "I am the backend"
233229

234230
reqInFlight := make(chan struct{})

src/net/http/serve_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"os/exec"
2727
"reflect"
2828
"runtime"
29+
"sort"
2930
"strconv"
3031
"strings"
3132
"sync"
@@ -2980,6 +2981,7 @@ func TestServerConnState(t *testing.T) {
29802981
if _, err := io.WriteString(c, "BOGUS REQUEST\r\n\r\n"); err != nil {
29812982
t.Fatal(err)
29822983
}
2984+
c.Read(make([]byte, 1)) // block until server hangs up on us
29832985
c.Close()
29842986
}
29852987

@@ -3013,9 +3015,14 @@ func TestServerConnState(t *testing.T) {
30133015
}
30143016
logString := func(m map[int][]ConnState) string {
30153017
var b bytes.Buffer
3016-
for id, l := range m {
3018+
var keys []int
3019+
for id := range m {
3020+
keys = append(keys, id)
3021+
}
3022+
sort.Ints(keys)
3023+
for _, id := range keys {
30173024
fmt.Fprintf(&b, "Conn %d: ", id)
3018-
for _, s := range l {
3025+
for _, s := range m[id] {
30193026
fmt.Fprintf(&b, "%s ", s)
30203027
}
30213028
b.WriteString("\n")

src/net/http/transport_test.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -874,9 +874,6 @@ func TestTransportGzipShort(t *testing.T) {
874874

875875
// tests that persistent goroutine connections shut down when no longer desired.
876876
func TestTransportPersistConnLeak(t *testing.T) {
877-
if runtime.GOOS == "plan9" {
878-
t.Skip("skipping test; see https://golang.org/issue/7237")
879-
}
880877
defer afterTest(t)
881878
gotReqCh := make(chan bool)
882879
unblockCh := make(chan bool)
@@ -943,9 +940,6 @@ func TestTransportPersistConnLeak(t *testing.T) {
943940
// golang.org/issue/4531: Transport leaks goroutines when
944941
// request.ContentLength is explicitly short
945942
func TestTransportPersistConnLeakShortBody(t *testing.T) {
946-
if runtime.GOOS == "plan9" {
947-
t.Skip("skipping test; see https://golang.org/issue/7237")
948-
}
949943
defer afterTest(t)
950944
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
951945
}))
@@ -2291,15 +2285,28 @@ type errorReader struct {
22912285

22922286
func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
22932287

2288+
type plan9SleepReader struct{}
2289+
2290+
func (plan9SleepReader) Read(p []byte) (int, error) {
2291+
if runtime.GOOS == "plan9" {
2292+
// After the fix to unblock TCP Reads in
2293+
// https://golang.org/cl/15941, this sleep is required
2294+
// on plan9 to make sure TCP Writes before an
2295+
// immediate TCP close go out on the wire. On Plan 9,
2296+
// it seems that a hangup of a TCP connection with
2297+
// queued data doesn't send the queued data first.
2298+
// https://golang.org/issue/9554
2299+
time.Sleep(50 * time.Millisecond)
2300+
}
2301+
return 0, io.EOF
2302+
}
2303+
22942304
type closerFunc func() error
22952305

22962306
func (f closerFunc) Close() error { return f() }
22972307

22982308
// Issue 6981
22992309
func TestTransportClosesBodyOnError(t *testing.T) {
2300-
if runtime.GOOS == "plan9" {
2301-
t.Skip("skipping test; see https://golang.org/issue/7782")
2302-
}
23032310
defer afterTest(t)
23042311
readBody := make(chan error, 1)
23052312
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -2313,7 +2320,7 @@ func TestTransportClosesBodyOnError(t *testing.T) {
23132320
io.Reader
23142321
io.Closer
23152322
}{
2316-
io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}),
2323+
io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), plan9SleepReader{}, errorReader{fakeErr}),
23172324
closerFunc(func() error {
23182325
select {
23192326
case didClose <- true:

0 commit comments

Comments
 (0)