summaryrefslogtreecommitdiff
path: root/src/pkg/net/fd_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/net/fd_linux.go')
-rw-r--r--src/pkg/net/fd_linux.go51
1 files changed, 28 insertions, 23 deletions
diff --git a/src/pkg/net/fd_linux.go b/src/pkg/net/fd_linux.go
index 70fc344b2..085e42307 100644
--- a/src/pkg/net/fd_linux.go
+++ b/src/pkg/net/fd_linux.go
@@ -33,21 +33,25 @@ type pollster struct {
ctlEvent syscall.EpollEvent
}
-func newpollster() (p *pollster, err os.Error) {
+func newpollster() (p *pollster, err error) {
p = new(pollster)
- var e int
-
- // The arg to epoll_create is a hint to the kernel
- // about the number of FDs we will care about.
- // We don't know, and since 2.6.8 the kernel ignores it anyhow.
- if p.epfd, e = syscall.EpollCreate(16); e != 0 {
- return nil, os.NewSyscallError("epoll_create", e)
+ if p.epfd, err = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC); err != nil {
+ if err != syscall.ENOSYS {
+ return nil, os.NewSyscallError("epoll_create1", err)
+ }
+ // The arg to epoll_create is a hint to the kernel
+ // about the number of FDs we will care about.
+ // We don't know, and since 2.6.8 the kernel ignores it anyhow.
+ if p.epfd, err = syscall.EpollCreate(16); err != nil {
+ return nil, os.NewSyscallError("epoll_create", err)
+ }
+ syscall.CloseOnExec(p.epfd)
}
p.events = make(map[int]uint32)
return p, nil
}
-func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
+func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
// pollServer is locked.
var already bool
@@ -68,8 +72,8 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
} else {
op = syscall.EPOLL_CTL_ADD
}
- if e := syscall.EpollCtl(p.epfd, op, fd, &p.ctlEvent); e != 0 {
- return false, os.NewSyscallError("epoll_ctl", e)
+ if err := syscall.EpollCtl(p.epfd, op, fd, &p.ctlEvent); err != nil {
+ return false, os.NewSyscallError("epoll_ctl", err)
}
p.events[fd] = p.ctlEvent.Events
return false, nil
@@ -80,7 +84,8 @@ func (p *pollster) StopWaiting(fd int, bits uint) {
events, already := p.events[fd]
if !already {
- print("Epoll unexpected fd=", fd, "\n")
+ // The fd returned by the kernel may have been
+ // cancelled already; return silently.
return
}
@@ -97,15 +102,15 @@ func (p *pollster) StopWaiting(fd int, bits uint) {
if int32(events)&^syscall.EPOLLONESHOT != 0 {
p.ctlEvent.Fd = int32(fd)
p.ctlEvent.Events = events
- if e := syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_MOD, fd, &p.ctlEvent); e != 0 {
- print("Epoll modify fd=", fd, ": ", os.Errno(e).String(), "\n")
+ if err := syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_MOD, fd, &p.ctlEvent); err != nil {
+ print("Epoll modify fd=", fd, ": ", err.Error(), "\n")
}
p.events[fd] = events
} else {
- if e := syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_DEL, fd, nil); e != 0 {
- print("Epoll delete fd=", fd, ": ", os.Errno(e).String(), "\n")
+ if err := syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_DEL, fd, nil); err != nil {
+ print("Epoll delete fd=", fd, ": ", err.Error(), "\n")
}
- p.events[fd] = 0, false
+ delete(p.events, fd)
}
}
@@ -130,7 +135,7 @@ func (p *pollster) DelFD(fd int, mode int) {
}
}
-func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.Error) {
+func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
for len(p.waitEvents) == 0 {
var msec int = -1
if nsec > 0 {
@@ -138,14 +143,14 @@ func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.E
}
s.Unlock()
- n, e := syscall.EpollWait(p.epfd, p.waitEventBuf[0:], msec)
+ n, err := syscall.EpollWait(p.epfd, p.waitEventBuf[0:], msec)
s.Lock()
- if e != 0 {
- if e == syscall.EAGAIN || e == syscall.EINTR {
+ if err != nil {
+ if err == syscall.EAGAIN || err == syscall.EINTR {
continue
}
- return -1, 0, os.NewSyscallError("epoll_wait", e)
+ return -1, 0, os.NewSyscallError("epoll_wait", err)
}
if n == 0 {
return -1, 0, nil
@@ -177,6 +182,6 @@ func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.E
return fd, 'r', nil
}
-func (p *pollster) Close() os.Error {
+func (p *pollster) Close() error {
return os.NewSyscallError("close", syscall.Close(p.epfd))
}