diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2012-06-12 12:28:36 +0100 |
---|---|---|
committer | Martyn Russell <martyn@lanedo.com> | 2012-07-05 17:02:55 +0100 |
commit | 5f00b825e3bc66e110f33d815b8659efb0af97f1 (patch) | |
tree | 62ce352a57466dc1e0b2b062f791a2077bb561fb | |
parent | 50fe7f57016f85929729ca395276e36cbfe384ed (diff) | |
download | tracker-5f00b825e3bc66e110f33d815b8659efb0af97f1.tar.gz |
libtracker-miner: Protect against infinite loops
When we defer processing on an item, set a counter in its qdata to
prevent the miner ever becoming stuck in an infinite loop.
Fixes GB#676435 and GB#674869
-rw-r--r-- | src/libtracker-miner/tracker-miner-fs.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c index eaa4e731a..54bd6175b 100644 --- a/src/libtracker-miner/tracker-miner-fs.c +++ b/src/libtracker-miner/tracker-miner-fs.c @@ -160,6 +160,7 @@ struct _TrackerMinerFSPrivate { GQuark quark_ignore_file; GQuark quark_attribute_updated; GQuark quark_directory_found_crawling; + GQuark quark_reentry_counter; GTimer *timer; GTimer *extraction_timer; @@ -602,6 +603,7 @@ tracker_miner_fs_init (TrackerMinerFS *object) priv->quark_ignore_file = g_quark_from_static_string ("tracker-ignore-file"); priv->quark_directory_found_crawling = g_quark_from_static_string ("tracker-directory-found-crawling"); priv->quark_attribute_updated = g_quark_from_static_string ("tracker-attribute-updated"); + priv->quark_reentry_counter = g_quark_from_static_string ("tracker-reentry-counter"); priv->mtime_checking = TRUE; priv->initial_crawling = TRUE; @@ -1771,6 +1773,40 @@ should_wait (TrackerMinerFS *fs, return FALSE; } +static void +item_reenqueue_full (TrackerMinerFS *fs, + TrackerPriorityQueue *item_queue, + GFile *queue_file, + gpointer queue_data, + gint priority) +{ + gint reentry_counter; + gchar *uri; + + reentry_counter = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (queue_file), + fs->priv->quark_reentry_counter)); + + if (reentry_counter < 2) { + g_object_set_qdata (G_OBJECT (queue_file), + fs->priv->quark_reentry_counter, + GINT_TO_POINTER (reentry_counter + 1)); + tracker_priority_queue_add (item_queue, queue_data, priority); + } else { + uri = g_file_get_uri (queue_file); + g_warning ("File '%s' has been reenqueued more than twice. It will not be indexed.", uri); + g_free (uri); + } +} + +static void +item_reenqueue (TrackerMinerFS *fs, + TrackerPriorityQueue *item_queue, + GFile *queue_file, + gint priority) +{ + item_reenqueue_full (fs, item_queue, queue_file, queue_file, priority); +} + static QueueState item_queue_get_next_file (TrackerMinerFS *fs, GFile **file, @@ -1835,8 +1871,8 @@ item_queue_get_next_file (TrackerMinerFS *fs, trace_eq_push_head ("DELETED", queue_file, "Should wait"); /* Need to postpone event... */ - tracker_priority_queue_add (fs->priv->items_deleted, - queue_file, priority - 1); + item_reenqueue (fs, fs->priv->items_deleted, queue_file, priority - 1); + return QUEUE_WAIT; } @@ -1888,8 +1924,8 @@ item_queue_get_next_file (TrackerMinerFS *fs, trace_eq_push_head ("CREATED", queue_file, "Should wait"); /* Need to postpone event... */ - tracker_priority_queue_add (fs->priv->items_created, - queue_file, priority - 1); + item_reenqueue (fs, fs->priv->items_created, queue_file, priority - 1); + return QUEUE_WAIT; } @@ -1927,8 +1963,8 @@ item_queue_get_next_file (TrackerMinerFS *fs, trace_eq_push_head ("UPDATED", queue_file, "Should wait"); /* Need to postpone event... */ - tracker_priority_queue_add (fs->priv->items_updated, - queue_file, priority - 1); + item_reenqueue (fs, fs->priv->items_updated, queue_file, priority - 1); + return QUEUE_WAIT; } @@ -1971,8 +2007,8 @@ item_queue_get_next_file (TrackerMinerFS *fs, trace_eq_push_head_2 ("MOVED", data->source_file, data->file, "Should wait"); /* Need to postpone event... */ - tracker_priority_queue_add (fs->priv->items_moved, - data, priority - 1); + item_reenqueue_full (fs, fs->priv->items_moved, data->file, data, priority - 1); + return QUEUE_WAIT; } @@ -2240,13 +2276,9 @@ item_queue_handlers_cb (gpointer user_data) * ensured, tasks are inserted at a higher priority so they * are processed promptly anyway. */ - tracker_priority_queue_add (item_queue, - g_object_ref (parent), - priority - 1); + item_reenqueue (fs, item_queue, g_object_ref (parent), priority - 1); + item_reenqueue (fs, item_queue, g_object_ref (file), priority); - tracker_priority_queue_add (item_queue, - g_object_ref (file), - priority); keep_processing = TRUE; } |