From 3fca06e8b1037f117ba57b5e824ea59a343b44ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Wed, 12 Oct 2022 08:23:58 +0200 Subject: [PATCH] Disconnect monitors in `dnf_repo_loader_finalize()` (RhBug:2070153) This fixes a crash that could occur due to dangling monitors there we executed even when the `DnfRepoLoader` was already freed. https://bugzilla.redhat.com/show_bug.cgi?id=2070153 --- libdnf/dnf-repo-loader.cpp | 73 +++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/libdnf/dnf-repo-loader.cpp b/libdnf/dnf-repo-loader.cpp index c6d4faaaf3..a686ee251e 100644 --- a/libdnf/dnf-repo-loader.cpp +++ b/libdnf/dnf-repo-loader.cpp @@ -61,25 +61,6 @@ static guint signals[SIGNAL_LAST] = { 0 }; G_DEFINE_TYPE_WITH_PRIVATE(DnfRepoLoader, dnf_repo_loader, G_TYPE_OBJECT) #define GET_PRIVATE(o) (static_cast(dnf_repo_loader_get_instance_private (o))) -/** - * dnf_repo_loader_finalize: - **/ -static void -dnf_repo_loader_finalize(GObject *object) -{ - DnfRepoLoader *self = DNF_REPO_LOADER(object); - DnfRepoLoaderPrivate *priv = GET_PRIVATE(self); - - if (priv->context != NULL) - g_object_remove_weak_pointer(G_OBJECT(priv->context), - (void **) &priv->context); - g_ptr_array_unref(priv->monitor_repos); - g_object_unref(priv->volume_monitor); - g_ptr_array_unref(priv->repos); - - G_OBJECT_CLASS(dnf_repo_loader_parent_class)->finalize(object); -} - /** * dnf_repo_loader_invalidate: */ @@ -104,6 +85,46 @@ dnf_repo_loader_mount_changed_cb(GVolumeMonitor *vm, GMount *mount, DnfRepoLoade dnf_repo_loader_invalidate(self); } +/** + * dnf_repo_loader_directory_changed_cb: + **/ +static void +dnf_repo_loader_directory_changed_cb(GFileMonitor *monitor_, + GFile *file, GFile *other_file, + GFileMonitorEvent event_type, + DnfRepoLoader *self) +{ + g_debug("emit changed(ReposDir changed)"); + g_signal_emit(self, signals[SIGNAL_CHANGED], 0); + dnf_repo_loader_invalidate(self); +} + +/** + * dnf_repo_loader_finalize: + **/ +static void +dnf_repo_loader_finalize(GObject *object) +{ + DnfRepoLoader *self = DNF_REPO_LOADER(object); + DnfRepoLoaderPrivate *priv = GET_PRIVATE(self); + + if (priv->context != NULL) + g_object_remove_weak_pointer(G_OBJECT(priv->context), + (void **) &priv->context); + guint i; + for (i = 0; i < priv->monitor_repos->len; i++) { + auto repo_file_monitor = static_cast(g_ptr_array_index(priv->monitor_repos, i)); + g_signal_handlers_disconnect_by_func(repo_file_monitor, (gpointer) dnf_repo_loader_directory_changed_cb, self); + } + g_ptr_array_unref(priv->monitor_repos); + + g_signal_handlers_disconnect_by_func(priv->volume_monitor, (gpointer) dnf_repo_loader_mount_changed_cb, self); + g_object_unref(priv->volume_monitor); + g_ptr_array_unref(priv->repos); + + G_OBJECT_CLASS(dnf_repo_loader_parent_class)->finalize(object); +} + /** * dnf_repo_loader_init: **/ @@ -525,20 +546,6 @@ dnf_repo_loader_get_repo_by_id(DnfRepoLoader *self, const gchar *id, GError **er return NULL; } CATCH_TO_GERROR(NULL) -/** - * dnf_repo_loader_directory_changed_cb: - **/ -static void -dnf_repo_loader_directory_changed_cb(GFileMonitor *monitor_, - GFile *file, GFile *other_file, - GFileMonitorEvent event_type, - DnfRepoLoader *self) -{ - g_debug("emit changed(ReposDir changed)"); - g_signal_emit(self, signals[SIGNAL_CHANGED], 0); - dnf_repo_loader_invalidate(self); -} - /** * dnf_repo_loader_setup_monitor: */