Иногда (примерно в 50% запусков) EnumDevices возвращается через 5-10 секунд. Обычно это почти мгновенно. Других сообщений о подобном поведении я не нашел.
Когда все так медленно, можно профилировать, наблюдая за stdout :) Это:
std::cout << "A";
directInput8Interface->EnumDevices(DI8DEVCLASS_GAMECTRL, MyCallback, NULL, DIEDFL_ATTACHEDONLY);
std::cout << "C";
...
BOOL CALLBACK MyCallback(LPCDIDEVICEINSTANCE, LPVOID)
{
std::cout << "B";
return DIENUM_CONTINUE;
}
Кажется, зависает в случайной точке через перечисление устройств - иногда это будет до того, как callback будет вызван вообще, иногда после пары, а иногда будет после последнего вызова к нему.
Это явно упрощенный фрагмент кода; На самом деле я использую библиотеку ввода OIS ( http://sourceforge.net/projects/wgois/ ), так что для контекста, пожалуйста, смотрите полный источник здесь:
Там, похоже, не происходит ничего особенно фруктового, но, возможно, причиной может быть что-то в их инициализации - я недостаточно знаю о DI8, чтобы это заметить.
Буду очень признателен за любые идеи о том, почему это может быть так медленно!
РЕДАКТИРОВАТЬ:
Мне удалось поймать зависание в файле трассировки etl и проанализировать его в анализаторе производительности Windows. Похоже, что EnumDevices
в конце концов звонит DInput8.dll!fGetProductStringFromDevice
, который звонит HIDUSB.SYS!HumCallUSB
, который звонит KeWaitForSingleObject
и ждет. В 9 случаях из 10 (буквально - в трассировке 10 выборок) это возвращается очень быстро (по 324 мкс каждый), при этом готовый стек вызовов содержит usbport.sys!USBPORT_Core_iCompleteDoneTransfer
, за которым следует HIDUSB.SYS!HumCallUsbComplete
, что выглядит вполне нормально.
Но 1 раз из 10 на возврат уходит почти ровно 5 секунд. В готовящемся стеке вызовов есть ntkrnlmp.exe!KiTimerExpiration
вместо функции HIDUSB.SYS
. Я предполагаю, что все это указывает на то, что драйвер HIDUSB.SYS опрашивает устройства асинхронно с тайм-аутом в 5 секунд, и иногда он дает сбой и достигает этого тайм-аута.
Я не знаю, связан ли этот сбой с каким-то конкретным устройством (у меня есть несколько USB HID) или он случайный - это трудно проверить, потому что это не всегда происходит. Опять же, любая информация, которую кто-либо может мне дать, будет оценена по достоинству, хотя я не питаю никакой надежды на то, что Microsoft исправит это в ближайшее время, учитывая странную ситуацию, в которой находится DirectInput!
Возможно, мне просто придется начать инициализацию ввода раньше, асинхронно, и принять, что иногда будет 5-секундная задержка, прежде чем пользователь сможет ввести данные.