Skip to content

v4l2.go / waitForFrame panics on "large" fds. #65

@dezi

Description

@dezi

waitForFrame panics on "large" fd value.

panic: runtime error: index out of range [19] with length 16

goroutine 410912 [running]:
golang.org/x/sys/unix.(*FdSet).Set(...)
        /home/dezi/go/src/golang.org/x/sys/unix/fdset.go:12
github.com/blackjack/webcam.waitForFrame(0x4e2, 0x5)
        /home/dezi/go/src/github.com/blackjack/webcam/v4l2.go:563 +0x165
github.com/blackjack/webcam.(*Webcam).WaitForFrame(0xc0157a4c90?, 0x4f9ebf?)
        /home/dezi/go/src/github.com/blackjack/webcam/webcam.go:289 +0x1c

Referring to unix manpage of select, this can only handle fds beeing less than some limit.
This leads to unpredictable panics.

The solution is to replace "select" with "poll":

func waitForFrame(fd uintptr, timeout uint32) (count int, err error) {

	for {
		//fds := &unix.FdSet{}
		//fds.Set(int(fd))

		//var oneSecInNsec int64 = 1e9
		//timeoutNsec := int64(timeout) * oneSecInNsec
		//nativeTimeVal := unix.NsecToTimeval(timeoutNsec)
		//tv := &nativeTimeVal

		//count, err = unix.Select(int(fd+1), fds, nil, nil, tv)
		
		pollFds := []unix.PollFd{{Fd: int32(fd), Events: unix.POLLIN}}
		count, err = unix.Poll(pollFds, int(timeout*1000))

		if count < 0 && err == unix.EINTR {
			continue
		}
		return
	}
}

I have tested this, and it works.
If desired, I can provide a pull request.

Regards, dezi

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions