Example #1
0
int ReapTransfer(transfer_wrapper* wrapper, int timeout)
{
	void* context (wrapper->usb);
	libusb_transfer* transfer (&wrapper->libusb);
	if (transfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER)
	{
		libusb_free_transfer(transfer);
		return(0);
	}

	const int read = usb_reap_async_nocancel(context, timeout);
	bool processed (true);
	if (read > 0)
	{
		PreprocessTransfer(transfer, read);
	}
	else if (0 == read)
	{
		const int pkts (transfer->num_iso_packets);
		for (int i=0; i<pkts; ++i)
		{
			libusb_iso_packet_descriptor& desc (transfer->iso_packet_desc[i]);
			desc.actual_length = 0;
		}
	}
	else if (read < 0)
	{
		enum { ETIMEOUT = -116 };
		if (ETIMEOUT == read)
		{
			if (LIBUSB_TRANSFER_CANCELLED != transfer->status)
				processed = false;
		}
		else
		{
			libusb_cancel_transfer(transfer);
			processed = false;
		}
	}

	if (processed)
	{
		TListTransfers::Remove(wrapper);
		transfer->callback(transfer);
		if (read > 0)
			memset(transfer->buffer, 0, transfer->length);
	}

	return(read);
}
Example #2
0
int TransferAsync(struct BENCHMARK_TRANSFER_PARAM* transferParam, struct BENCHMARK_TRANSFER_HANDLE** handleRef)
{
	int ret;
	struct BENCHMARK_TRANSFER_HANDLE* handle;

	*handleRef = NULL;

	// Submit transfers until the maximum number of outstanding transfer(s) is reached.
	while (transferParam->OutstandingTransferCount < transferParam->Test->BufferCount)
	{
		// Get the next available benchmark transfer handle.
		*handleRef = handle = &transferParam->TransferHandles[transferParam->TransferHandleNextIndex];

		// If a libusb-win32 transfer context hasn't been setup for this benchmark transfer
		// handle, do it now.
		//
		if (!handle->Context)
		{
			// Data buffer(s) are located at the end of the transfer param.
			handle->Data = transferParam->Buffer + (transferParam->TransferHandleNextIndex * transferParam->Test->BufferSize);
			handle->DataMaxLength = transferParam->Test->BufferSize;

			
			switch (ENDPOINT_TYPE(transferParam))
			{
			case USB_ENDPOINT_TYPE_ISOCHRONOUS:
				ret = usb_isochronous_setup_async(transferParam->Test->DeviceHandle, 
					&handle->Context,
					transferParam->Ep.bEndpointAddress,
					transferParam->IsoPacketSize ? transferParam->IsoPacketSize : transferParam->Ep.wMaxPacketSize);
				break;
			case USB_ENDPOINT_TYPE_BULK:
				ret = usb_bulk_setup_async(transferParam->Test->DeviceHandle,
					&handle->Context,
					transferParam->Ep.bEndpointAddress);
				break;
			case USB_ENDPOINT_TYPE_INTERRUPT:
				ret = usb_interrupt_setup_async(transferParam->Test->DeviceHandle,
					&handle->Context,
					transferParam->Ep.bEndpointAddress);
				break;
			default:
				ret = -1;
				break;
			}

			if (ret < 0) 
			{
				CONERR("failed creating transfer context ret=%d\n",ret);
				goto Done;
			}
		}


		// Submit this transfer now.
		handle->ReturnCode = ret = usb_submit_async(handle->Context, handle->Data, handle->DataMaxLength);
		if (ret < 0) goto Done;

		// Mark this handle has InUse.
		handle->InUse = TRUE;

		// When transfers ir successfully submitted, OutstandingTransferCount goes up; when
		// they are completed it goes down.
		//
		transferParam->OutstandingTransferCount++;

		// Move TransferHandleNextIndex to the next available transfer.
		INC_ROLL(transferParam->TransferHandleNextIndex, transferParam->Test->BufferCount);

	}

	// If the number of outstanding transfers has reached the limit, wait for the 
	// oldest outstanding transfer to complete.
	//
	if (transferParam->OutstandingTransferCount == transferParam->Test->BufferCount)
	{
		// TransferHandleWaitIndex is the index of the oldest outstanding transfer.
		*handleRef = handle = &transferParam->TransferHandles[transferParam->TransferHandleWaitIndex];

		// Only wait, cancelling & freeing is handled by the caller.
		handle->ReturnCode = ret = usb_reap_async_nocancel(handle->Context, transferParam->Test->Timeout);

		if (ret < 0) goto Done;

		// Mark this handle has no longer InUse.
		handle->InUse = FALSE;

		// When transfers ir successfully submitted, OutstandingTransferCount goes up; when
		// they are completed it goes down.
		//
		transferParam->OutstandingTransferCount--;

		// Move TransferHandleWaitIndex to the oldest outstanding transfer.
		INC_ROLL(transferParam->TransferHandleWaitIndex, transferParam->Test->BufferCount);
	}

Done:
	return ret;
}