func (p *pollster) WaitFD(nsec int64) (fd int, mode int, err os.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, e int
		var tmpReadFds, tmpWriteFds syscall.FdSet_t
		for {
			// Temporary syscall.FdSet_ts into which the values are copied
			// because select mutates the values.
			tmpReadFds = *p.readFds
			tmpWriteFds = *p.writeFds

			n, e = syscall.Select(p.maxFd+1, &tmpReadFds, &tmpWriteFds, nil, timeout)
			if e != syscall.EINTR {
				break
			}
		}
		if e != 0 {
			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
}
Example #2
0
func (p *pollster) DelFD(fd int, mode int) bool {
	// pollServer is locked.

	if p.closed {
		return false
	}

	if mode == 'r' {
		if !syscall.FDIsSet(fd, p.readFds) {
			print("Select unexpected fd=", fd, " for read\n")
			return false
		}
		syscall.FDClr(fd, p.readFds)
	} else {
		if !syscall.FDIsSet(fd, p.writeFds) {
			print("Select unexpected fd=", fd, " for write\n")
			return false
		}
		syscall.FDClr(fd, p.writeFds)
	}

	// Doesn't matter if not already present.
	syscall.FDClr(fd, p.repeatFds)

	// We don't worry about maxFd here.

	return true
}
func (p *pollster) DelFD(fd int, mode int) {
	if mode == 'r' {
		if !syscall.FDIsSet(fd, p.readFds) {
			print("Select unexpected fd=", fd, " for read\n")
			return
		}
		syscall.FDClr(fd, p.readFds)
	} else {
		if !syscall.FDIsSet(fd, p.writeFds) {
			print("Select unexpected fd=", fd, " for write\n")
			return
		}
		syscall.FDClr(fd, p.writeFds)
	}

	// Doesn't matter if not already present.
	syscall.FDClr(fd, p.repeatFds)

	// We don't worry about maxFd here.
}
Example #4
0
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
}