aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-10-15 16:56:51 +0100
committerBrad Fitzpatrick <bradfitz@golang.org>2016-10-17 05:53:00 +0000
commit7a7ea01c65e8366af277b956dc8ccf0601727172 (patch)
treec91c8a1c4043b4eadb53f161c6453d853076901b /src/syscall
parentcd2c9df7612795cad5b56cabe5ec29c7771db5fe (diff)
downloadgo-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.go44
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
}