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
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) {
// pollServer is locked.
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.
var kmode int
// EV_DELETE - delete event from kqueue list
syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE)
syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
+ return false
}
func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
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) {
// pollServer is locked.
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.
var kmode int
// rather than waiting for real event
syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE|syscall.EV_RECEIPT)
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) {
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) {
// pollServer is locked.
}
}
-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.
if mode == 'r' {
i++
}
}
+ return false
}
func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
// Evict evicts fd from the pending list, unblocking
// any I/O running on fd. The caller must have locked
// 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 {
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)
}
if s.pending[fd.sysfd<<1|1] == fd {
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)
}
+ return doWakeup
}
var wakeupbuf [1]byte
// the final decref will close fd.sysfd. This should happen
// fairly quickly, since all the I/O is non-blocking, and any
// attempts to block in the pollserver will return errClosing.
- fd.pollServer.Evict(fd)
+ doWakeup := fd.pollServer.Evict(fd)
fd.pollServer.Unlock()
fd.decref()
+ if doWakeup {
+ fd.pollServer.Wakeup()
+ }
return nil
}