]> Cypherpunks repositories - gostls13.git/commitdiff
internal/poll: if poller init fails, assume blocking mode
authorIan Lance Taylor <iant@golang.org>
Tue, 6 Mar 2018 22:12:45 +0000 (14:12 -0800)
committerIan Lance Taylor <iant@golang.org>
Tue, 6 Mar 2018 23:21:25 +0000 (23:21 +0000)
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>

src/internal/poll/fd_unix.go
src/os/timeout_test.go

index 372dc816335a7d1075d62fa979a92a70492e2f17..36376ef6cbb787bab319259e8f1cda9fcd245a8a 100644 (file)
@@ -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
index 6f47ed04a9748d892977050575794a5d3f9529a2..6105f9b1a1e952d4130e6a7c0d204a9429c80be5 100644 (file)
@@ -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.
+}