Joystick hotplug support through HAL

Hello,

I try to support joystick hotplug on Linux through HAL. When a joystick
is plugged or unplugged I receive an HAL message and restart joystick
subsystem.

  // Restart SDL joystick subsystem
  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
  if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
  {
    printf("HAL: Stop joystick subsystem failed");
    return false;
  }
  if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
  {
    printf("HAL: Restart joystick subsystem failed : %s",SDL_GetError

());
return false;
}

  // Initialize joysticks ...

It works with one joystick but failed with 2 when I disconnect the last.
An “double free or corruption (fasttop)” error occurred.
I have also test to close all joysticks before restart subsystem.

gdb backtrace:
SDL-1.2.13

#0 0x000000350fc32f05 in raise (sig=)
at …/nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x000000350fc34a73 in abort () at abort.c:88
#2 0x000000350fc72438 in __libc_message (do_abort=2,
fmt=0x350fd3c428 “*** glibc detected *** %s: %s: 0x%s ***\n”)
at …/sysdeps/unix/sysv/linux/libc_fatal.c:170
#3 0x000000350fc77ec8 in malloc_printerr (action=2,
str=0x350fd3c4c8 “double free or corruption (fasttop)”,
ptr=) at malloc.c:5994
#4 0x000000350fc7a486 in __libc_free (mem=0x350fd32880) at malloc.c:3625
#5 0x0000003dd1e3421b in SDL_JoystickQuit ()
at src/joystick/SDL_joystick.c:411
#6 0x0000003dd1e07f85 in SDL_QuitSubSystem (flags=512) at src/SDL.c:184
#7 0x0000000000e29934 in CHalManager::RemoveDevice (this=0x150a660,
udi=0x1a0fe44 “/org/freedesktop/Hal/devices/
usb_device_45e_289_noserial_if0_logicaldev_input”) at HalManager.cpp:686
#8 0x0000000000e29b80 in CHalManager::DeviceRemoved (ctx=0x1b18080,
udi=0x1a0fe44 “/org/freedesktop/Hal/devices/
usb_device_45e_289_noserial_if0_logicaldev_input”) at HalManager.cpp:49
#9 0x00007ffff7866d29 in ?? () from /usr/lib64/libhal.so.1
#10 0x000000350f00ef7b in dbus_connection_dispatch ()
from /lib64/libdbus-1.so.3
#11 0x000000350f00f33b in ?? () from /lib64/libdbus-1.so.3
—Type to continue, or q to quit—
#12 0x0000000000e29d3b in CHalManager::Update (this=0x150a660)
at HalManager.cpp:373
#13 0x0000000000846f14 in CApplication::ProcessSlow (this=0x149c9a0)
at Application.cpp:5125
#14 0x000000000084e617 in CApplication::Process (this=0x149c9a0)
at Application.cpp:5056
#15 0x0000000000b4828b in CXBApplicationEx::Run (this=0x149c9a0)
at XBApplicationEx.cpp:210
#16 0x0000000000b48c26 in main (argc=1, argv=0x7fffffffe338)
at XboxMediaCenter.cpp:117

Do you have any ideas ?

Just to get the ball rolling with ideas, (As we all want Autoplug support
with joysticks in XBMC :wink: )

Perhaps you need to pump events or atleast run the eventhandling method
between init and quit, should be in XBApplicationEx.cpp, ReadInput. Also
afaik just init a subsystem when already init?ed it will quit and init.

Cheers,
Topfs2On Sat, Feb 21, 2009 at 3:22 AM, Adrien Lassere wrote:

Hello,

I try to support joystick hotplug on Linux through HAL. When a joystick
is plugged or unplugged I receive an HAL message and restart joystick
subsystem.

 // Restart SDL joystick subsystem
 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
 if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
 {
   printf("HAL: Stop joystick subsystem failed");
   return false;
 }
 if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
 {
   printf("HAL: Restart joystick subsystem failed : %s",SDL_GetError

());
return false;
}

 // Initialize joysticks ...

It works with one joystick but failed with 2 when I disconnect the last.
An “double free or corruption (fasttop)” error occurred.
I have also test to close all joysticks before restart subsystem.

gdb backtrace:
SDL-1.2.13

