SDL icon indicating copy to clipboard operation
SDL copied to clipboard

Possible race condition with hotplugging and force feedback

Open orbea opened this issue 3 years ago • 0 comments

OS: Gentoo linux: 5.15.64 SDL: 2.24.0 Controllers: 8bitdo SN30 Pro+ xpadneo: https://github.com/atar-axis/xpadneo/commit/48f4b119fdef9479d5e45056dc7a234e8959af0d

The xpadneo kernel driver has a short delay for the force feedback notify event. As a result of this SDL fails to see the controller as a haptic device when the controller connects after the program or when it disconnects and then reconnects.

This can be reproduced with this test program. sdl2hp.c.txt

It can be compiled with:

cc sdl2hp.c -std=c99 $(sdl2-config --cflags --libs) -o sdl2hp

To reproduce:

  1. Run the program: ./sdl2hp
  2. Turn on the controller.
  3. The controller physically rumbles while SDL2 believes it is not a haptic device and the rumble does not work in the program.
$ ./sdl2hp
Joystick Connected: Xbox 360 Controller
	Instance ID: 0, Player: 0
Device is not haptic
Ports: 1 0 0 0

And the second scenario.

  1. Turn on the controller.
  2. Start the program: ./sdl2hp
  3. The rumble works.
  4. Turn off the controller and wait for it to disconnect.
  5. Turn the controller back on.
  6. The controller physically rumbles while SDL2 believes it is not a haptic device and the rumble does not work in the program.
$ ./sdl2hp
Joystick Connected: Xbox 360 Controller
	Instance ID: 0, Player: 0
Force Feedback Enabled
Ports: 1 0 0 0

Instance ID: 0
Joystick 0 Disconnected
Ports: 0 0 0 0

Joystick Connected: Xbox 360 Controller
	Instance ID: 1, Player: 0
Device is not haptic
Ports: 1 0 0 0

This does not happen with my Sony PLAYSTATION(R)3 Controller which uses a different kernel driver. Additionally it doesn't happen if xpadneo is started with the kernel module parameter ff_connect_notify=0 or if a 1000ms delay is added before SDL_JoystickIsHaptic(...).

--- a/sdl2hp.c
+++ b/sdl2hp.c
@@ -62,6 +62,8 @@ int main(int argc, char *argv[]) {
                         SDL_JoystickGetPlayerIndex(joystick[port])
                     );
 
+                    SDL_Delay(1000);
+
                     if (SDL_JoystickIsHaptic(joystick[port])) {
                         haptic[port] =
                             SDL_HapticOpenFromJoystick(joystick[port]);

Also see this related SDL issue: https://github.com/libsdl-org/SDL/issues/6250

For reference there is a SDL2 hotplug example here: https://github.com/carmiker/sdl2-hotplug-example

orbea avatar Sep 18 '22 16:09 orbea