1
0
mirror of https://github.com/golang/go synced 2024-11-25 08:07:57 -07:00

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
This commit is contained in:
Dmitriy Vyukov 2013-08-13 19:11:42 +04:00
parent d1cefd6b6d
commit aaab946943
2 changed files with 35 additions and 13 deletions

View File

@ -351,20 +351,29 @@ func (pd *pollDesc) Init(fd *netFD) error {
return nil
}
// TODO(dfc) these unused error returns could be removed
func (fd *netFD) setDeadline(t time.Time) error {
fd.setReadDeadline(t)
fd.setWriteDeadline(t)
return nil
return setDeadlineImpl(fd, t, true, true)
}
func (fd *netFD) setReadDeadline(t time.Time) error {
fd.pd.rdeadline.setTime(t)
return nil
return setDeadlineImpl(fd, t, true, false)
}
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
}

View File

@ -134,9 +134,13 @@ func runtime_pollWaitCanceled(pd *PollDesc, mode int) {
}
func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
G *rg, *wg;
runtime·lock(pd);
if(pd->closing)
goto ret;
if(pd->closing) {
runtime·unlock(pd);
return;
}
pd->seq++; // invalidate current timers
// Reset current timers.
if(pd->rt.fv) {
@ -148,9 +152,8 @@ func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
pd->wt.fv = nil;
}
// Setup new timers.
if(d != 0 && d <= runtime·nanotime()) {
if(d != 0 && d <= runtime·nanotime())
d = -1;
}
if(mode == 'r' || mode == 'r'+'w')
pd->rd = d;
if(mode == 'w' || mode == 'r'+'w')
@ -180,8 +183,18 @@ func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
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);
if(rg)
runtime·ready(rg);
if(wg)
runtime·ready(wg);
}
func runtime_pollUnblock(pd *PollDesc) {