mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Handle zero time correctly in gonet.deadlineTimer.
After setDeadline(ch, timer, time.Time{}), the timer pointer is not reset and
may point to an already expired timer. So the next call to setDeadline() will
close the cancel channel, even though the timer did not expire. This was fixed
by setting timer to nil if time.Time.IsZero().
Fixes #9885
Co-authored-by: snyh <snyh@snyh.org>
PiperOrigin-RevId: 598940274
This commit is contained in:
committed by
gVisor bot
co-authored by
snyh
parent
be48200c0e
commit
f1f3dbd6c2
@@ -25,6 +25,7 @@ go_test(
|
||||
srcs = ["gonet_test.go"],
|
||||
library = ":gonet",
|
||||
deps = [
|
||||
"//pkg/sync",
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/header",
|
||||
"//pkg/tcpip/link/loopback",
|
||||
|
||||
@@ -179,6 +179,7 @@ func (d *deadlineTimer) setDeadline(cancelCh *chan struct{}, timer **time.Timer,
|
||||
// "A zero value for t means I/O operations will not time out."
|
||||
// - net.Conn.SetDeadline
|
||||
if t.IsZero() {
|
||||
*timer = nil
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/nettest"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
|
||||
@@ -1003,3 +1004,25 @@ func TestInterruptListender(t *testing.T) {
|
||||
func TestNetTest(t *testing.T) {
|
||||
nettest.TestConn(t, makePipe)
|
||||
}
|
||||
|
||||
// NOTE(gvisor.dev/issue/9885): Regression test.
|
||||
func TestDeadlineTimerAfterZeroValue(t *testing.T) {
|
||||
timer := &deadlineTimer{}
|
||||
timer.init()
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
ch := timer.readCancel()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
select {
|
||||
case <-ch:
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fail()
|
||||
}
|
||||
}()
|
||||
timer.SetReadDeadline(time.Now().Add(10 * time.Second))
|
||||
timer.SetReadDeadline(time.Time{})
|
||||
timer.SetReadDeadline(time.Unix(1, 0))
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user