</dd>
</dl>
+<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
+ <dd>
+ <p><!-- CL -->
+ If an I/O operation exceeds a deadline set by
+ the <a href="/pkg/net/#Conn"><code>Conn.SetDeadline</code></a>,
+ <code>Conn.SetReadDeadline</code>,
+ or <code>Conn.SetWriteDeadline</code> methods, it will now
+ return an error that is or wraps
+ <a href="/pkg/os#ErrDeadlineExceeded"><code>os.ErrDeadlineExceeded</code></a>.
+ This may be used to reliably detect whether an error is due to
+ an exceeded deadline.
+ Earlier releases recommended calling the <code>Timeout</code>
+ method on the error, but I/O operations can return errors for
+ which <code>Timeout</code> returns <code>true</code> although a
+ deadline has not been exceeded.
+ </p>
+ </dd>
+</dl>
+
<dl id="net/http/pprof"><dt><a href="/pkg/net/http/pprof/">net/http/pprof</a></dt>
<dd>
<p><!-- CL 147598, 229537 -->
</dd>
</dl>
+<dl id="os"><dt><a href="/pkg/os/">os</a></dt>
+ <dd>
+ <p><!-- CL -->
+ If an I/O operation exceeds a deadline set by
+ the <a href="/pkg/os/#File.SetDeadline"><code>File.SetDeadline</code></a>,
+ <a href="/pkg/os/#File.SetReadDeadline"><code>File.SetReadDeadline</code></a>,
+ or <a href="/pkg/os/#File.SetWriteDeadline"><code>File.SetWriteDeadline</code></a>
+ methods, it will now return an error that is or wraps
+ <a href="/pkg/os#ErrDeadlineExceeded"><code>os.ErrDeadlineExceeded</code></a>.
+ This may be used to reliably detect whether an error is due to
+ an exceeded deadline.
+ Earlier releases recommended calling the <code>Timeout</code>
+ method on the error, but I/O operations can return errors for
+ which <code>Timeout</code> returns <code>true</code> although a
+ deadline has not been exceeded.
+ </p>
+ </dd>
+</dl>
+
<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
<dd>
<p><!-- CL 228902 -->
return ErrNetClosing
}
-// ErrTimeout is returned for an expired deadline.
-var ErrTimeout error = &TimeoutError{}
+// ErrDeadlineExceeded is returned for an expired deadline.
+// This is exported by the os package as os.ErrDeadlineExceeded.
+var ErrDeadlineExceeded error = &DeadlineExceededError{}
-// TimeoutError is returned for an expired deadline.
-type TimeoutError struct{}
+// DeadlineExceededError is returned for an expired deadline.
+type DeadlineExceededError struct{}
// Implement the net.Error interface.
-func (e *TimeoutError) Error() string { return "i/o timeout" }
-func (e *TimeoutError) Timeout() bool { return true }
-func (e *TimeoutError) Temporary() bool { return true }
+// The string is "i/o timeout" because that is what was returned
+// by earlier Go versions. Changing it may break programs that
+// match on error strings.
+func (e *DeadlineExceededError) Error() string { return "i/o timeout" }
+func (e *DeadlineExceededError) Timeout() bool { return true }
+func (e *DeadlineExceededError) Temporary() bool { return true }
// ErrNotPollable is returned when the file or socket is not suitable
// for event notification.
// Read implements io.Reader.
func (fd *FD) Read(fn func([]byte) (int, error), b []byte) (int, error) {
if fd.rtimedout.isSet() {
- return 0, ErrTimeout
+ return 0, ErrDeadlineExceeded
}
if err := fd.readLock(); err != nil {
return 0, err
err = io.EOF
}
if isInterrupted(err) {
- err = ErrTimeout
+ err = ErrDeadlineExceeded
}
return n, err
}
// Write implements io.Writer.
func (fd *FD) Write(fn func([]byte) (int, error), b []byte) (int, error) {
if fd.wtimedout.isSet() {
- return 0, ErrTimeout
+ return 0, ErrDeadlineExceeded
}
if err := fd.writeLock(); err != nil {
return 0, err
n, err := fd.waio.Wait()
fd.waio = nil
if isInterrupted(err) {
- err = ErrTimeout
+ err = ErrDeadlineExceeded
}
return n, err
}
if isFile { // TODO(neelance): wasm: Use callbacks from JS to block until the read/write finished.
return nil
}
- return ErrTimeout
+ return ErrDeadlineExceeded
}
func (pd *pollDesc) waitRead(isFile bool) error { return pd.wait('r', isFile) }
case pollErrClosing:
return errClosing(isFile)
case pollErrTimeout:
- return ErrTimeout
+ return ErrDeadlineExceeded
case pollErrNotPollable:
return ErrNotPollable
}
// IO is interrupted by "close" or "timeout"
netpollErr := err
switch netpollErr {
- case ErrNetClosing, ErrFileClosing, ErrTimeout:
+ case ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded:
// will deal with those.
default:
panic("unexpected runtime.netpoll error: " + netpollErr.Error())
import (
"context"
"internal/nettrace"
- "internal/poll"
"syscall"
"time"
)
}
timeRemaining := deadline.Sub(now)
if timeRemaining <= 0 {
- return time.Time{}, poll.ErrTimeout
+ return time.Time{}, errTimeout
}
// Tentatively allocate equal time to each remaining address.
timeout := timeRemaining / time.Duration(addrsRemaining)
import (
"bufio"
"context"
- "internal/poll"
"internal/testenv"
"io"
"os"
{now, noDeadline, 1, noDeadline, nil},
// Step the clock forward and cross the deadline.
{now.Add(-1 * time.Millisecond), now, 1, now, nil},
- {now.Add(0 * time.Millisecond), now, 1, noDeadline, poll.ErrTimeout},
- {now.Add(1 * time.Millisecond), now, 1, noDeadline, poll.ErrTimeout},
+ {now.Add(0 * time.Millisecond), now, 1, noDeadline, errTimeout},
+ {now.Add(1 * time.Millisecond), now, 1, noDeadline, errTimeout},
}
for i, tt := range testCases {
deadline, err := partialDeadline(tt.now, tt.deadline, tt.addrs)
"context"
"errors"
"fmt"
- "internal/poll"
"io/ioutil"
"os"
"path"
break
default:
time.Sleep(10 * time.Millisecond)
- return dnsmessage.Message{}, poll.ErrTimeout
+ return dnsmessage.Message{}, os.ErrDeadlineExceeded
}
r := dnsmessage.Message{
Header: dnsmessage.Header{
if s == "192.0.2.1:53" {
deadline0 = deadline
time.Sleep(10 * time.Millisecond)
- return dnsmessage.Message{}, poll.ErrTimeout
+ return dnsmessage.Message{}, os.ErrDeadlineExceeded
}
if deadline.Equal(deadline0) {
}
makeTimeout := func() error {
return &DNSError{
- Err: poll.ErrTimeout.Error(),
+ Err: os.ErrDeadlineExceeded.Error(),
Name: name,
Server: server,
IsTimeout: true,
Questions: q.Questions,
}, nil
case resolveTimeout:
- return dnsmessage.Message{}, poll.ErrTimeout
+ return dnsmessage.Message{}, os.ErrDeadlineExceeded
default:
t.Fatal("Impossible resolveWhich")
}
switch q.Questions[0].Name.String() {
case searchX:
- return dnsmessage.Message{}, poll.ErrTimeout
+ return dnsmessage.Message{}, os.ErrDeadlineExceeded
case searchY:
return mockTXTResponse(q), nil
default:
var wantRRs int
if strict {
wantErr = &DNSError{
- Err: poll.ErrTimeout.Error(),
+ Err: os.ErrDeadlineExceeded.Error(),
Name: name,
Server: server,
IsTimeout: true,
fake := fakeDNSServer{rh: func(n, s string, q dnsmessage.Message, t time.Time) (dnsmessage.Message, error) {
time.Sleep(10 * time.Microsecond)
- return dnsmessage.Message{}, poll.ErrTimeout
+ return dnsmessage.Message{}, os.ErrDeadlineExceeded
}}
r := Resolver{PreferGo: true, Dial: fake.DialContext}
return nil
}
switch err := nestedErr.(type) {
- case *AddrError, addrinfoErrno, *DNSError, InvalidAddrError, *ParseError, *poll.TimeoutError, UnknownNetworkError:
+ case *AddrError, addrinfoErrno, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError:
return nil
case *os.SyscallError:
nestedErr = err.Err
goto third
}
switch nestedErr {
- case poll.ErrNetClosing, poll.ErrTimeout, poll.ErrNotPollable:
+ case poll.ErrNetClosing, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
return nil
}
switch err := nestedErr.(type) {
- case *AddrError, addrinfoErrno, *DNSError, InvalidAddrError, *ParseError, *poll.TimeoutError, UnknownNetworkError:
+ case *AddrError, addrinfoErrno, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError:
return nil
case *os.SyscallError:
nestedErr = err.Err
goto third
}
switch nestedErr {
- case errCanceled, poll.ErrNetClosing, errMissingAddress, poll.ErrTimeout, ErrWriteToConnected, io.ErrUnexpectedEOF:
+ case errCanceled, poll.ErrNetClosing, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
goto third
}
switch nestedErr {
- case poll.ErrNetClosing, poll.ErrTimeout, poll.ErrNotPollable:
+ case poll.ErrNetClosing, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
import (
"context"
"errors"
- "internal/poll"
"io"
"os"
"sync"
// SetReadDeadline and SetWriteDeadline.
//
// A deadline is an absolute time after which I/O operations
- // fail with a timeout (see type Error) instead of
- // blocking. The deadline applies to all future and pending
- // I/O, not just the immediately following call to Read or
- // Write. After a deadline has been exceeded, the connection
- // can be refreshed by setting a deadline in the future.
+ // fail instead of blocking. The deadline applies to all future
+ // and pending I/O, not just the immediately following call to
+ // Read or Write. After a deadline has been exceeded, the
+ // connection can be refreshed by setting a deadline in the future.
+ //
+ // If the deadline is exceeded a call to Read or Write or to other
+ // I/O methods will return an error that wraps os.ErrDeadlineExceeded.
+ // This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
+ // The error's Timeout method will return true, but note that there
+ // are other possible errors for which the Timeout method will
+ // return true even if the deadline has not been exceeded.
//
// An idle timeout can be implemented by repeatedly extending
// the deadline after successful Read or Write calls.
//
// A zero value for t means I/O operations will not time out.
- //
- // Note that if a TCP connection has keep-alive turned on,
- // which is the default unless overridden by Dialer.KeepAlive
- // or ListenConfig.KeepAlive, then a keep-alive failure may
- // also return a timeout error. On Unix systems a keep-alive
- // failure on I/O can be detected using
- // errors.Is(err, syscall.ETIMEDOUT).
SetDeadline(t time.Time) error
// SetReadDeadline sets the deadline for future Read calls
case context.Canceled:
return errCanceled
case context.DeadlineExceeded:
- return poll.ErrTimeout
+ return errTimeout
default:
return err
}
func (e InvalidAddrError) Timeout() bool { return false }
func (e InvalidAddrError) Temporary() bool { return false }
+// errTimeout exists to return the historical "i/o timeout" string
+// for context.DeadlineExceeded. See mapErr.
+// It is also used when Dialer.Deadline is exceeded.
+//
+// TODO(iant): We could consider changing this to os.ErrDeadlineExceeded
+// in the future, but note that that would conflict with the TODO
+// at mapErr that suggests changing it to context.DeadlineExceeded.
+var errTimeout error = &timeoutError{}
+
+type timeoutError struct{}
+
+func (e *timeoutError) Error() string { return "i/o timeout" }
+func (e *timeoutError) Timeout() bool { return true }
+func (e *timeoutError) Temporary() bool { return true }
+
// DNSConfigError represents an error reading the machine's DNS configuration.
// (No longer used; kept for compatibility.)
type DNSConfigError struct {
import (
"io"
+ "os"
"sync"
"time"
)
}
}
-type timeoutError struct{}
-
-func (timeoutError) Error() string { return "deadline exceeded" }
-func (timeoutError) Timeout() bool { return true }
-func (timeoutError) Temporary() bool { return true }
-
type pipeAddr struct{}
func (pipeAddr) Network() string { return "pipe" }
case isClosedChan(p.remoteDone):
return 0, io.EOF
case isClosedChan(p.readDeadline.wait()):
- return 0, timeoutError{}
+ return 0, os.ErrDeadlineExceeded
}
select {
case <-p.remoteDone:
return 0, io.EOF
case <-p.readDeadline.wait():
- return 0, timeoutError{}
+ return 0, os.ErrDeadlineExceeded
}
}
case isClosedChan(p.remoteDone):
return 0, io.ErrClosedPipe
case isClosedChan(p.writeDeadline.wait()):
- return 0, timeoutError{}
+ return 0, os.ErrDeadlineExceeded
}
p.wrMu.Lock() // Ensure entirety of b is written together
case <-p.remoteDone:
return n, io.ErrClosedPipe
case <-p.writeDeadline.wait():
- return n, timeoutError{}
+ return n, os.ErrDeadlineExceeded
}
}
return n, nil
if perr := parseWriteError(err); perr != nil {
t.Error(perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Errorf("got %v; want timeout", err)
}
if _, err = readRawConn(cc, b[:]); err == nil {
if perr := parseReadError(err); perr != nil {
t.Error(perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Errorf("got %v; want timeout", err)
}
if perr := parseReadError(err); perr != nil {
t.Error(perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Errorf("got %v; want timeout", err)
}
if perr := parseWriteError(err); perr != nil {
t.Error(perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Errorf("got %v; want timeout", err)
}
})
package net
import (
+ "errors"
"fmt"
- "internal/poll"
"internal/testenv"
"io"
"io/ioutil"
"net/internal/socktest"
+ "os"
"runtime"
"sync"
"testing"
}{
// Tests that accept deadlines in the past work, even if
// there's incoming connections available.
- {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+ {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
- {50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+ {50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
}
func TestAcceptTimeout(t *testing.T) {
if perr := parseAcceptError(err); perr != nil {
t.Errorf("#%d/%d: %v", i, j, perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatalf("#%d/%d: %v", i, j, err)
}
}
if perr := parseAcceptError(err); perr != nil {
t.Error(perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatal(err)
}
}
}{
// Tests that read deadlines work, even if there's data ready
// to be read.
- {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+ {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
- {50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+ {50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
}
func TestReadTimeout(t *testing.T) {
if perr := parseReadError(err); perr != nil {
t.Errorf("#%d/%d: %v", i, j, perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatalf("#%d/%d: %v", i, j, err)
}
}
}{
// Tests that read deadlines work, even if there's data ready
// to be read.
- {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+ {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
- {50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+ {50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
}
func TestReadFromTimeout(t *testing.T) {
if perr := parseReadError(err); perr != nil {
t.Errorf("#%d/%d: %v", i, j, perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatalf("#%d/%d: %v", i, j, err)
}
}
}{
// Tests that write deadlines work, even if there's buffer
// space available to write.
- {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+ {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
- {10 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+ {10 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
}
func TestWriteTimeout(t *testing.T) {
if perr := parseWriteError(err); perr != nil {
t.Errorf("#%d/%d: %v", i, j, perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatalf("#%d/%d: %v", i, j, err)
}
}
}{
// Tests that write deadlines work, even if there's buffer
// space available to write.
- {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+ {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
- {10 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+ {10 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
}
func TestWriteToTimeout(t *testing.T) {
if perr := parseWriteError(err); perr != nil {
t.Errorf("#%d/%d: %v", i, j, perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatalf("#%d/%d: %v", i, j, err)
}
}
if perr := parseReadError(err); perr != nil {
t.Error(perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatal(err)
}
}
if perr := parseReadError(err); perr != nil {
t.Error(perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatal(err)
}
}
if perr := parseWriteError(err); perr != nil {
t.Error(perr)
}
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatal(err)
}
}
}
wg.Wait()
}
+
+// isDeadlineExceeded reports whether err is or wraps os.ErrDeadlineExceeded.
+// We also check that the error implements net.Error, and that the
+// Timeout method returns true.
+func isDeadlineExceeded(err error) bool {
+ nerr, ok := err.(Error)
+ if !ok {
+ return false
+ }
+ if !nerr.Timeout() {
+ return false
+ }
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ return false
+ }
+ return true
+}
t.Fatalf("unexpected peer address: %v", peer)
}
default: // Read may timeout, it depends on the platform
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatal(err)
}
}
t.Fatalf("unexpected peer address: %v", peer)
}
default: // Read may timeout, it depends on the platform
- if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
+ if !isDeadlineExceeded(err) {
t.Fatal(err)
}
}
// Methods on File will return this error when the receiver is nil.
ErrInvalid = errInvalid() // "invalid argument"
- ErrPermission = errPermission() // "permission denied"
- ErrExist = errExist() // "file already exists"
- ErrNotExist = errNotExist() // "file does not exist"
- ErrClosed = errClosed() // "file already closed"
- ErrNoDeadline = errNoDeadline() // "file type does not support deadline"
+ ErrPermission = errPermission() // "permission denied"
+ ErrExist = errExist() // "file already exists"
+ ErrNotExist = errNotExist() // "file does not exist"
+ ErrClosed = errClosed() // "file already closed"
+ ErrNoDeadline = errNoDeadline() // "file type does not support deadline"
+ ErrDeadlineExceeded = errDeadlineExceeded() // "i/o timeout"
)
func errInvalid() error { return oserror.ErrInvalid }
func errClosed() error { return oserror.ErrClosed }
func errNoDeadline() error { return poll.ErrNoDeadline }
+// errDeadlineExceeded returns the value for os.ErrDeadlineExceeded.
+// This error comes from the internal/poll package, which is also
+// used by package net. Doing this this way ensures that the net
+// package will return os.ErrDeadlineExceeded for an exceeded deadline,
+// as documented by net.Conn.SetDeadline, without requiring any extra
+// work in the net package and without requiring the internal/poll
+// package to import os (which it can't, because that would be circular).
+func errDeadlineExceeded() error { return poll.ErrDeadlineExceeded }
+
type timeout interface {
Timeout() bool
}
// After a deadline has been exceeded, the connection can be refreshed
// by setting a deadline in the future.
//
-// An error returned after a timeout fails will implement the
-// Timeout method, and calling the Timeout method will return true.
-// The PathError and SyscallError types implement the Timeout method.
-// In general, call IsTimeout to test whether an error indicates a timeout.
+// If the deadline is exceeded a call to Read or Write or to other I/O
+// methods will return an error that wraps ErrDeadlineExceeded.
+// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
+// That error implements the Timeout method, and calling the Timeout
+// method will return true, but there are other possible errors for which
+// the Timeout will return true even if the deadline has not been exceeded.
//
// An idle timeout can be implemented by repeatedly extending
// the deadline after successful Read or Write calls.
t.Fatalf("first names: %v, second names: %v", names1, names2)
}
}
+
+// isDeadlineExceeded reports whether err is or wraps os.ErrDeadlineExceeded.
+// We also check that the error has a Timeout method that returns true.
+func isDeadlineExceeded(err error) bool {
+ if !IsTimeout(err) {
+ return false
+ }
+ if !errors.Is(err, ErrDeadlineExceeded) {
+ return false
+ }
+ return true
+}
_, err := file.Read(b)
if !blocking {
// We want it to fail with a timeout.
- if !IsTimeout(err) {
+ if !isDeadlineExceeded(err) {
t.Fatalf("No timeout reading from file: %v", err)
}
} else {
import (
"fmt"
- "internal/poll"
"io"
"io/ioutil"
"math/rand"
}{
// Tests that read deadlines work, even if there's data ready
// to be read.
- {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+ {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
- {50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+ {50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
}
func TestReadTimeout(t *testing.T) {
for {
n, err := r.Read(b[:])
if xerr != nil {
- if !os.IsTimeout(err) {
+ if !isDeadlineExceeded(err) {
t.Fatalf("#%d/%d: %v", i, j, err)
}
}
}{
// Tests that write deadlines work, even if there's buffer
// space available to write.
- {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}},
+ {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
- {10 * time.Millisecond, [2]error{nil, poll.ErrTimeout}},
+ {10 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
}
func TestWriteTimeout(t *testing.T) {
for {
n, err := w.Write([]byte("WRITE TIMEOUT TEST"))
if xerr != nil {
- if !os.IsTimeout(err) {
+ if !isDeadlineExceeded(err) {
t.Fatalf("%d: %v", j, err)
}
}
var n int
n, err = r.Read(b)
t1 := time.Now()
- if n != 0 || err == nil || !os.IsTimeout(err) {
+ if n != 0 || err == nil || !isDeadlineExceeded(err) {
err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err)
return
}
case <-max.C:
t.Fatal("Read took over 1s; expected 0.1s")
case err := <-ch:
- if !os.IsTimeout(err) {
+ if !isDeadlineExceeded(err) {
t.Fatal(err)
}
}
}
}
t1 := time.Now()
- if err == nil || !os.IsTimeout(err) {
+ if err == nil || !isDeadlineExceeded(err) {
err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err)
return
}
case <-max.C:
t.Fatalf("Write took over %v; expected 0.1s", d)
case err := <-ch:
- if !os.IsTimeout(err) {
+ if !isDeadlineExceeded(err) {
t.Fatal(err)
}
}
select {
case res := <-actvch:
- if os.IsTimeout(res.err) {
+ if !isDeadlineExceeded(err) {
t.Logf("good client timeout after %v, reading %d bytes", res.d, res.n)
} else {
t.Fatalf("client Copy = %d, %v; want timeout", res.n, res.err)
var b [1]byte
for i := 0; i < N; i++ {
_, err := r.Read(b[:])
- if err != nil && !os.IsTimeout(err) {
+ if err != nil && !isDeadlineExceeded(err) {
t.Error("Read returned non-timeout error", err)
}
}
var b [1]byte
for i := 0; i < N; i++ {
_, err := w.Write(b[:])
- if err != nil && !os.IsTimeout(err) {
+ if err != nil && !isDeadlineExceeded(err) {
t.Error("Write returned non-timeout error", err)
}
}
_, err := r.Read(b1)
copy(b1, b2) // Mutate b1 to trigger potential race
if err != nil {
- if !os.IsTimeout(err) {
+ if !isDeadlineExceeded(err) {
t.Error(err)
}
r.SetReadDeadline(time.Now().Add(time.Millisecond))
_, err := w.Write(b1)
copy(b1, b2) // Mutate b1 to trigger potential race
if err != nil {
- if !os.IsTimeout(err) {
+ if !isDeadlineExceeded(err) {
t.Error(err)
}
w.SetWriteDeadline(time.Now().Add(time.Millisecond))