diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2016-02-04 06:42:43 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2016-02-04 06:47:28 +0100 |
commit | 436e10fae5cdc42ad932ccdcf194418bf3d96108 (patch) | |
tree | f3b6edf5e8a29b4817330b60573078b3212c7b0e /src | |
parent | d4bfd54a8811c27e67e5a0032d3836ff801c81e8 (diff) | |
download | sciteco-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.cpp | 27 | ||||
-rw-r--r-- | src/interface-gtk/interface-gtk.h | 11 |
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) |