Commit aaab9469 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: fix handling of network deadlines

Ensure that deadlines affect already issued IO.

R=golang-dev, mikioh.mikioh, bradfitz
CC=golang-dev
https://golang.org/cl/12847043
parent d1cefd6b
...@@ -351,20 +351,29 @@ func (pd *pollDesc) Init(fd *netFD) error { ...@@ -351,20 +351,29 @@ func (pd *pollDesc) Init(fd *netFD) error {
return nil return nil
} }
// TODO(dfc) these unused error returns could be removed
func (fd *netFD) setDeadline(t time.Time) error { func (fd *netFD) setDeadline(t time.Time) error {
fd.setReadDeadline(t) return setDeadlineImpl(fd, t, true, true)
fd.setWriteDeadline(t)
return nil
} }
func (fd *netFD) setReadDeadline(t time.Time) error { func (fd *netFD) setReadDeadline(t time.Time) error {
fd.pd.rdeadline.setTime(t) return setDeadlineImpl(fd, t, true, false)
return nil
} }
func (fd *netFD) setWriteDeadline(t time.Time) error { func (fd *netFD) setWriteDeadline(t time.Time) error {
fd.pd.wdeadline.setTime(t) return setDeadlineImpl(fd, t, false, true)
}
func setDeadlineImpl(fd *netFD, t time.Time, read, write bool) error {
if err := fd.incref(); err != nil {
return err
}
defer fd.decref()
if read {
fd.pd.rdeadline.setTime(t)
}
if write {
fd.pd.wdeadline.setTime(t)
}
fd.pd.Wakeup()
return nil return nil
} }
...@@ -134,9 +134,13 @@ func runtime_pollWaitCanceled(pd *PollDesc, mode int) { ...@@ -134,9 +134,13 @@ func runtime_pollWaitCanceled(pd *PollDesc, mode int) {
} }
func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) { func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
G *rg, *wg;
runtime·lock(pd); runtime·lock(pd);
if(pd->closing) if(pd->closing) {
goto ret; runtime·unlock(pd);
return;
}
pd->seq++; // invalidate current timers pd->seq++; // invalidate current timers
// Reset current timers. // Reset current timers.
if(pd->rt.fv) { if(pd->rt.fv) {
...@@ -148,9 +152,8 @@ func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) { ...@@ -148,9 +152,8 @@ func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
pd->wt.fv = nil; pd->wt.fv = nil;
} }
// Setup new timers. // Setup new timers.
if(d != 0 && d <= runtime·nanotime()) { if(d != 0 && d <= runtime·nanotime())
d = -1; d = -1;
}
if(mode == 'r' || mode == 'r'+'w') if(mode == 'r' || mode == 'r'+'w')
pd->rd = d; pd->rd = d;
if(mode == 'w' || mode == 'r'+'w') if(mode == 'w' || mode == 'r'+'w')
...@@ -180,8 +183,18 @@ func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) { ...@@ -180,8 +183,18 @@ func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
runtime·addtimer(&pd->wt); runtime·addtimer(&pd->wt);
} }
} }
ret: // If we set the new deadline in the past, unblock currently pending IO if any.
rg = nil;
wg = nil;
if(pd->rd < 0)
rg = netpollunblock(pd, 'r', false);
if(pd->wd < 0)
wg = netpollunblock(pd, 'w', false);
runtime·unlock(pd); runtime·unlock(pd);
if(rg)
runtime·ready(rg);
if(wg)
runtime·ready(wg);
} }
func runtime_pollUnblock(pd *PollDesc) { func runtime_pollUnblock(pd *PollDesc) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment