1
0
mirror of https://github.com/golang/go synced 2024-11-22 00:54:43 -07:00

net: let OS-specific AddFD routine wake up polling thread.

With gccgo some operating systems require using select rather
than epoll or kevent.  Using select means that we have to wake
up the polling thread each time we add a new file descriptor.
This implements that in the generic code rather than adding
another wakeup channel, even though nothing in the current net
package uses the capability.

R=rsc, iant2
CC=golang-dev
https://golang.org/cl/4284069
This commit is contained in:
Ian Lance Taylor 2011-03-28 12:39:09 -07:00
parent 5be77a204b
commit 0caa0c0923
5 changed files with 19 additions and 15 deletions

View File

@ -122,9 +122,13 @@ func (s *pollServer) AddFD(fd *netFD, mode int) {
doWakeup = true
}
if err := s.poll.AddFD(intfd, mode, false); err != nil {
wake, err := s.poll.AddFD(intfd, mode, false)
if err != nil {
panic("pollServer AddFD " + err.String())
}
if wake {
doWakeup = true
}
s.Unlock()

View File

@ -31,7 +31,7 @@ func newpollster() (p *pollster, err os.Error) {
return p, nil
}
func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
// pollServer is locked.
var kmode int
@ -53,15 +53,15 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
n, e := syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil)
if e != 0 {
return os.NewSyscallError("kevent", e)
return false, os.NewSyscallError("kevent", e)
}
if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
return os.ErrorString("kqueue phase error")
return false, os.ErrorString("kqueue phase error")
}
if ev.Data != 0 {
return os.Errno(int(ev.Data))
return false, os.Errno(int(ev.Data))
}
return nil
return false, nil
}
func (p *pollster) DelFD(fd int, mode int) {

View File

@ -31,7 +31,7 @@ func newpollster() (p *pollster, err os.Error) {
return p, nil
}
func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
// pollServer is locked.
var kmode int
@ -51,15 +51,15 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
n, e := syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
if e != 0 {
return os.NewSyscallError("kevent", e)
return false, os.NewSyscallError("kevent", e)
}
if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
return os.NewSyscallError("kqueue phase error", e)
return false, os.NewSyscallError("kqueue phase error", e)
}
if ev.Data != 0 {
return os.Errno(int(ev.Data))
return false, os.Errno(int(ev.Data))
}
return nil
return false, nil
}
func (p *pollster) DelFD(fd int, mode int) {

View File

@ -47,7 +47,7 @@ func newpollster() (p *pollster, err os.Error) {
return p, nil
}
func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
// pollServer is locked.
var already bool
@ -69,10 +69,10 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
op = syscall.EPOLL_CTL_ADD
}
if e := syscall.EpollCtl(p.epfd, op, fd, &p.ctlEvent); e != 0 {
return os.NewSyscallError("epoll_ctl", e)
return false, os.NewSyscallError("epoll_ctl", e)
}
p.events[fd] = p.ctlEvent.Events
return nil
return false, nil
}
func (p *pollster) StopWaiting(fd int, bits uint) {

View File

@ -31,7 +31,7 @@ func newPollServer() (s *pollServer, err os.Error) {
if s.poll, err = newpollster(); err != nil {
goto Error
}
if err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil {
if _, err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil {
s.poll.Close()
goto Error
}