private static int libusb_control_transfer(MonoUsbDeviceHandle deviceHandle, MonoUsbControlSetupHandle controlSetupHandle, int timeout) { MonoUsbTransfer transfer = MonoUsbTransfer.Alloc(0); ManualResetEvent completeEvent = new ManualResetEvent(false); GCHandle gcCompleteEvent = GCHandle.Alloc(completeEvent); transfer.FillControl(deviceHandle, controlSetupHandle, controlTransferDelegate, GCHandle.ToIntPtr(gcCompleteEvent), timeout); int r = (int)transfer.Submit(); if (r < 0) { transfer.Free(); gcCompleteEvent.Free(); return(r); } while (!completeEvent.WaitOne(0, false)) { r = MonoUsbApi.HandleEvents(sessionHandle); if (r < 0) { if (r == (int)MonoUsbError.ErrorInterrupted) { continue; } transfer.Cancel(); while (!completeEvent.WaitOne(0, false)) { if (MonoUsbApi.HandleEvents(sessionHandle) < 0) { break; } } transfer.Free(); gcCompleteEvent.Free(); return(r); } } if (transfer.Status == MonoUsbTansferStatus.TransferCompleted) { r = transfer.ActualLength; } else { r = (int)MonoUsbApi.MonoLibUsbErrorFromTransferStatus(transfer.Status); } transfer.Free(); gcCompleteEvent.Free(); return(r); }