diff options
author | Sascha Hlusiak <saschahlusiak@arcor.de> | 2011-04-20 19:33:10 +0200 |
---|---|---|
committer | Sascha Hlusiak <saschahlusiak@arcor.de> | 2011-04-20 19:33:10 +0200 |
commit | 4358209e7e4383b4ebdec93cc116bb1c21d373a7 (patch) | |
tree | a9580fe941dcb1d3ddbb70be0d2794161a19fd12 | |
parent | 3f03fa76f8fb152210c6ed80191f34e428af2c00 (diff) |
Free pInfo->private only once to fix server crash on unplug (bug #35391)
The hotplugged keyboard device and the main device share the same pInfo->private data
and the same jstkCoreUnInit, so the data is freed twice. Furthermore, since the keyboard
device will delete itself, we must not delete it from within the deletion of the main device.
Freeing pInfo->private is done by the main device, hopefully done independently of the order
in which the two devices will be removed by the server.
Should fix bug #35391
-rw-r--r-- | src/jstk.c | 27 |
1 files changed, 20 insertions, 7 deletions
@@ -611,6 +611,10 @@ SetupProc_fail: * jstkCoreUnInit -- * * Called when a device is unplugged and needs to be removed + * This is a bit tricky, because the keyboard device and the main device + * share the same private data, which must be freed only once, which is done + * by the main device. + * * *************************************************************************** */ @@ -620,15 +624,24 @@ jstkCoreUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { - JoystickDevPtr device = (JoystickDevPtr) pInfo->private; - - if (device->keyboard_device != NULL) - { - xf86DisableDevice(device->keyboard_device->dev, TRUE); - device->keyboard_device = NULL; + if (pInfo->private) { + JoystickDevPtr priv = (JoystickDevPtr) pInfo->private; + if (priv->keyboard_device == pInfo) { + /* this is the keyboard device */ + /* Unlink from private data to notify that the + * keyboard device is no more, but don't free */ + priv->keyboard_device = NULL; + } else { + /* freeing main device + if keyboard still exists, notify keyboard device that it's + private data is gone */ + if (priv->keyboard_device) + priv->keyboard_device->private = NULL; + + free (priv); + } } - free (device); pInfo->private = NULL; xf86DeleteInput(pInfo, 0); } |