diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-10-13 14:02:32 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-10-13 16:32:31 +0300 |
commit | 4a59a66d1f7b569313396f0b63127796987f1ca6 (patch) | |
tree | 873b63e37b321855e8a37a0888fca3d4ea82e86b /src | |
parent | 33a16ae04270647e99dc0741b706061e6468fa3c (diff) | |
download | sciteco-4a59a66d1f7b569313396f0b63127796987f1ca6.tar.gz |
GTK: fixed teco_view_free() (hopefully)
* The old implementation could apparently result in use-after-free
situations that are not related to unstopped watchers in Scintilla.
This would result in frequent crashes.
Possibly, this only now manifests after upgrading to Scintilla 5.
* The old implementation also had the bug that freeing views
(e.g. via <EF>) would not release any memory in batch mode since the
main loop is not triggered.
* I don't pretend to understand why we need gtk_widget_destroy()
instead of g_object_unref().
Diffstat (limited to 'src')
-rw-r--r-- | src/interface-gtk/interface.c | 27 |
1 files changed, 7 insertions, 20 deletions
diff --git a/src/interface-gtk/interface.c b/src/interface-gtk/interface.c index 27c043c..ea9745a 100644 --- a/src/interface-gtk/interface.c +++ b/src/interface-gtk/interface.c @@ -146,31 +146,18 @@ teco_view_ssm(teco_view_t *ctx, unsigned int iMessage, uptr_t wParam, sptr_t lPa return scintilla_send_message(SCINTILLA(ctx), iMessage, wParam, lParam); } -static gboolean -teco_view_free_idle_cb(gpointer user_data) -{ - /* - * This does NOT destroy the Scintilla object - * and GTK widget, if it is the current view - * (and therefore added to the vbox). - */ - g_object_unref(user_data); - return G_SOURCE_REMOVE; -} - void teco_view_free(teco_view_t *ctx) { /* - * FIXME: The widget is unreffed only in an idle watcher because - * Scintilla may have idle callbacks activated (see ScintillaGTK.cxx) - * and we must prevent use-after-frees. - * A simple g_idle_remove_by_data() does not suffice for some strange reason - * (perhaps it does not prevent the invocation of already activated watchers). - * This is a bug should better be fixed by reference counting in - * ScintillaGTK.cxx itself. + * FIXME: It's not entirely clear why g_object_unref() won't do here. + * This results in crashes later on because something is still referencing + * the widget/GObject. + * However, currently displayed views (ctx == teco_interface.current_view_widget) + * should have a reference count of 2 and unreffing them should not actually + * touch the object until is is removed from the view. */ - g_idle_add_full(G_PRIORITY_LOW, teco_view_free_idle_cb, SCINTILLA(ctx), NULL); + gtk_widget_destroy(teco_view_get_widget(ctx)); } static struct { |