#0 0x000000350fc32f05 in raise (sig=)
at …/nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x000000350fc34a73 in abort () at abort.c:88
#2 0x000000350fc72438 in __libc_message (do_abort=2,
fmt=0x350fd3c428 “*** glibc detected *** %s: %s: 0x%s ***\n”)
at …/sysdeps/unix/sysv/linux/libc_fatal.c:170
#3 0x000000350fc77ec8 in malloc_printerr (action=2,
str=0x350fd3c4c8 “double free or corruption (fasttop)”,
ptr=) at malloc.c:5994
#4 0x000000350fc7a486 in __libc_free (mem=0x350fd32880) at malloc.c:3625
#5 0x0000003dd1e3421b in SDL_JoystickQuit ()
at src/joystick/SDL_joystick.c:411
#6 0x0000003dd1e07f85 in SDL_QuitSubSystem (flags=512) at src/SDL.c:184
#7 0x0000000000e29934 in CHalManager::RemoveDevice (this=0x150a660,
udi=0x1a0fe44 “/org/freedesktop/Hal/devices/
usb_device_45e_289_noserial_if0_logicaldev_input”) at HalManager.cpp:686
#8 0x0000000000e29b80 in CHalManager::DeviceRemoved (ctx=0x1b18080,
udi=0x1a0fe44 “/org/freedesktop/Hal/devices/
usb_device_45e_289_noserial_if0_logicaldev_input”) at HalManager.cpp:49
#9 0x00007ffff7866d29 in ?? () from /usr/lib64/libhal.so.1
#10 0x000000350f00ef7b in dbus_connection_dispatch ()
from /lib64/libdbus-1.so.3
#11 0x000000350f00f33b in ?? () from /lib64/libdbus-1.so.3
—Type to continue, or q to quit—
#12 0x0000000000e29d3b in CHalManager::Update (this=0x150a660)
at HalManager.cpp:373
#13 0x0000000000846f14 in CApplication::ProcessSlow (this=0x149c9a0)
at Application.cpp:5125
#14 0x000000000084e617 in CApplication::Process (this=0x149c9a0)
at Application.cpp:5056
#15 0x0000000000b4828b in CXBApplicationEx::Run (this=0x149c9a0)
at XBApplicationEx.cpp:210
#16 0x0000000000b48c26 in main (argc=1, argv=0x7fffffffe338)
at XboxMediaCenter.cpp:117

Do you have any ideas ?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Can you provide a small example program for us to debug?On Fri, Feb 20, 2009 at 9:22 PM, Adrien Lassere wrote:

I try to support joystick hotplug on Linux through HAL. When a joystick
is plugged or unplugged I receive an HAL message and restart joystick
subsystem.

It works with one joystick but failed with 2 when I disconnect the last.
An “double free or corruption (fasttop)” error occurred.
I have also test to close all joysticks before restart subsystem.


http://codebad.com/

Le Sat, 21 Feb 2009 20:30:25 +0100, Tobias Arrskog a ?crit?:

Just to get the ball rolling with ideas, (As we all want Autoplug
support with joysticks in XBMC :wink: )

Perhaps you need to pump events or atleast run the eventhandling method
between init and quit, should be in XBApplicationEx.cpp, ReadInput. Also
afaik just init a subsystem when already init?ed it will quit and init.

Cheers,
Topfs2

I have tested various combination of ReadInput and SDL_PumEvents with no
success.

Starting the joystick subsystem already initialized doesn’t restart it.

Le Sat, 21 Feb 2009 18:24:11 -0500, Donny Viszneki a ?crit?:> On Fri, Feb 20, 2009 at 9:22 PM, Adrien Lassere <@Adrien_Lassere> wrote:

I try to support joystick hotplug on Linux through HAL. When a joystick
is plugged or unplugged I receive an HAL message and restart joystick
subsystem.

It works with one joystick but failed with 2 when I disconnect the
last. An “double free or corruption (fasttop)” error occurred. I have
also test to close all joysticks before restart subsystem.

Can you provide a small example program for us to debug?

I have writen a not so small example program. This program doesn’t open
or close joysticks because it fails on SDL_QuitSubSystem when the second
joystick has been unplugged.

gcc -g -o hal_joystick hal_joysick.c pkg-config --libs --cflags dbus-1 hal dbus-glib-1 glib-2.0 sdl

#include <stdio.h>
#include <unistd.h>
#include <hal/libhal.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <SDL/SDL.h>

typedef struct{
char *udi;
SDL_Joystick *joy;
}HalJoy;

HalJoy *joysticks[10];
uint nJoy = 0;

static void handle_device_added(LibHalContext *ctx, const char *udi){
printf("\nDevice with udi=%s is added\n", udi);

DBusError dbusError;
dbus_error_init(&dbusError);

int i;
char **ptr;
char **capability;
capability =libhal_device_get_property_strlist (ctx, udi,
“info.capabilities”, &dbusError);
if(capability == NULL)
return;;

for(ptr = capability; *ptr != NULL;ptr++){
if(strcmp(*ptr, “input.joystick”) == 0){
printf(“A joystick has been detected\n”);

  // Create joystick
  for(i=0;joysticks[i] != NULL; i++){};
  joysticks[i] = (HalJoy*)malloc(sizeof(HalJoy));
  joysticks[i]->udi = udi;
  nJoy++;
  
  // Restart SDL joystick subsystem
  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
  if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0){
printf("HAL: Stop joystick subsystem failed");
break;
  }
  if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0){
printf("HAL: Restart joystick subsystem failed : %s",SDL_GetError

());
break;
}
//InitializeJoystick();
}
}
libhal_free_string_array(capability);
}

