[tracker-miners/wip/carlosg/test-error-fixes: 4/5] libtracker-miner: Fix possible double DELETED emission on directories




commit 2db1b30e1f8c05b71df4b12ab3a49188a80a8b71
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Jul 13 11:36:41 2021 +0200

    libtracker-miner: Fix possible double DELETED emission on directories
    
    We may receive DELETED events in directories from 2 directory monitors:
    - The directory monitor for this directory itself (via IN_DELETE_SELF)
    - The directory monitor of the parent directory (via regular IN_DELETE
      on a child).
    
    We typically will get the parent directory event first, cancel the
    directory monitor for the deleted directory, and this way avoid receiving
    the second event.
    
    Less typically, we would receive the event from the directory itself
    first, cancel that file monitor, but still receive the second DELETED
    event from the parent folder (which was not cancelled). In these cases,
    we'd usually still coalesce the events anyway, since the DELETED event
    emission does not happen immediately (and the DELETED event would drop
    the cached events).
    
    But, in even stranger situations (I presume load related, since this
    has just been seen in CI an build machines), these 2 DELETED events
    happen separately enough that the monitor thread already let the first
    DELETED event entirely through, so no coalescing happens, and we actually
    emit DELETED on the folder twice. This caused test failures in
    tracker-file-notifier-test.
    
    To fix this, check explicitly on DELETED events the folder's directory
    monitor and whether it's already cancelled, before maybe emitting a
    second event. This still does account for the cases where there is only
    one directory monitor on the file (e.g. parent is monitored, but we run
    out of monitors with the directory itself).
    
    Fixes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/174

 src/libtracker-miner/tracker-monitor.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
---
diff --git a/src/libtracker-miner/tracker-monitor.c b/src/libtracker-miner/tracker-monitor.c
index aca697cb7..81d17003c 100644
--- a/src/libtracker-miner/tracker-monitor.c
+++ b/src/libtracker-miner/tracker-monitor.c
@@ -928,6 +928,30 @@ monitor_event_cb (GFileMonitor      *file_monitor,
                                         monitor_event_to_string (event_type),
                                         is_directory ? "directory" : "file",
                                         file_uri));
+
+               if (is_directory &&
+                   event_type == G_FILE_MONITOR_EVENT_DELETED) {
+                       GFileMonitor *dir_monitor;
+
+                       dir_monitor = g_hash_table_lookup (priv->thread.monitors, file);
+
+                       /* We may get 2 DELETED events on directories, one from the
+                        * directory monitor for the directory itself, and again from
+                        * the parent folder.
+                        *
+                        * If the parent event is handled first, we cancel the monitor
+                        * so the second event does not get to us. However if the
+                        * order is inverted, just cancelling the directory monitor
+                        * for the deleted directory will not stop the parent directory
+                        * event. We must check explicitly for that case.
+                        */
+                       if (dir_monitor &&
+                           dir_monitor != file_monitor &&
+                           g_file_monitor_is_cancelled (dir_monitor)) {
+                               g_free (file_uri);
+                               return;
+                       }
+               }
        } else {
                if (event_type == G_FILE_MONITOR_EVENT_RENAMED ||
                    event_type == G_FILE_MONITOR_EVENT_MOVED_OUT) {


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