diff options
| author | Ian Lance Taylor <iant@golang.org> | 2018-03-06 14:12:45 -0800 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2018-03-06 23:21:25 +0000 |
| commit | 558769a61b246464f979f3f4d370dad96cee2109 (patch) | |
| tree | b0efbd840819eaed6357d7a3a2ebdd3efab9704b /src | |
| parent | 42ecf39e85a6960f4e0c2272bf9aff491eda3b66 (diff) | |
| download | go-558769a61b246464f979f3f4d370dad96cee2109.tar.xz | |
internal/poll: if poller init fails, assume blocking mode
Fixes #23943
Change-Id: I16e604872f1615963925ec3c4710106bcce1330c
Reviewed-on: https://go-review.googlesource.com/99015
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/internal/poll/fd_unix.go | 8 | ||||
| -rw-r--r-- | src/os/timeout_test.go | 33 |
2 files changed, 40 insertions, 1 deletions
diff --git a/src/internal/poll/fd_unix.go b/src/internal/poll/fd_unix.go index 372dc81633..36376ef6cb 100644 --- a/src/internal/poll/fd_unix.go +++ b/src/internal/poll/fd_unix.go @@ -59,7 +59,13 @@ func (fd *FD) Init(net string, pollable bool) error { fd.isBlocking = true return nil } - return fd.pd.init(fd) + err := fd.pd.init(fd) + if err != nil { + // If we could not initialize the runtime poller, + // assume we are using blocking mode. + fd.isBlocking = true + } + return err } // Destroy closes the file descriptor. This is called when there are diff --git a/src/os/timeout_test.go b/src/os/timeout_test.go index 6f47ed04a9..6105f9b1a1 100644 --- a/src/os/timeout_test.go +++ b/src/os/timeout_test.go @@ -587,3 +587,36 @@ func TestRacyWrite(t *testing.T) { }() } } + +// Closing a TTY while reading from it should not hang. Issue 23943. +func TestTTYClose(t *testing.T) { + f, err := os.Open("/dev/tty") + if err != nil { + t.Skipf("skipping because opening /dev/tty failed: %v", err) + } + + go func() { + var buf [1]byte + f.Read(buf[:]) + }() + + // Give the goroutine a chance to enter the read. + // It doesn't matter much if it occasionally fails to do so, + // we won't be testing what we want to test but the test will pass. + time.Sleep(time.Millisecond) + + c := make(chan bool) + go func() { + defer close(c) + f.Close() + }() + + select { + case <-c: + case <-time.After(time.Second): + t.Error("timed out waiting for close") + } + + // On some systems the goroutines may now be hanging. + // There's not much we can do about that. +} |
