1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Waiting for FDs via select(2).
15 type pollster
struct {
16 readFds
, writeFds
, repeatFds
*syscall
.FdSet
18 readyReadFds
, readyWriteFds
*syscall
.FdSet
24 func newpollster() (p
*pollster
, err error
) {
26 p
.readFds
= new(syscall
.FdSet
)
27 p
.writeFds
= new(syscall
.FdSet
)
28 p
.repeatFds
= new(syscall
.FdSet
)
29 p
.readyReadFds
= new(syscall
.FdSet
)
30 p
.readyWriteFds
= new(syscall
.FdSet
)
37 func (p
*pollster
) AddFD(fd
int, mode
int, repeat
bool) (bool, error
) {
38 // pollServer is locked.
41 return false, errors
.New("pollster closed")
45 syscall
.FDSet(fd
, p
.readFds
)
47 syscall
.FDSet(fd
, p
.writeFds
)
51 syscall
.FDSet(fd
, p
.repeatFds
)
61 func (p
*pollster
) DelFD(fd
int, mode
int) bool {
62 // pollServer is locked.
69 if !syscall
.FDIsSet(fd
, p
.readFds
) {
70 print("Select unexpected fd=", fd
, " for read\n")
73 syscall
.FDClr(fd
, p
.readFds
)
75 if !syscall
.FDIsSet(fd
, p
.writeFds
) {
76 print("Select unexpected fd=", fd
, " for write\n")
79 syscall
.FDClr(fd
, p
.writeFds
)
82 // Doesn't matter if not already present.
83 syscall
.FDClr(fd
, p
.repeatFds
)
85 // We don't worry about maxFd here.
90 func (p
*pollster
) WaitFD(s
*pollServer
, nsec
int64) (fd
int, mode
int, err error
) {
92 var timeout
*syscall
.Timeval
93 var tv syscall
.Timeval
96 tv
= syscall
.NsecToTimeval(nsec
)
102 var tmpReadFds
, tmpWriteFds syscall
.FdSet
105 return -1, 0, errors
.New("pollster closed")
108 // Temporary syscall.FdSet's into which the values are copied
109 // because select mutates the values.
110 tmpReadFds
= *p
.readFds
111 tmpWriteFds
= *p
.writeFds
114 n
, e
= syscall
.Select(p
.maxFd
+1, &tmpReadFds
, &tmpWriteFds
, nil, timeout
)
117 if e
!= syscall
.EINTR
{
121 if e
== syscall
.EBADF
{
122 // Some file descriptor has been closed.
123 tmpReadFds
= syscall
.FdSet
{}
124 tmpWriteFds
= syscall
.FdSet
{}
126 for i
:= 0; i
< p
.maxFd
+1; i
++ {
127 if syscall
.FDIsSet(i
, p
.readFds
) {
129 if syscall
.Fstat(i
, &s
) == syscall
.EBADF
{
130 syscall
.FDSet(i
, &tmpReadFds
)
133 } else if syscall
.FDIsSet(i
, p
.writeFds
) {
135 if syscall
.Fstat(i
, &s
) == syscall
.EBADF
{
136 syscall
.FDSet(i
, &tmpWriteFds
)
142 return -1, 0, os
.NewSyscallError("select", e
)
149 *p
.readyReadFds
= tmpReadFds
150 *p
.readyWriteFds
= tmpWriteFds
155 for i
:= p
.lastFd
; i
< p
.maxFd
+1; i
++ {
156 if syscall
.FDIsSet(i
, p
.readyReadFds
) {
159 syscall
.FDClr(i
, p
.readyReadFds
)
160 } else if syscall
.FDIsSet(i
, p
.readyWriteFds
) {
163 syscall
.FDClr(i
, p
.readyWriteFds
)
166 if !syscall
.FDIsSet(i
, p
.repeatFds
) {
175 // Will not reach here. Just to shut up the compiler.
179 func (p
*pollster
) Close() error
{