We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2323

Summary: Invalid device id when hotplugging joystick on Windows/Xinput
Product: SDL Reporter: BurnSpamAddress
Component: joystickAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED WORKSFORME QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: icculus
Version: 2.0.1   
Hardware: x86_64   
OS: Windows 7   

Description BurnSpamAddress 2013-12-22 23:42:27 UTC
On Windows 7 64bit, the following sequence of events occurs when I unplug and replug my wireless Xbox360 controller:

{plug the device}
SDL.InitSubSystems(JOYSTICK | GAMECONTROLLER)
-- Missing CONTROLLERDEVICEADDED, see bug 2322
JOYDEVICEADDED which: 0

{unplug the device}
JOYAXISMOTION which: 0 -- repeat for each axis
JOYBUTTONUP which: 0 -- repeat for each button
JOYDEVICEREMOVED which: 0

{replug the device}
CONTROLLERDEVICEADDED -- finally 
JOYAXISMOTION which: 1 -- 6x events with Invalid ID!!!!
JOYDEVICEADDED which: 1 -- id 1 is finally added

We should not get a JOYAXISMOTION event with which:1 before a JOYDEVICE with which:1 has been added!

This is reproducible with SDL 2.0.1 on Windows 7 64bit and my Xbox360 wireless controller. SDL is apparently using the Xinput backend.
Comment 1 BurnSpamAddress 2013-12-22 23:49:58 UTC
This is even worse than I thought: when replugging the device, I get:

JOYDEVICEADDED which: 0 -- same id as on startup
JOYAXISMOTION  which: 1 -- different id from JOYDEVICEADDED

So when replugging the device, I correctly get the original device id but all events are delivered to a bogus id!

It was a lucky break that I decided to get very defensive when implementing a SDL backend in my project, so I have detailed logging information for all events that are delivered.

Please let me know if you need any more testing.
Comment 2 BurnSpamAddress 2013-12-23 00:10:36 UTC
This issue is also reproducible in hg 8064.
Comment 3 Sam Lantinga 2013-12-23 23:50:41 UTC
The added events provide a device index, but the other events provide a device instance ID.

Documentation in SDL_joystick.h:
 * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks, with the exact joystick
 *   behind a device_index changing as joysticks are plugged and unplugged.
 *
 * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted
 *   then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in.
Comment 4 BurnSpamAddress 2013-12-24 17:10:16 UTC
The crux of the issue is this:

JOYDEVICEREMOVED which: 0
JOYAXISMOTION which: 1 -- 6x events with *PROBLEM IS HERE*
JOYDEVICEADDED which: 1 -- id 1 is finally added

I am getting JOYAXISMOTION events with an instance id that does not exist. It does not exist, because SDL hasn't delivered an ADDED event yet - the added event comes *after* the MOTION events.

Is this really expected behavior?
Comment 5 Sam Lantinga 2013-12-24 20:23:03 UTC
Nope, that's not expected behavior. It's probably a race condition in the joystick detection code.
Comment 6 Ryan C. Gordon 2014-03-02 05:14:35 UTC
I couldn't reproduce this here with the latest in Mercurial. It's very possible we fixed it elsewhere, since we've made a lot of changes to the related code, but since this looks like a race condition, it's possible I just couldn't trigger it.

If you can still reproduce this with the latest in Mercurial, please reopen this bug and I'll dig in again.

Thanks,
--ryan.