Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Device or resource busy #14

Closed
colin-davis opened this issue Mar 6, 2018 · 6 comments
Closed

Device or resource busy #14

colin-davis opened this issue Mar 6, 2018 · 6 comments

Comments

@colin-davis
Copy link
Contributor

colin-davis commented Mar 6, 2018

Error:

panic : device or resource busy

When:

Any time the service tries to write to the camera (ioctl.Ioctl executions)

Example:

If I use the stdout_streamer.go the camera opens properly and is supported (I've successfully used an older version of this library also). Read events works fine such as cam.GetSupportedFormats() and cam.GetSupportedFrameSizes(format) but as soon as the first write event occurs cam.SetImageFormat(format, uint32(size.MaxWidth), uint32(size.MaxHeight)) the system panics with "device or resource busy".

Thoughts:

I've had no luck tracking down the source of this issue. My old build of this library still runs fine so I'm certain that my setup is correct. I'm guessing that something with os.OpenFile(path, unix.O_RDWR|unix.O_NONBLOCK, 0666) is blocking and only allowing read access.

PS: I am cross compiling from a windows machine (previously I was cross compiling from a mac). I will test today if this is the source of the issue.

Thanks

@colin-davis
Copy link
Contributor Author

Update: Cross Compiling from mac has the same issue.

@blackjack
Copy link
Owner

Can you specify which 'old' version was working for you?

@colin-davis
Copy link
Contributor Author

Unfortunately I only have the binary saved from it... I have been going back through the commits to see if I can recognize when it was built. I believe at the time there were still some C files included. Probably just before the project was converted to fully go. (sorry I know that's not very helpful).

@colin-davis
Copy link
Contributor Author

colin-davis commented Mar 6, 2018

Okay I'm on to something now. It seems that the os.OpenFile is not adhering to the flag for unix.O_RDWR|unix.O_NONBLOCK. I first tried to replace those with os.O_RDWR but that had the same outcome.

I can get the camera to work without write blocking by specifically defining unix.Open instead of os.OpenFile command.

Therefore the webcam.Open func becomes this:

func Open(path string) (*Webcam, error) {

	file, err := unix.Open(path, unix.O_RDWR|unix.O_NONBLOCK, 0666)
	fd := uintptr(file)

	if fd < 0 || err != nil {
		return nil, err
	}

	supportsVideoCapture, supportsVideoStreaming, err := checkCapabilities(fd)

	if err != nil {
		return nil, err
	}

	if !supportsVideoCapture {
		return nil, errors.New("Not a video capture device")
	}

	if !supportsVideoStreaming {
		return nil, errors.New("Device does not support the streaming I/O method")
	}

	w := new(Webcam)
	w.fd = fd
        // no longer have the file var so i just dropped it
	// w.file = file
	return w, nil
}

This might be usable considering the whole library requires linux anyways and unix is defined elsewhere.

EDIT: I have added a pull request bellow to compare the changes.

@colin-davis
Copy link
Contributor Author

colin-davis commented Mar 6, 2018

The Pull Request has an error where fd uintptr needs to be converted to an int for unix.Close().
ie: unix.Close(int(w.fd))

Temporarily this would work, however it seems that fd could be stored as an int and be converted to uintptr when it is needed as a value in syscalls.

Also as per golang.org/pkg/unsafe the Ioctl unsafe.pointer should be converted in the parameters of the Syscall function so the garbage collector knows to not move or delete anything until the Syscall is completed. Probably not a large issue, but I can try to refactor that while I'm changing fd anyways.

(4) Conversion of a Pointer to a uintptr when calling syscall.Syscall.

The Syscall functions in package syscall pass their uintptr arguments directly to the operating system, which then may, depending on the details of the call, reinterpret some of them as pointers. That is, the system call implementation is implicitly converting certain arguments back from uintptr to pointer.

If a pointer argument must be converted to uintptr for use as an argument, that conversion must appear in the call expression itself:

syscall.Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(n))

If this seems correct I can update the PR #15 soon with these changes.

@colin-davis
Copy link
Contributor Author

Thanks for merging

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants