[tracker-miners/wip/carlosg/fix-monitor-race-condition: 1/2] libtracker-miner: Refactor TrackerMonitor event tracking
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker-miners/wip/carlosg/fix-monitor-race-condition: 1/2] libtracker-miner: Refactor TrackerMonitor event tracking
- Date: Sat, 1 Aug 2020 12:20:37 +0000 (UTC)
commit 9ef12ee9f314340bc18dce598be8f77c47e24946
Author: Carlos Garnacho <carlosg gnome org>
Date: Sat Aug 1 14:06:46 2020 +0200
libtracker-miner: Refactor TrackerMonitor event tracking
Make it cache more information about the individual events, this
will be useful for events that we don't flush while handling events
(eg. a timeout instead of CHANGES_DONE_HINT).
src/libtracker-miner/tracker-monitor.c | 72 +++++++++++++++++++++-------------
1 file changed, 44 insertions(+), 28 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-monitor.c b/src/libtracker-miner/tracker-monitor.c
index cf5d6c7c1..2aa495c6f 100644
--- a/src/libtracker-miner/tracker-monitor.c
+++ b/src/libtracker-miner/tracker-monitor.c
@@ -34,9 +34,6 @@
#include "libtracker-miners-common/tracker-debug.h"
-/* The life time of an item in the cache */
-#define CACHE_LIFETIME_SECONDS 1
-
typedef struct TrackerMonitorPrivate TrackerMonitorPrivate;
struct TrackerMonitorPrivate {
@@ -68,6 +65,13 @@ typedef struct {
gboolean expirable;
} EventData;
+typedef struct {
+ TrackerMonitor *monitor;
+ GFile *file;
+ gboolean is_directory;
+ GFileMonitorEvent event_type;
+} CachedEvent;
+
enum {
ITEM_CREATED,
ITEM_UPDATED,
@@ -188,6 +192,13 @@ tracker_monitor_class_init (TrackerMonitorClass *klass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
}
+static void
+cached_event_free (CachedEvent *event)
+{
+ g_object_unref (event->file);
+ g_free (event);
+}
+
static void
tracker_monitor_init (TrackerMonitor *object)
{
@@ -212,7 +223,7 @@ tracker_monitor_init (TrackerMonitor *object)
g_hash_table_new_full (g_file_hash,
(GEqualFunc) g_file_equal,
g_object_unref,
- NULL);
+ (GDestroyNotify) cached_event_free);
/* For the first monitor we get the type and find out if we
* are using inotify, FAM, polling, etc.
@@ -611,41 +622,46 @@ emit_signal_for_event (TrackerMonitor *monitor,
}
static void
-flush_cached_event (TrackerMonitor *monitor,
- GFile *file,
- gboolean is_directory)
+flush_event_now (TrackerMonitor *monitor,
+ GFile *file)
{
- gpointer value = NULL;
TrackerMonitorPrivate *priv;
+ CachedEvent *event;
priv = tracker_monitor_get_instance_private (monitor);
- if (g_hash_table_lookup_extended (priv->cached_events,
- file, NULL, &value)) {
- GFileMonitorEvent prev_event_type = GPOINTER_TO_UINT (value);
+ event = g_hash_table_lookup (priv->cached_events, file);
+ if (event) {
+ emit_signal_for_event (monitor, event->event_type,
+ event->is_directory, event->file, NULL);
g_hash_table_remove (priv->cached_events, file);
- emit_signal_for_event (monitor, prev_event_type,
- is_directory, file, NULL);
}
}
static void
cache_event (TrackerMonitor *monitor,
GFile *file,
- GFileMonitorEvent event_type)
+ GFileMonitorEvent event_type,
+ gboolean is_directory)
{
TrackerMonitorPrivate *priv;
+ CachedEvent *event;
priv = tracker_monitor_get_instance_private (monitor);
-
- if (g_hash_table_lookup_extended (priv->cached_events, file,
- NULL, NULL))
- return;
-
- g_hash_table_insert (priv->cached_events,
- g_object_ref (file),
- GUINT_TO_POINTER (event_type));
+ event = g_hash_table_lookup (priv->cached_events, file);
+
+ if (!event) {
+ event = g_new0 (CachedEvent, 1);
+ event->monitor = monitor;
+ event->file = g_object_ref (file);
+ event->event_type = event_type;
+ event->is_directory = is_directory;
+
+ g_hash_table_insert (priv->cached_events,
+ g_object_ref (file),
+ event);
+ }
}
static void
@@ -660,10 +676,11 @@ monitor_event_cb (GFileMonitor *file_monitor,
gchar *other_file_uri;
gboolean is_directory = FALSE;
TrackerMonitorPrivate *priv;
- gpointer value;
+ CachedEvent *prev_event;
monitor = user_data;
priv = tracker_monitor_get_instance_private (monitor);
+ prev_event = g_hash_table_lookup (priv->cached_events, file);
if (G_UNLIKELY (!priv->enabled)) {
TRACKER_NOTE (MONITORS, g_message ("Silently dropping monitor event, monitor disabled for
now"));
@@ -704,16 +721,15 @@ monitor_event_cb (GFileMonitor *file_monitor,
case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_CHANGED:
if (!priv->use_changed_event) {
- cache_event (monitor, file, event_type);
+ cache_event (monitor, file, event_type, is_directory);
} else {
emit_signal_for_event (monitor, event_type,
is_directory, file, NULL);
}
break;
case G_FILE_MONITOR_EVENT_DELETED:
- if (g_hash_table_lookup_extended (priv->cached_events,
- file, NULL, &value) &&
- GPOINTER_TO_UINT (value) == G_FILE_MONITOR_EVENT_CREATED) {
+ if (prev_event &&
+ prev_event->event_type == G_FILE_MONITOR_EVENT_CREATED) {
/* Consume both the cached CREATED event and this one */
g_hash_table_remove (priv->cached_events, file);
break;
@@ -728,7 +744,7 @@ monitor_event_cb (GFileMonitor *file_monitor,
is_directory, file, NULL);
break;
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
- flush_cached_event (monitor, file, is_directory);
+ flush_event_now (monitor, file);
break;
case G_FILE_MONITOR_EVENT_MOVED_IN:
if (other_file) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]