func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error { if mode == 'r' { syscall.FDSet(fd, p.readFds) } else { syscall.FDSet(fd, p.writeFds) } if repeat { syscall.FDSet(fd, p.repeatFds) } if fd > p.maxFd { p.maxFd = fd } return nil }
func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { // pollServer is locked. if mode == 'r' { syscall.FDSet(fd, p.readFds) } else { syscall.FDSet(fd, p.writeFds) } if repeat { syscall.FDSet(fd, p.repeatFds) } if fd > p.maxFd { p.maxFd = fd } return true, nil }
func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) { if p.nReady == 0 { var timeout *syscall.Timeval var tv syscall.Timeval timeout = nil if nsec > 0 { tv = syscall.NsecToTimeval(nsec) timeout = &tv } var n int var e error var tmpReadFds, tmpWriteFds syscall.FdSet for { if p.closed { return -1, 0, errors.New("pollster closed") } // Temporary syscall.FdSet's into which the values are copied // because select mutates the values. tmpReadFds = *p.readFds tmpWriteFds = *p.writeFds s.Unlock() n, e = syscall.Select(p.maxFd+1, &tmpReadFds, &tmpWriteFds, nil, timeout) s.Lock() if e != syscall.EINTR { break } } if e == syscall.EBADF { // Some file descriptor has been closed. tmpReadFds = syscall.FdSet{} tmpWriteFds = syscall.FdSet{} n = 0 for i := 0; i < p.maxFd+1; i++ { if syscall.FDIsSet(i, p.readFds) { var s syscall.Stat_t if syscall.Fstat(i, &s) == syscall.EBADF { syscall.FDSet(i, &tmpReadFds) n++ } } else if syscall.FDIsSet(i, p.writeFds) { var s syscall.Stat_t if syscall.Fstat(i, &s) == syscall.EBADF { syscall.FDSet(i, &tmpWriteFds) n++ } } } } else if e != nil { return -1, 0, os.NewSyscallError("select", e) } if n == 0 { return -1, 0, nil } p.nReady = n *p.readyReadFds = tmpReadFds *p.readyWriteFds = tmpWriteFds p.lastFd = 0 } flag := false for i := p.lastFd; i < p.maxFd+1; i++ { if syscall.FDIsSet(i, p.readyReadFds) { flag = true mode = 'r' syscall.FDClr(i, p.readyReadFds) } else if syscall.FDIsSet(i, p.readyWriteFds) { flag = true mode = 'w' syscall.FDClr(i, p.readyWriteFds) } if flag { if !syscall.FDIsSet(i, p.repeatFds) { p.DelFD(i, mode) } p.nReady-- p.lastFd = i return i, mode, nil } } // Will not reach here. Just to shut up the compiler. return -1, 0, nil }