[tracker-miners/wip/carlosg/cancel-fixes] libtracker-miner: Fix TrackerFileNotifier cancellation paths




commit 32a15b9df15ba042ca35f8408c3b138ad2f2adc2
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Jun 18 13:54:16 2022 +0200

    libtracker-miner: Fix TrackerFileNotifier cancellation paths
    
    Currently, the code paths handling cancellation of a TrackerCrawler async
    request attempt to still emit ::directory-finished and update stats. However
    this causes invalid memory accesses on finalization paths, since the
    TrackerFileNotifier has been already disposed at the time the async callback
    is handled. This may result in crashes.
    
    To fix this, avoid all TrackerFileNotifier manipulation in the cancellation
    paths of the async callback, the callback is meant to execute and bail out
    cleanly now in these situations. This makes it a responsibility of the
    g_cancellable_cancel() caller to instruct the TrackerFileNotifier how to
    proceed.
    
    Other callers, like the paths handling unmount and deletion of the folder
    being crawled, have also been updated to ensure TrackerFileNotifier
    resumes operation correctly after those situations.
    
    Fixes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/223

 src/libtracker-miner/tracker-file-notifier.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-file-notifier.c b/src/libtracker-miner/tracker-file-notifier.c
index d3664e74a..2ad4e23e2 100644
--- a/src/libtracker-miner/tracker-file-notifier.c
+++ b/src/libtracker-miner/tracker-file-notifier.c
@@ -505,10 +505,9 @@ crawler_get_cb (TrackerCrawler *crawler,
                                   uri, error->message);
                        g_free (uri);
                }
-               tracker_monitor_remove (priv->monitor, directory);
 
-               if (interrupted || !crawl_directory_in_current_root (notifier))
-                       finish_current_directory (notifier, interrupted);
+               if (!interrupted && !crawl_directory_in_current_root (notifier))
+                       finish_current_directory (notifier, FALSE);
 
                g_clear_error (&error);
                return;
@@ -675,10 +674,8 @@ file_notifier_current_root_check_remove_directory (TrackerFileNotifier *notifier
            root_data_remove_directory (priv->current_index_root, file)) {
                g_cancellable_cancel (priv->cancellable);
 
-               if (!crawl_directory_in_current_root (notifier)) {
-                       g_clear_pointer (&priv->current_index_root, root_data_free);
-                       notifier_check_next_root (notifier);
-               }
+               if (!crawl_directory_in_current_root (notifier))
+                       finish_current_directory (notifier, FALSE);
        }
 }
 
@@ -1360,10 +1357,7 @@ indexing_tree_directory_removed (TrackerIndexingTree *indexing_tree,
            g_file_equal (directory, priv->current_index_root->root)) {
                /* Directory being currently processed */
                g_cancellable_cancel (priv->cancellable);
-
-               /* If the crawler was already stopped (eg. we're at the querying
-                * phase), the current index root won't be cleared.
-                */
+               finish_current_directory (notifier, TRUE);
                g_clear_pointer (&priv->current_index_root, root_data_free);
                notifier_check_next_root (notifier);
        }
@@ -1792,7 +1786,6 @@ tracker_file_notifier_stop (TrackerFileNotifier *notifier)
        priv = tracker_file_notifier_get_instance_private (notifier);
 
        if (!priv->stopped) {
-               g_clear_pointer (&priv->current_index_root, root_data_free);
                g_cancellable_cancel (priv->cancellable);
                priv->stopped = TRUE;
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]