kylelemons/gousb — pull request #3 by mevers47 (2013-01-27 04:00:46+00:00)
Title: Let the gc close the usb context

Hello, I am building a driver for the Velleman k8055 USB experiment interface board as an Go exercise. I plan to upload it to github as a public project. Having a background with high level languages I am used to work with a garbage collector. And being this close to the metal is relatively new for me, so please bear with me.

I like the idiomatic approach a lot. And being someone usually working with a gc I made the following code for my project:
```go
func getUsbDevice(address uint8) (*usb.Device, error) {
ctx := usb.NewContext()
defer ctx.Close()

var productId usb.ID = DEVICE_BASE_ID + usb.ID(address)
devices, err := ctx.ListDevices(func(desc *usb.Descriptor) bool {
if desc.Product == productId && desc.Vendor == VENDOR_ID {
return true
}

return false
})

if nil != err {
return nil, err
}

switch len(devices) {
case 0:
return nil, fmt.Errorf("Could not find k8055 on address: %d", address)

case 1:
return devices[0], nil
}

return nil, fmt.Errorf("Mutiple devices found with usb vendor:product combination '%x:%s'", VENDOR_ID, productId)
}
```

This piece of code was the beginning of an insightful journey into the libusb codebase. When I called OpenEndpoint on the usb Device object I got an "unknown error". So I traced the call back to the timerfd_settime call in function libusb_submit_transfer in libusb/io.c.

The solution was to remove "defer ctx.Close()".

So I made three adjustments in this PR to make it (hopefully) more idiomatic:
* If the gc cleans an Context the finalizer should close it first.
* Passed the Context to each Device so the context is not collected when there are still devices in memory. There are some functions in libusb that rely on devices to have a pointer to context.
* Check if we got a libusb context pointer before opening an endpoint.

I got the finalizer idea from http://golang.org/src/pkg/os/file_unix.go but I did not quite understand how they use it. So maybe this needs some more polishing. Anyway it would be really nice if we can take full advantage of the gc.