aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2016-02-04 06:42:43 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2016-02-04 06:47:28 +0100
commit436e10fae5cdc42ad932ccdcf194418bf3d96108 (patch)
treef3b6edf5e8a29b4817330b60573078b3212c7b0e /src
parentd4bfd54a8811c27e67e5a0032d3836ff801c81e8 (diff)
downloadsciteco-436e10fae5cdc42ad932ccdcf194418bf3d96108.tar.gz
Gtk UI: fixed segfaults because of unsynchronized ViewGtk destruction
* this was worked around by using an idle watcher which can be registered thread-safe. * this workaround can be reverted once we're single-threaded again.
Diffstat (limited to 'src')
-rw-r--r--src/interface-gtk/interface-gtk.cpp27
-rw-r--r--src/interface-gtk/interface-gtk.h11
2 files changed, 26 insertions, 12 deletions
diff --git a/src/interface-gtk/interface-gtk.cpp b/src/interface-gtk/interface-gtk.cpp
index ca14f2f..9da7454 100644
--- a/src/interface-gtk/interface-gtk.cpp
+++ b/src/interface-gtk/interface-gtk.cpp
@@ -83,6 +83,13 @@ static gboolean window_delete_cb(GtkWidget *w, GdkEventAny *e,
static gboolean sigterm_handler(gpointer user_data) G_GNUC_UNUSED;
+static gboolean
+g_object_unref_idle_cb(gpointer user_data)
+{
+ g_object_unref(user_data);
+ return G_SOURCE_REMOVE;
+}
+
} /* extern "C" */
#define UNNAMED_FILE "(Unnamed)"
@@ -116,7 +123,7 @@ ViewGtk::initialize_impl(void)
* We don't want the object to be destroyed
* when it is removed from the vbox.
*/
- g_object_ref_sink(G_OBJECT(sci));
+ g_object_ref_sink(sci);
scintilla_set_id(sci, 0);
@@ -137,7 +144,7 @@ ViewGtk::initialize_impl(void)
events &= ~(GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
gtk_widget_set_events(get_widget(), events);
- g_signal_connect(G_OBJECT(sci), SCINTILLA_NOTIFY,
+ g_signal_connect(sci, SCINTILLA_NOTIFY,
G_CALLBACK(scintilla_notify), NULL);
/*
@@ -149,6 +156,22 @@ ViewGtk::initialize_impl(void)
setup();
}
+ViewGtk::~ViewGtk()
+{
+ /*
+ * This does NOT destroy the Scintilla object
+ * and GTK widget, if it is the current view
+ * (and therefore added to the vbox).
+ * FIXME: This only uses an idle watcher
+ * because the destructor can be called with
+ * the Gdk lock held and without.
+ * Once the threading model is revised this
+ * can be simplified and inlined again.
+ */
+ if (sci)
+ gdk_threads_add_idle(g_object_unref_idle_cb, sci);
+}
+
GOptionGroup *
InterfaceGtk::get_options(void)
{
diff --git a/src/interface-gtk/interface-gtk.h b/src/interface-gtk/interface-gtk.h
index 7762ee4..8bd189d 100644
--- a/src/interface-gtk/interface-gtk.h
+++ b/src/interface-gtk/interface-gtk.h
@@ -43,16 +43,7 @@ public:
/* implementation of View::initialize() */
void initialize_impl(void);
- inline ~ViewGtk()
- {
- /*
- * This does NOT destroy the Scintilla object
- * and GTK widget, if it is the current view
- * (and therefore added to the vbox).
- */
- if (sci)
- g_object_unref(G_OBJECT(sci));
- }
+ ~ViewGtk();
inline GtkWidget *
get_widget(void)