Commit 0592c449 authored by Ian Lance Taylor's avatar Ian Lance Taylor

net: permit pollster DelFD to return whether to call Wakeup

This is necessary for systems that use select as the pollster,
such as Solaris (supported by gccgo).  It corresponds to the
bool returned by AddFD.  In general it's not clearly defined
what happens when a descriptor used in a select is closed, and
different systems behave differently.  Waking up the select
will cause the right thing to happen: the closed descriptor
will be dropped from the next iteration.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/7303056
parent c2fb6e2c
...@@ -33,6 +33,8 @@ func newpollster() (p *pollster, err error) { ...@@ -33,6 +33,8 @@ func newpollster() (p *pollster, err error) {
return p, nil return p, nil
} }
// First return value is whether the pollServer should be woken up.
// This version always returns false.
func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
// pollServer is locked. // pollServer is locked.
...@@ -64,7 +66,9 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { ...@@ -64,7 +66,9 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
return false, nil return false, nil
} }
func (p *pollster) DelFD(fd int, mode int) { // Return value is whether the pollServer should be woken up.
// This version always returns false.
func (p *pollster) DelFD(fd int, mode int) bool {
// pollServer is locked. // pollServer is locked.
var kmode int var kmode int
...@@ -77,6 +81,7 @@ func (p *pollster) DelFD(fd int, mode int) { ...@@ -77,6 +81,7 @@ func (p *pollster) DelFD(fd int, mode int) {
// EV_DELETE - delete event from kqueue list // EV_DELETE - delete event from kqueue list
syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE) syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE)
syscall.Kevent(p.kq, p.kbuf[:], nil, nil) syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
return false
} }
func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) { func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
......
...@@ -32,6 +32,8 @@ func newpollster() (p *pollster, err error) { ...@@ -32,6 +32,8 @@ func newpollster() (p *pollster, err error) {
return p, nil return p, nil
} }
// First return value is whether the pollServer should be woken up.
// This version always returns false.
func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
// pollServer is locked. // pollServer is locked.
...@@ -65,7 +67,9 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { ...@@ -65,7 +67,9 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
return false, nil return false, nil
} }
func (p *pollster) DelFD(fd int, mode int) { // Return value is whether the pollServer should be woken up.
// This version always returns false.
func (p *pollster) DelFD(fd int, mode int) bool {
// pollServer is locked. // pollServer is locked.
var kmode int var kmode int
...@@ -80,6 +84,7 @@ func (p *pollster) DelFD(fd int, mode int) { ...@@ -80,6 +84,7 @@ func (p *pollster) DelFD(fd int, mode int) {
// rather than waiting for real event // rather than waiting for real event
syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE|syscall.EV_RECEIPT) syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE|syscall.EV_RECEIPT)
syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil) syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil)
return false
} }
func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) { func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
......
...@@ -51,6 +51,8 @@ func newpollster() (p *pollster, err error) { ...@@ -51,6 +51,8 @@ func newpollster() (p *pollster, err error) {
return p, nil return p, nil
} }
// First return value is whether the pollServer should be woken up.
// This version always returns false.
func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
// pollServer is locked. // pollServer is locked.
...@@ -114,7 +116,9 @@ func (p *pollster) StopWaiting(fd int, bits uint) { ...@@ -114,7 +116,9 @@ func (p *pollster) StopWaiting(fd int, bits uint) {
} }
} }
func (p *pollster) DelFD(fd int, mode int) { // Return value is whether the pollServer should be woken up.
// This version always returns false.
func (p *pollster) DelFD(fd int, mode int) bool {
// pollServer is locked. // pollServer is locked.
if mode == 'r' { if mode == 'r' {
...@@ -133,6 +137,7 @@ func (p *pollster) DelFD(fd int, mode int) { ...@@ -133,6 +137,7 @@ func (p *pollster) DelFD(fd int, mode int) {
i++ i++
} }
} }
return false
} }
func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) { func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
......
...@@ -109,17 +109,24 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error { ...@@ -109,17 +109,24 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error {
// Evict evicts fd from the pending list, unblocking // Evict evicts fd from the pending list, unblocking
// any I/O running on fd. The caller must have locked // any I/O running on fd. The caller must have locked
// pollserver. // pollserver.
func (s *pollServer) Evict(fd *netFD) { // Return value is whether the pollServer should be woken up.
func (s *pollServer) Evict(fd *netFD) bool {
doWakeup := false
if s.pending[fd.sysfd<<1] == fd { if s.pending[fd.sysfd<<1] == fd {
s.WakeFD(fd, 'r', errClosing) s.WakeFD(fd, 'r', errClosing)
s.poll.DelFD(fd.sysfd, 'r') if s.poll.DelFD(fd.sysfd, 'r') {
doWakeup = true
}
delete(s.pending, fd.sysfd<<1) delete(s.pending, fd.sysfd<<1)
} }
if s.pending[fd.sysfd<<1|1] == fd { if s.pending[fd.sysfd<<1|1] == fd {
s.WakeFD(fd, 'w', errClosing) s.WakeFD(fd, 'w', errClosing)
s.poll.DelFD(fd.sysfd, 'w') if s.poll.DelFD(fd.sysfd, 'w') {
doWakeup = true
}
delete(s.pending, fd.sysfd<<1|1) delete(s.pending, fd.sysfd<<1|1)
} }
return doWakeup
} }
var wakeupbuf [1]byte var wakeupbuf [1]byte
...@@ -386,9 +393,12 @@ func (fd *netFD) Close() error { ...@@ -386,9 +393,12 @@ func (fd *netFD) Close() error {
// the final decref will close fd.sysfd. This should happen // the final decref will close fd.sysfd. This should happen
// fairly quickly, since all the I/O is non-blocking, and any // fairly quickly, since all the I/O is non-blocking, and any
// attempts to block in the pollserver will return errClosing. // attempts to block in the pollserver will return errClosing.
fd.pollServer.Evict(fd) doWakeup := fd.pollServer.Evict(fd)
fd.pollServer.Unlock() fd.pollServer.Unlock()
fd.decref() fd.decref()
if doWakeup {
fd.pollServer.Wakeup()
}
return nil return nil
} }
......
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