[gtk+] Fix bugs that crashed gdk_display_close() on x11
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Fix bugs that crashed gdk_display_close() on x11
- Date: Sun, 19 Sep 2010 02:59:08 +0000 (UTC)
commit c7d73ee5875786f88ab72ed94072d25c207bcf94
Author: Havoc Pennington <hp pobox com>
Date: Sat Sep 18 22:57:36 2010 -0400
Fix bugs that crashed gdk_display_close() on x11
* _gdk_device_set_associated_device() did not allow NULL device
* GdkDisplay should dispose device manager to avoid devices
trying to touch the display in finalize
* GdkDeviceManagerXI did not ref devices in id hash
* GdkDisplayX11 did not ref devices in ->input_devices
gdk/gdkdevice.c | 2 +-
gdk/gdkdisplay.c | 10 ++++++++--
gdk/x11/gdkdevicemanager-x11.c | 16 ++++++++++++----
gdk/x11/gdkdevicemanager-xi.c | 17 +++++++++++------
gdk/x11/gdkdevicemanager-xi2.c | 19 +++++++++++++------
gdk/x11/gdkdisplay-x11.c | 9 +++++----
gdk/x11/gdkeventsource.c | 5 +++++
7 files changed, 55 insertions(+), 23 deletions(-)
---
diff --git a/gdk/gdkdevice.c b/gdk/gdkdevice.c
index 5c62e09..3c8114b 100644
--- a/gdk/gdkdevice.c
+++ b/gdk/gdkdevice.c
@@ -766,7 +766,7 @@ _gdk_device_set_associated_device (GdkDevice *device,
GdkDevicePrivate *priv;
g_return_if_fail (GDK_IS_DEVICE (device));
- g_return_if_fail (GDK_IS_DEVICE (associated));
+ g_return_if_fail (associated == NULL || GDK_IS_DEVICE (associated));
priv = device->priv;
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index dc1c5c8..e74f74e 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -278,7 +278,7 @@ gdk_display_dispose (GObject *object)
_gdk_displays = g_slist_remove (_gdk_displays, object);
- if (gdk_display_get_default() == display)
+ if (gdk_display_get_default () == display)
{
if (_gdk_displays)
gdk_display_manager_set_default_display (gdk_display_manager_get(),
@@ -289,7 +289,13 @@ gdk_display_dispose (GObject *object)
}
if (device_manager)
- g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, object);
+ {
+ /* this is to make it drop devices which may require using the X
+ * display and therefore can't be cleaned up in finalize.
+ * It will also disconnect device_removed_cb
+ */
+ g_object_run_dispose (G_OBJECT (display->device_manager));
+ }
G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
}
diff --git a/gdk/x11/gdkdevicemanager-x11.c b/gdk/x11/gdkdevicemanager-x11.c
index 335764b..e1cefaa 100644
--- a/gdk/x11/gdkdevicemanager-x11.c
+++ b/gdk/x11/gdkdevicemanager-x11.c
@@ -53,6 +53,8 @@ _gdk_device_manager_new (GdkDisplay *display)
{
GdkDeviceManagerXI2 *device_manager_xi2;
+ GDK_NOTE (INPUT, g_print ("Creating XI2 device manager\n"));
+
device_manager_xi2 = g_object_new (GDK_TYPE_DEVICE_MANAGER_XI2,
"display", display,
NULL);
@@ -62,14 +64,20 @@ _gdk_device_manager_new (GdkDisplay *display)
}
else
#endif /* XINPUT_2 */
- return g_object_new (GDK_TYPE_DEVICE_MANAGER_XI,
- "display", display,
- "event-base", firstevent,
- NULL);
+ {
+ GDK_NOTE (INPUT, g_print ("Creating XI device manager\n"));
+
+ return g_object_new (GDK_TYPE_DEVICE_MANAGER_XI,
+ "display", display,
+ "event-base", firstevent,
+ NULL);
+ }
}
#endif /* XINPUT_2 || XINPUT_XFREE */
}
+ GDK_NOTE (INPUT, g_print ("Creating core device manager\n"));
+
return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
"display", display,
NULL);
diff --git a/gdk/x11/gdkdevicemanager-xi.c b/gdk/x11/gdkdevicemanager-xi.c
index e11cb58..7229b58 100644
--- a/gdk/x11/gdkdevicemanager-xi.c
+++ b/gdk/x11/gdkdevicemanager-xi.c
@@ -37,7 +37,7 @@ struct _GdkDeviceManagerXIPrivate
};
static void gdk_device_manager_xi_constructed (GObject *object);
-static void gdk_device_manager_xi_finalize (GObject *object);
+static void gdk_device_manager_xi_dispose (GObject *object);
static void gdk_device_manager_xi_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -72,7 +72,7 @@ gdk_device_manager_xi_class_init (GdkDeviceManagerXIClass *klass)
GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
object_class->constructed = gdk_device_manager_xi_constructed;
- object_class->finalize = gdk_device_manager_xi_finalize;
+ object_class->dispose = gdk_device_manager_xi_dispose;
object_class->set_property = gdk_device_manager_xi_set_property;
object_class->get_property = gdk_device_manager_xi_get_property;
@@ -279,7 +279,7 @@ gdk_device_manager_xi_constructed (GObject *object)
priv->devices = g_list_prepend (priv->devices, device);
g_hash_table_insert (priv->id_table,
GINT_TO_POINTER (devices[i].id),
- device);
+ g_object_ref (device));
}
}
@@ -294,7 +294,7 @@ gdk_device_manager_xi_constructed (GObject *object)
}
static void
-gdk_device_manager_xi_finalize (GObject *object)
+gdk_device_manager_xi_dispose (GObject *object)
{
GdkDeviceManagerXIPrivate *priv;
@@ -302,12 +302,17 @@ gdk_device_manager_xi_finalize (GObject *object)
g_list_foreach (priv->devices, (GFunc) g_object_unref, NULL);
g_list_free (priv->devices);
+ priv->devices = NULL;
- g_hash_table_destroy (priv->id_table);
+ if (priv->id_table != NULL)
+ {
+ g_hash_table_destroy (priv->id_table);
+ priv->id_table = NULL;
+ }
gdk_window_remove_filter (NULL, window_input_info_filter, object);
- G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->finalize (object);
+ G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->dispose (object);
}
static void
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 36ae37e..51002c7 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -33,7 +33,7 @@
static void gdk_device_manager_xi2_constructed (GObject *object);
-static void gdk_device_manager_xi2_finalize (GObject *object);
+static void gdk_device_manager_xi2_dispose (GObject *object);
static GList * gdk_device_manager_xi2_list_devices (GdkDeviceManager *device_manager,
GdkDeviceType type);
@@ -63,7 +63,7 @@ gdk_device_manager_xi2_class_init (GdkDeviceManagerXI2Class *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gdk_device_manager_xi2_constructed;
- object_class->finalize = gdk_device_manager_xi2_finalize;
+ object_class->dispose = gdk_device_manager_xi2_dispose;
device_manager_class->list_devices = gdk_device_manager_xi2_list_devices;
device_manager_class->get_client_pointer = gdk_device_manager_xi2_get_client_pointer;
@@ -258,7 +258,7 @@ add_device (GdkDeviceManagerXI2 *device_manager,
g_hash_table_replace (device_manager->id_table,
GINT_TO_POINTER (dev->deviceid),
- device);
+ g_object_ref (device));
if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
device_manager->master_devices = g_list_append (device_manager->master_devices, device);
@@ -373,7 +373,7 @@ gdk_device_manager_xi2_constructed (GObject *object)
}
static void
-gdk_device_manager_xi2_finalize (GObject *object)
+gdk_device_manager_xi2_dispose (GObject *object)
{
GdkDeviceManagerXI2 *device_manager_xi2;
@@ -381,16 +381,23 @@ gdk_device_manager_xi2_finalize (GObject *object)
g_list_foreach (device_manager_xi2->master_devices, (GFunc) g_object_unref, NULL);
g_list_free (device_manager_xi2->master_devices);
+ device_manager_xi2->master_devices = NULL;
g_list_foreach (device_manager_xi2->slave_devices, (GFunc) g_object_unref, NULL);
g_list_free (device_manager_xi2->slave_devices);
+ device_manager_xi2->slave_devices = NULL;
g_list_foreach (device_manager_xi2->floating_devices, (GFunc) g_object_unref, NULL);
g_list_free (device_manager_xi2->floating_devices);
+ device_manager_xi2->floating_devices = NULL;
- g_hash_table_destroy (device_manager_xi2->id_table);
+ if (device_manager_xi2->id_table)
+ {
+ g_hash_table_destroy (device_manager_xi2->id_table);
+ device_manager_xi2->id_table = NULL;
+ }
- G_OBJECT_CLASS (gdk_device_manager_xi2_parent_class)->finalize (object);
+ G_OBJECT_CLASS (gdk_device_manager_xi2_parent_class)->dispose (object);
}
static GList *
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 9ad4178..ea4e991 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1154,7 +1154,8 @@ _gdk_input_init (GdkDisplay *display)
if (device->source == GDK_SOURCE_KEYBOARD)
continue;
- display_x11->input_devices = g_list_prepend (display_x11->input_devices, l->data);
+ display_x11->input_devices = g_list_prepend (display_x11->input_devices,
+ g_object_ref (l->data));
}
g_list_free (list);
@@ -1176,7 +1177,8 @@ _gdk_input_init (GdkDisplay *display)
}
/* Add the core pointer to the devices list */
- display_x11->input_devices = g_list_prepend (display_x11->input_devices, display->core_pointer);
+ display_x11->input_devices = g_list_prepend (display_x11->input_devices,
+ g_object_ref (display->core_pointer));
g_list_free (list);
}
@@ -1449,8 +1451,7 @@ gdk_display_open (const gchar *display_name)
_gdk_x11_screen_setup (display_x11->screens[i]);
g_signal_emit_by_name (display, "opened");
- g_signal_emit_by_name (gdk_display_manager_get(),
- "display_opened", display);
+ g_signal_emit_by_name (gdk_display_manager_get (), "display-opened", display);
return display;
}
diff --git a/gdk/x11/gdkeventsource.c b/gdk/x11/gdkeventsource.c
index d230488..9521b9d 100644
--- a/gdk/x11/gdkeventsource.c
+++ b/gdk/x11/gdkeventsource.c
@@ -312,6 +312,11 @@ gdk_event_source_dispatch (GSource *source,
static void
gdk_event_source_finalize (GSource *source)
{
+ GdkEventSource *event_source = (GdkEventSource *)source;
+
+ g_list_free (event_source->translators);
+ event_source->translators = NULL;
+
event_sources = g_list_remove (event_sources, source);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]