diff --git a/internal/nbconn/nbconn_real_non_block_windows.go b/internal/nbconn/nbconn_real_non_block_windows.go index b4c11555..945ec01d 100644 --- a/internal/nbconn/nbconn_real_non_block_windows.go +++ b/internal/nbconn/nbconn_real_non_block_windows.go @@ -8,6 +8,7 @@ import ( "golang.org/x/sys/windows" "io" "syscall" + "time" "unsafe" ) @@ -40,6 +41,10 @@ func setSockMode(fd uintptr, mode sockMode) error { return nil } +func (c *NetConn) isDeadlineSet(dl time.Time) bool { + return !dl.IsZero() && dl != NonBlockingDeadline && dl != disableSetDeadlineDeadline +} + // realNonblockingWrite does a non-blocking write. readFlushLock must already be held. func (c *NetConn) realNonblockingWrite(b []byte) (n int, err error) { if c.nonblockWriteFunc == nil { @@ -58,6 +63,12 @@ func (c *NetConn) realNonblockingWrite(b []byte) (n int, err error) { c.nonblockWriteN = 0 c.nonblockWriteErr = nil + if c.isDeadlineSet(c.writeDeadline) && time.Now().After(c.writeDeadline) { + c.nonblockWriteErr = errors.New("i/o timeout") + + return 0, c.nonblockWriteErr + } + err = c.rawConn.Write(c.nonblockWriteFunc) n = c.nonblockWriteN c.nonblockWriteBuf = nil // ensure that no reference to b is kept. @@ -98,6 +109,12 @@ func (c *NetConn) realNonblockingRead(b []byte) (n int, err error) { c.nonblockReadN = 0 c.nonblockReadErr = nil + if c.isDeadlineSet(c.readDeadline) && time.Now().After(c.readDeadline) { + c.nonblockReadErr = errors.New("i/o timeout") + + return 0, c.nonblockReadErr + } + err = c.rawConn.Read(c.nonblockReadFunc) n = c.nonblockReadN c.nonblockReadBuf = nil // ensure that no reference to b is kept.