summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Hlusiak <saschahlusiak@arcor.de>2011-04-20 19:33:10 +0200
committerSascha Hlusiak <saschahlusiak@arcor.de>2011-04-20 19:33:10 +0200
commit4358209e7e4383b4ebdec93cc116bb1c21d373a7 (patch)
treea9580fe941dcb1d3ddbb70be0d2794161a19fd12
parent3f03fa76f8fb152210c6ed80191f34e428af2c00 (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.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/jstk.c b/src/jstk.c
index 9796a46..ec6b79a 100644
--- a/src/jstk.c
+++ b/src/jstk.c
@@ -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);
}