Replace wHashTable with wArrayList in USB channel
The streamID is not guaranteed to be uniqe, so add all transfers to a list and remove by checking pointers instead of the streamID
This commit is contained in:
parent
ea8f93441d
commit
3ebc71abf3
@ -75,12 +75,33 @@ struct _ASYNC_TRANSFER_USER_DATA
|
||||
UINT32 OutputBufferSize;
|
||||
URBDRC_CHANNEL_CALLBACK* callback;
|
||||
t_isoch_transfer_cb cb;
|
||||
wHashTable* queue;
|
||||
wArrayList* queue;
|
||||
#if !defined(HAVE_STREAM_ID_API)
|
||||
UINT32 streamID;
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct libusb_transfer* list_contains(wArrayList* list, UINT32 streamID)
|
||||
{
|
||||
int x, count;
|
||||
if (!list)
|
||||
return NULL;
|
||||
count = ArrayList_Count(list);
|
||||
for (x = 0; x < count; x++)
|
||||
{
|
||||
struct libusb_transfer* transfer = ArrayList_GetItem(list, x);
|
||||
|
||||
#if defined(HAVE_STREAM_ID_API)
|
||||
const UINT32 currentID = libusb_transfer_get_stream_id(transfer);
|
||||
#else
|
||||
const UINT32 currentID = user_data->streamID;
|
||||
#endif
|
||||
if (currentID == streamID)
|
||||
return transfer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL log_libusb_result(wLog* log, DWORD lvl, const char* fmt, int error, ...)
|
||||
{
|
||||
if (error < 0)
|
||||
@ -235,7 +256,7 @@ static void func_iso_callback(struct libusb_transfer* transfer)
|
||||
const UINT32 InterfaceId =
|
||||
((STREAM_ID_PROXY << 30) | user_data->idev->get_ReqCompletion(user_data->idev));
|
||||
|
||||
if (HashTable_Contains(user_data->queue, (void*)(size_t)streamID))
|
||||
if (list_contains(user_data->queue, streamID))
|
||||
{
|
||||
if (!user_data->noack)
|
||||
{
|
||||
@ -247,7 +268,7 @@ static void func_iso_callback(struct libusb_transfer* transfer)
|
||||
user_data->OutputBufferSize);
|
||||
user_data->data = NULL;
|
||||
}
|
||||
HashTable_Remove(user_data->queue, (void*)(size_t)streamID);
|
||||
ArrayList_Remove(user_data->queue, transfer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -303,7 +324,7 @@ static void func_bulk_transfer_cb(struct libusb_transfer* transfer)
|
||||
streamID = user_data->streamID;
|
||||
#endif
|
||||
|
||||
if (HashTable_Contains(user_data->queue, (void*)(size_t)streamID))
|
||||
if (list_contains(user_data->queue, streamID))
|
||||
{
|
||||
const UINT32 InterfaceId =
|
||||
((STREAM_ID_PROXY << 30) | user_data->idev->get_ReqCompletion(user_data->idev));
|
||||
@ -314,7 +335,7 @@ static void func_bulk_transfer_cb(struct libusb_transfer* transfer)
|
||||
transfer->status, user_data->StartFrame, user_data->ErrorCount,
|
||||
transfer->actual_length);
|
||||
user_data->data = NULL;
|
||||
HashTable_Remove(user_data->queue, (void*)(size_t)streamID);
|
||||
ArrayList_Remove(user_data->queue, transfer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1171,8 +1192,7 @@ static int libusb_udev_isoch_transfer(IUDEVICE* idev, URBDRC_CHANNEL_CALLBACK* c
|
||||
#endif
|
||||
libusb_set_iso_packet_lengths(iso_transfer, iso_packet_size);
|
||||
|
||||
if ((HashTable_Contains(pdev->request_queue, (void*)(size_t)streamID)) ||
|
||||
(HashTable_Add(pdev->request_queue, (void*)(size_t)streamID, iso_transfer) < 0))
|
||||
if (ArrayList_Add(pdev->request_queue, iso_transfer) < 0)
|
||||
{
|
||||
WLog_Print(urbdrc->log, WLOG_WARN,
|
||||
"Failed to queue iso transfer, streamID %08" PRIx32 " already in use!",
|
||||
@ -1290,8 +1310,7 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, URBDRC_CHANNEL
|
||||
#else
|
||||
user_data->streamID = streamID;
|
||||
#endif
|
||||
if ((HashTable_Contains(pdev->request_queue, (void*)(size_t)streamID)) ||
|
||||
(HashTable_Add(pdev->request_queue, (void*)(size_t)streamID, transfer) < 0))
|
||||
if (ArrayList_Add(pdev->request_queue, transfer) < 0)
|
||||
{
|
||||
WLog_Print(urbdrc->log, WLOG_WARN,
|
||||
"Failed to queue transfer, streamID %08" PRIx32 " already in use!", streamID);
|
||||
@ -1302,12 +1321,11 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, URBDRC_CHANNEL
|
||||
return libusb_submit_transfer(transfer);
|
||||
}
|
||||
|
||||
static int func_cancel_xact_request(URBDRC_PLUGIN* urbdrc, wHashTable* queue, uint32_t streamID,
|
||||
struct libusb_transfer* transfer)
|
||||
static int func_cancel_xact_request(URBDRC_PLUGIN* urbdrc, struct libusb_transfer* transfer)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!urbdrc || !queue || !transfer)
|
||||
if (!urbdrc || !transfer)
|
||||
return -1;
|
||||
|
||||
status = libusb_cancel_transfer(transfer);
|
||||
@ -1325,22 +1343,21 @@ static int func_cancel_xact_request(URBDRC_PLUGIN* urbdrc, wHashTable* queue, ui
|
||||
static void libusb_udev_cancel_all_transfer_request(IUDEVICE* idev)
|
||||
{
|
||||
UDEVICE* pdev = (UDEVICE*)idev;
|
||||
ULONG_PTR* keys;
|
||||
int count, x;
|
||||
|
||||
if (!pdev || !pdev->request_queue || !pdev->urbdrc)
|
||||
return;
|
||||
|
||||
count = HashTable_GetKeys(pdev->request_queue, &keys);
|
||||
ArrayList_Lock(pdev->request_queue);
|
||||
count = ArrayList_Count(pdev->request_queue);
|
||||
|
||||
for (x = 0; x < count; x++)
|
||||
{
|
||||
struct libusb_transfer* transfer =
|
||||
HashTable_GetItemValue(pdev->request_queue, (void*)keys[x]);
|
||||
func_cancel_xact_request(pdev->urbdrc, pdev->request_queue, (uint32_t)keys[x], transfer);
|
||||
struct libusb_transfer* transfer = ArrayList_GetItem(pdev->request_queue, x);
|
||||
func_cancel_xact_request(pdev->urbdrc, transfer);
|
||||
}
|
||||
|
||||
free(keys);
|
||||
ArrayList_Unlock(pdev->request_queue);
|
||||
}
|
||||
|
||||
static int libusb_udev_cancel_transfer_request(IUDEVICE* idev, UINT32 RequestId)
|
||||
@ -1348,24 +1365,22 @@ static int libusb_udev_cancel_transfer_request(IUDEVICE* idev, UINT32 RequestId)
|
||||
UDEVICE* pdev = (UDEVICE*)idev;
|
||||
struct libusb_transfer* transfer;
|
||||
URBDRC_PLUGIN* urbdrc;
|
||||
BOOL id1;
|
||||
uint32_t cancelID;
|
||||
uint32_t cancelID1 = 0x40000000 | RequestId;
|
||||
uint32_t cancelID2 = 0x80000000 | RequestId;
|
||||
|
||||
if (!idev || !pdev->urbdrc || !pdev->request_queue)
|
||||
return -1;
|
||||
|
||||
id1 = HashTable_Contains(pdev->request_queue, (void*)(size_t)cancelID1);
|
||||
transfer = list_contains(pdev->request_queue, cancelID1);
|
||||
if (!transfer)
|
||||
transfer = list_contains(pdev->request_queue, cancelID2);
|
||||
|
||||
if (!id1)
|
||||
if (!transfer)
|
||||
return -1;
|
||||
|
||||
urbdrc = (URBDRC_PLUGIN*)pdev->urbdrc;
|
||||
cancelID = (id1) ? cancelID1 : cancelID2;
|
||||
|
||||
transfer = HashTable_GetItemValue(pdev->request_queue, (void*)(size_t)cancelID);
|
||||
return func_cancel_xact_request(urbdrc, pdev->request_queue, cancelID, transfer);
|
||||
return func_cancel_xact_request(urbdrc, transfer);
|
||||
}
|
||||
|
||||
BASIC_STATE_FUNC_DEFINED(channelManager, IWTSVirtualChannelManager*)
|
||||
@ -1420,7 +1435,7 @@ static void udev_free(IUDEVICE* idev)
|
||||
|
||||
/* release all interface and attach kernel driver */
|
||||
udev->iface.attach_kernel_driver(idev);
|
||||
HashTable_Free(udev->request_queue);
|
||||
ArrayList_Free(udev->request_queue);
|
||||
/* free the config descriptor that send from windows */
|
||||
msusb_msconfig_free(udev->MsConfig);
|
||||
libusb_close(udev->libusb_handle);
|
||||
@ -1655,12 +1670,12 @@ static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUS
|
||||
/* initialize pdev */
|
||||
pdev->bus_number = bus_number;
|
||||
pdev->dev_number = dev_number;
|
||||
pdev->request_queue = HashTable_New(TRUE);
|
||||
pdev->request_queue = ArrayList_New(TRUE);
|
||||
|
||||
if (!pdev->request_queue)
|
||||
goto fail;
|
||||
|
||||
pdev->request_queue->valueFree = request_free;
|
||||
ArrayList_Object(pdev->request_queue)->fnObjectFree = request_free;
|
||||
|
||||
/* set config of windows */
|
||||
pdev->MsConfig = msusb_msconfig_new();
|
||||
|
@ -63,7 +63,7 @@ struct _UDEVICE
|
||||
MSUSB_CONFIG_DESCRIPTOR* MsConfig;
|
||||
LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig;
|
||||
|
||||
wHashTable* request_queue;
|
||||
wArrayList* request_queue;
|
||||
|
||||
URBDRC_PLUGIN* urbdrc;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user