diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2016-10-15 16:56:51 +0100 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2016-10-17 05:53:00 +0000 |
| commit | 7a7ea01c65e8366af277b956dc8ccf0601727172 (patch) | |
| tree | c91c8a1c4043b4eadb53f161c6453d853076901b /src/syscall | |
| parent | cd2c9df7612795cad5b56cabe5ec29c7771db5fe (diff) | |
| download | go-7a7ea01c65e8366af277b956dc8ccf0601727172.tar.xz | |
syscall, net: make deadline changes affect blocked read/write calls on nacl
Flesh out nacl's fake network system to match how all the other
platforms work: all other systems' SetReadDeadline and
SetWriteDeadline affect currently-blocked read & write calls.
This was documented in golang.org/cl/30164 because it was the status
quo and existing packages relied on it. (notably the net/http package)
And add a test.
Change-Id: I074a1054dcabcedc97b173dad5e827f8babf7cfc
Reviewed-on: https://go-review.googlesource.com/31178
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/syscall')
| -rw-r--r-- | src/syscall/net_nacl.go | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/src/syscall/net_nacl.go b/src/syscall/net_nacl.go index 1a0122c4b6..9dc5d0ca0b 100644 --- a/src/syscall/net_nacl.go +++ b/src/syscall/net_nacl.go @@ -6,6 +6,8 @@ // The simulation is not particularly tied to NaCl, // but other systems have real networks. +// All int64 times are UnixNanos. + package syscall import ( @@ -50,6 +52,22 @@ func (t *timer) stop() { stopTimer(&t.r) } +func (t *timer) reset(q *queue, deadline int64) { + if t.r.f != nil { + t.stop() + } + if deadline == 0 { + return + } + if t.r.f == nil { + t.q = q + t.r.f = timerExpired + t.r.arg = t + } + t.r.when = deadline + startTimer(&t.r) +} + func timerExpired(i interface{}, seq uintptr) { t := i.(*timer) go func() { @@ -233,9 +251,11 @@ type queue struct { sync.Mutex canRead sync.Cond canWrite sync.Cond - r int // total read index - w int // total write index - m int // index mask + rtimer *timer // non-nil if in read + wtimer *timer // non-nil if in write + r int // total read index + w int // total write index + m int // index mask closed bool } @@ -259,9 +279,11 @@ func (q *queue) waitRead(n int, deadline int64) (int, error) { } var t timer t.start(q, deadline) + q.rtimer = &t for q.w-q.r == 0 && !q.closed && !t.expired { q.canRead.Wait() } + q.rtimer = nil t.stop() m := q.w - q.r if m == 0 && t.expired { @@ -281,9 +303,11 @@ func (q *queue) waitWrite(n int, deadline int64) (int, error) { } var t timer t.start(q, deadline) + q.wtimer = &t for q.w-q.r > q.m && !q.closed && !t.expired { q.canWrite.Wait() } + q.wtimer = nil t.stop() m := q.m + 1 - (q.w - q.r) if m == 0 && t.expired { @@ -871,6 +895,13 @@ func SetReadDeadline(fd int, t int64) error { return err } atomic.StoreInt64(&f.rddeadline, t) + if bq := f.rd; bq != nil { + bq.Lock() + if timer := bq.rtimer; timer != nil { + timer.reset(&bq.queue, t) + } + bq.Unlock() + } return nil } @@ -884,6 +915,13 @@ func SetWriteDeadline(fd int, t int64) error { return err } atomic.StoreInt64(&f.wrdeadline, t) + if bq := f.wr; bq != nil { + bq.Lock() + if timer := bq.wtimer; timer != nil { + timer.reset(&bq.queue, t) + } + bq.Unlock() + } return nil } |
