title: DirectInput8 EnumDevices sometimes painfully slow
body: <p>Sometimes (in about 50% of runs), EnumDevices takes 5-10 seconds to return. Normally it is almost instant. I couldn't find any other reports of this kind of behaviour.</p>
  
  <p>When things are this slow, it's ok to profile by watching stdout :) This:</p>
  
  <pre><code>std::cout &lt;&lt; "A";
  directInput8Interface-&gt;EnumDevices(DI8DEVCLASS_GAMECTRL, MyCallback, NULL, DIEDFL_ATTACHEDONLY);
  std::cout &lt;&lt; "C";
  
  ...
  
  BOOL CALLBACK MyCallback(LPCDIDEVICEINSTANCE, LPVOID)
  {
      std::cout &lt;&lt; "B";
      return DIENUM_CONTINUE;
  }
  </code></pre>
  
  <p>Seems to hang at a random point through enumerating devices - sometimes it'll be before the callback is called at all, sometimes after a couple, and sometimes it will be after the last call to it.</p>
  
  <p>This is clearly a simplified chunk of code; I'm actually using the OIS input library ( <a href="http://sourceforge.net/projects/wgois/" rel="noreferrer">http://sourceforge.net/projects/wgois/</a> ), so for context, please see the full source here:</p>
  
  <p><a href="http://wgois.svn.sourceforge.net/viewvc/wgois/ois/trunk/src/win32/Win32InputManager.cpp?revision=39&amp;view=markup" rel="noreferrer">http://wgois.svn.sourceforge.net/viewvc/wgois/ois/trunk/src/win32/Win32InputManager.cpp?revision=39&amp;view=markup</a></p>
  
  <p>There doesn't seem to be anything particularly fruity going on there though, but possibly something in their initialisation could be the cause - I don't know enough about DI8 to spot it.</p>
  
  <p>Any ideas about why it could be so slow will be greatly appreciated!</p>
  
  <p>EDIT:</p>
  
  <p>I've managed to catch the hang in an etl trace file and analysed it in Windows Performance Analyzer. It looks like <code>EnumDevices</code> eventually calls through to <code>DInput8.dll!fGetProductStringFromDevice</code>, which calls <code>HIDUSB.SYS!HumCallUSB</code>, which calls <code>KeWaitForSingleObject</code> and waits. 9 times out of 10 (literally - there are 10 samples in the trace) this returns very quickly (324us each), with the readying callstack containing <code>usbport.sys!USBPORT_Core_iCompleteDoneTransfer</code> followed by <code>HIDUSB.SYS!HumCallUsbComplete</code>, which looks quite normal.</p>
  
  <p>But 1 time in 10, this takes almost exactly 5 seconds to return. On the readying callstack is <code>ntkrnlmp.exe!KiTimerExpiration</code> instead of the <code>HIDUSB.SYS</code> function. I guess all this indicates that the HIDUSB.SYS driver is querying devices asynchronously with a timeout of 5 seconds, and sometimes it fails and hits this timeout.</p>
  
  <p>I don't know whether this failure is associated with any one device in particular (I do have a few USB HIDs) or if it's random - it's hard to test because it doesn't always happen. Again, any information anyone can give me will be appreciated, though I don't hold out any hope for Microsoft fixing this any time soon given the odd situation DirectInput is in!</p>
  
  <p>Perhaps I'll just have to start initialising input earlier, asynchronously, and accept that sometimes there'll be a 5 second delay before user input can happen.</p>