static void handle_device_removed(LibHalContext *ctx, const char *udi){
printf("\nDevice with udi=%s is removed\n", udi);

int i;
for(i = 0; i < 10; i++){
if (joysticks[i] != NULL && strcmp(joysticks[i]->udi, udi) == 0){

  // Restart SDL joystick subsystem
  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
  if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
printf("HAL: Stop joystick subsystem failed");
  if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
printf("HAL: Restart joystick subsystem failed : %s",SDL_GetError

());

  //InitializeJoystick();

  // Free joystick      
  free(joysticks[i]);
  joysticks[i]=NULL;
  nJoy--;
}

}
}

int main(){

DBusConnection *connection;
DBusError error;

LibHalContext *ctx;
const char *udi = “/org/freedesktop/Hal/devices/computer”;

dbus_error_init(&error);
connection = dbus_bus_get(DBUS_BUS_SYSTEM,&error);

if ( dbus_error_is_set(&error) ){
printf(“Unable to connect to DBus: %s\n”,error.message);
dbus_error_free(&error);
return 1;
}

ctx = libhal_ctx_new();

if ( !libhal_ctx_set_dbus_connection(ctx, connection) ){
printf(“Error %s\n”,error.message);
dbus_error_free(&error);
return 1;
}

if ( !libhal_ctx_init(ctx, &error) ){
printf(“Hal context initializing failure %s\n”,error.message);
return 1;
}

GMainLoop *loop;
loop = g_main_loop_new(NULL,FALSE);

dbus_connection_setup_with_g_main(connection,NULL);

libhal_ctx_set_device_added(ctx, handle_device_added);
libhal_ctx_set_device_removed(ctx, handle_device_removed);

g_main_loop_run(loop);
}

I specifically need a program which causes the crash. Thanks!On Sun, Feb 22, 2009 at 4:16 PM, Adrien Lassere wrote:

Le Sat, 21 Feb 2009 18:24:11 -0500, Donny Viszneki a ?crit :

It works with one joystick but failed with 2 when I disconnect the
last. An “double free or corruption (fasttop)” error occurred. I have
also test to close all joysticks before restart subsystem.

Can you provide a small example program for us to debug?

I have writen a not so small example program. This program doesn’t open
or close joysticks because it fails on SDL_QuitSubSystem when the second
joystick has been unplugged.


http://codebad.com/

Le Sun, 22 Feb 2009 16:46:24 -0500, Donny Viszneki a ?crit?:> On Sun, Feb 22, 2009 at 4:16 PM, Adrien Lassere <@Adrien_Lassere> wrote:

Le Sat, 21 Feb 2009 18:24:11 -0500, Donny Viszneki a ?crit :

It works with one joystick but failed with 2 when I disconnect the
last. An “double free or corruption (fasttop)” error occurred. I have
also test to close all joysticks before restart subsystem.

Can you provide a small example program for us to debug?

I have writen a not so small example program. This program doesn’t open
or close joysticks because it fails on SDL_QuitSubSystem when the
second joystick has been unplugged.

I specifically need a program which causes the crash. Thanks!

I don’t understand why this program doesn’t suit for your problem.
After the program start, you must plug both joysticks and the crash
occurs when you unplug the second joystick.

Ah, sorry, I must have misunderstood you earlier, this sounds perfect.On Sun, Feb 22, 2009 at 5:29 PM, Adrien Lassere wrote:

I don’t understand why this program doesn’t suit for your problem.
After the program start, you must plug both joysticks and the crash
occurs when you unplug the second joystick.


http://codebad.com/

Le lundi 23 f?vrier 2009 ? 16:12 -0500, Donny Viszneki a ?crit :

Ah, sorry, I must have misunderstood you earlier, this sounds perfect.

I have found a fix to the bug. It avoid double free in SDL_JoystickQuit
function.

Index: src/joystick/linux/SDL_sysjoystick.c===================================================================
— src/joystick/linux/SDL_sysjoystick.c (r?vision 4454)
+++ src/joystick/linux/SDL_sysjoystick.c (copie de travail)
@@ -1211,8 +1211,8 @@

 for (i = 0; SDL_joylist[i].fname; ++i) {
     SDL_free(SDL_joylist[i].fname);
  •    SDL_joylist[i].fname = NULL;
    
    }
  • SDL_joylist[0].fname = NULL;
    }

#endif /* SDL_JOYSTICK_LINUX */

Great work!On Thu, Mar 5, 2009 at 12:04 PM, Adrien Lassere wrote:

I have found a fix to the bug. It avoid double free in SDL_JoystickQuit
function.


http://codebad.com/

Le lundi 23 f??vrier 2009 ?? 16:12 -0500, Donny Viszneki a ??crit :

Ah, sorry, I must have misunderstood you earlier, this sounds perfect.

I have found a fix to the bug. It avoid double free in SDL_JoystickQuit
function.

Thanks! A similar fix has been checked in to source control.

See ya,
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC