pd.wd = d
}
combo := pd.rd > 0 && pd.rd == pd.wd
- // Reset current timers if necessary.
- if pd.rt.f != nil && (pd.rd != rd0 || combo != combo0) {
- pd.rseq++ // invalidate current timers
- deltimer(&pd.rt)
- pd.rt.f = nil
- }
- if pd.wt.f != nil && (pd.wd != wd0 || combo != combo0) {
- pd.wseq++ // invalidate current timers
- deltimer(&pd.wt)
- pd.wt.f = nil
- }
- // Setup new timers.
+ rtf := netpollReadDeadline
if combo {
- if pd.rt.f == nil {
- pd.rt.f = netpollDeadline
+ rtf = netpollDeadline
+ }
+ if pd.rt.f == nil {
+ if pd.rd > 0 {
+ pd.rt.f = rtf
pd.rt.when = pd.rd
// Copy current seq into the timer arg.
// Timer func will check the seq against current descriptor seq,
pd.rt.seq = pd.rseq
addtimer(&pd.rt)
}
- } else {
- if pd.rd > 0 && pd.rt.f == nil {
- pd.rt.f = netpollReadDeadline
- pd.rt.when = pd.rd
- pd.rt.arg = pd
- pd.rt.seq = pd.rseq
- addtimer(&pd.rt)
+ } else if pd.rd != rd0 || combo != combo0 {
+ pd.rseq++ // invalidate current timers
+ if pd.rd > 0 {
+ modtimer(&pd.rt, pd.rd, 0, rtf, pd, pd.rseq)
+ } else {
+ deltimer(&pd.rt)
+ pd.rt.f = nil
}
- if pd.wd > 0 && pd.wt.f == nil {
+ }
+ if pd.wt.f == nil {
+ if pd.wd > 0 && !combo {
pd.wt.f = netpollWriteDeadline
pd.wt.when = pd.wd
pd.wt.arg = pd
pd.wt.seq = pd.wseq
addtimer(&pd.wt)
}
+ } else if pd.wd != wd0 || combo != combo0 {
+ pd.wseq++ // invalidate current timers
+ if pd.wd > 0 && !combo {
+ modtimer(&pd.wt, pd.wd, 0, netpollWriteDeadline, pd, pd.wseq)
+ } else {
+ deltimer(&pd.wt)
+ pd.wt.f = nil
+ }
}
// If we set the new deadline in the past, unblock currently pending IO if any.
var rg, wg *g
tb := t.tb
lock(&tb.lock)
+ removed, ok := tb.deltimerLocked(t)
+ unlock(&tb.lock)
+ if !ok {
+ badTimer()
+ }
+ return removed
+}
+
+func (tb *timersBucket) deltimerLocked(t *timer) (removed, ok bool) {
// t may not be registered anymore and may have
// a bogus i (typically 0, if generated by Go).
// Verify it before proceeding.
i := t.i
last := len(tb.t) - 1
if i < 0 || i > last || tb.t[i] != t {
- unlock(&tb.lock)
- return false
+ return false, true
}
if i != last {
tb.t[i] = tb.t[last]
}
tb.t[last] = nil
tb.t = tb.t[:last]
- ok := true
+ ok = true
if i != last {
if !siftupTimer(tb.t, i) {
ok = false
ok = false
}
}
+ return true, ok
+}
+
+func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) {
+ tb := t.tb
+
+ lock(&tb.lock)
+ _, ok := tb.deltimerLocked(t)
+ if ok {
+ t.when = when
+ t.period = period
+ t.f = f
+ t.arg = arg
+ t.seq = seq
+ ok = tb.addtimerLocked(t)
+ }
unlock(&tb.lock)
if !ok {
badTimer()
}
- return true
}
// Timerproc runs the time-driven events.