[tracker-miners/tracker-miners-2.3: 1/2] tracker-extract: Set a deadline of 30 seconds for extraction tasks



commit c6b8241cf98f8b5b31c9434563a9b5d69c09504a
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon May 4 12:58:36 2020 +0200

    tracker-extract: Set a deadline of 30 seconds for extraction tasks
    
    If we stick longer than that for a single file, it would seem there's
    some trouble processing it. As we're no longer guaranteed to stay in
    control of the extraction thread, just exit the process. As the file
    was being processed at the time of exiting, it would fall through the
    retry/ignore paths we have in place for extractor crashes.
    
    This timeout executes on the same thread/main context that called
    tracker_extract_file(). It is guaranteed to trigger since we offload
    extraction tasks to other threads.
    
    This makes tracker-extract resilient to possible infinite loops that
    might happen in 3rd party code via extractor modules.
    
    Fixes: https://gitlab.gnome.org/GNOME/tracker-miners/-/issues/107

 src/tracker-extract/tracker-extract.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
---
diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c
index d3e538cba..e2005de23 100644
--- a/src/tracker-extract/tracker-extract.c
+++ b/src/tracker-extract/tracker-extract.c
@@ -45,6 +45,8 @@
 
 G_DEFINE_QUARK (TrackerExtractError, tracker_extract_error)
 
+#define DEADLINE_SECONDS 30
+
 extern gboolean debug;
 
 typedef struct {
@@ -91,6 +93,7 @@ typedef struct {
        GModule *cur_module;
 
        guint signal_id;
+       guint timeout_id;
        guint success : 1;
 } TrackerExtractTask;
 
@@ -335,6 +338,19 @@ task_cancellable_cancelled_cb (GCancellable       *cancellable,
        g_mutex_unlock (&priv->task_mutex);
 }
 
+static gboolean
+task_deadline_cb (gpointer user_data)
+{
+       TrackerExtractTask *task = user_data;
+
+       g_warning ("File '%s' took too long to process. Shutting down everything",
+                  task->file);
+
+       if (task->cancellable)
+               g_cancellable_cancel (task->cancellable);
+       _exit (0);
+}
+
 static TrackerExtractTask *
 extract_task_new (TrackerExtract *extract,
                   const gchar    *uri,
@@ -380,6 +396,15 @@ extract_task_new (TrackerExtract *extract,
        task->mimetype = mimetype_used;
        task->extract = extract;
 
+       if (task->res) {
+               GSource *source;
+
+               source = g_timeout_source_new_seconds (DEADLINE_SECONDS);
+               g_source_set_callback (source, task_deadline_cb, task, NULL);
+               task->timeout_id =
+                       g_source_attach (source, g_task_get_context (G_TASK (task->res)));
+       }
+
        if (task->cancellable) {
                task->signal_id = g_cancellable_connect (cancellable,
                                                         G_CALLBACK (task_cancellable_cancelled_cb),
@@ -398,6 +423,9 @@ extract_task_free (TrackerExtractTask *task)
 
        notify_task_finish (task, task->success);
 
+       if (task->timeout_id)
+               g_source_remove (task->timeout_id);
+
        if (task->res) {
                g_object_unref (task->res);
        }


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