[nautilus/wip/ernestask/tasks: 2/17] Add task manager class



commit 4fde0e1f4acd0f1c132184b2e7120ebb68189f8f
Author: Ernestas Kulik <ernestask gnome org>
Date:   Thu May 11 16:29:20 2017 +0300

    Add task manager class

 data/org.gnome.nautilus.gschema.xml |   10 +++
 src/meson.build                     |    2 +
 src/nautilus-global-preferences.h   |    2 +
 src/nautilus-task-manager.c         |  147 +++++++++++++++++++++++++++++++++++
 src/nautilus-task-manager.h         |   19 +++++
 5 files changed, 180 insertions(+), 0 deletions(-)
---
diff --git a/data/org.gnome.nautilus.gschema.xml b/data/org.gnome.nautilus.gschema.xml
index f093c3c..979ae5c 100644
--- a/data/org.gnome.nautilus.gschema.xml
+++ b/data/org.gnome.nautilus.gschema.xml
@@ -222,6 +222,16 @@
       <summary>Whether to have full text search enabled by default when opening a new window/tab</summary>
       <description>If set to true, then Nautilus will also match the file contents besides the name. This 
toggles the default active state, which can still be overriden in the search popover</description>
     </key>
+    <key type="i" name="task-limit">
+      <range min="0" max="64"/>
+      <default>16</default>
+      <summary>
+        Active concurrent task limit
+      </summary>
+      <description>
+        Limits the maximum number of tasks that can be running at any moment.
+      </description>
+    </key>
   </schema>
 
   <schema path="/org/gnome/nautilus/compression/" id="org.gnome.nautilus.compression" 
gettext-domain="nautilus">
diff --git a/src/meson.build b/src/meson.build
index 5f4b22b..9c31ffd 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -258,6 +258,8 @@ libnautilus_sources = [
     'nautilus-file-undo-manager.h',
     'nautilus-task.c',
     'nautilus-task.h',
+    'nautilus-task-manager.c',
+    'nautilus-task-manager.h'
 ]
 
 if get_option ('enable-tracker')
diff --git a/src/nautilus-global-preferences.h b/src/nautilus-global-preferences.h
index f508f7d..8e50282 100644
--- a/src/nautilus-global-preferences.h
+++ b/src/nautilus-global-preferences.h
@@ -180,6 +180,8 @@ typedef enum
 /* Full Text Search as default */
 #define NAUTILUS_PREFERENCES_FTS_DEFAULT "fts-default"
 
+#define NAUTILUS_PREFERENCES_TASK_LIMIT "task-limit"
+
 void nautilus_global_preferences_init                      (void);
 
 extern GSettings *nautilus_preferences;
diff --git a/src/nautilus-task-manager.c b/src/nautilus-task-manager.c
new file mode 100644
index 0000000..890de0e
--- /dev/null
+++ b/src/nautilus-task-manager.c
@@ -0,0 +1,147 @@
+#include "nautilus-task-manager.h"
+
+#include "nautilus-global-preferences.h"
+
+struct _NautilusTaskManager
+{
+    GObject parent_instance;
+
+    gint task_limit;
+    GThreadPool *thread_pool;
+};
+
+G_DEFINE_TYPE (NautilusTaskManager, nautilus_task_manager, G_TYPE_OBJECT)
+
+enum
+{
+    QUEUED,
+    LAST_SIGNAL
+};
+
+static NautilusTaskManager *instance = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GObject *
+constructor (GType                  type,
+             guint                  n_construct_properties,
+             GObjectConstructParam *construct_properties)
+{
+    static GMutex mutex;
+    GObjectClass *parent_class;
+
+    g_mutex_lock (&mutex);
+
+    if (instance != NULL)
+    {
+        g_mutex_unlock (&mutex);
+        return g_object_ref (instance);
+    }
+
+    parent_class = G_OBJECT_CLASS (nautilus_task_manager_parent_class);
+    instance = NAUTILUS_TASK_MANAGER (parent_class->constructor (type,
+                                                                 n_construct_properties,
+                                                                 construct_properties));
+
+    g_object_add_weak_pointer (G_OBJECT (instance), (gpointer *) &instance);
+
+    g_mutex_unlock (&mutex);
+
+    return G_OBJECT (instance);
+}
+
+static void
+finalize (GObject *object)
+{
+    NautilusTaskManager *self;
+
+    self = NAUTILUS_TASK_MANAGER (object);
+
+    g_thread_pool_free (self->thread_pool, TRUE, TRUE);
+}
+
+static void
+nautilus_task_manager_class_init (NautilusTaskManagerClass *klass)
+{
+    GObjectClass *object_class;
+
+    object_class = G_OBJECT_CLASS (klass);
+
+    object_class->constructor = constructor;
+    object_class->finalize = finalize;
+
+    signals[QUEUED] = g_signal_new ("queued",
+                                    NAUTILUS_TYPE_TASK_MANAGER,
+                                    0, 0, NULL, NULL,
+                                    g_cclosure_marshal_VOID__OBJECT,
+                                    G_TYPE_NONE,
+                                    1,
+                                    G_TYPE_OBJECT);
+}
+
+static void
+on_task_limit_changed (GSettings *settings,
+                       gchar     *key,
+                       gpointer   user_data)
+{
+    NautilusTaskManager *self;
+    gint task_limit;
+
+    self = NAUTILUS_TASK_MANAGER (user_data);
+    task_limit = g_settings_get_int (nautilus_preferences,
+                                     NAUTILUS_PREFERENCES_TASK_LIMIT);
+
+    if (task_limit == self->task_limit)
+    {
+        return;
+    }
+
+    self->task_limit = task_limit;
+
+    g_thread_pool_set_max_threads (self->thread_pool, self->task_limit, NULL);
+}
+
+static void
+execute_task (gpointer data,
+              gpointer user_data)
+{
+    g_autoptr (NautilusTask) task = NULL;
+
+    task = NAUTILUS_TASK (data);
+
+    nautilus_task_execute (task);
+}
+
+static void
+nautilus_task_manager_init (NautilusTaskManager *self)
+{
+    nautilus_global_preferences_init ();
+
+    self->task_limit = g_settings_get_int (nautilus_preferences,
+                                           NAUTILUS_PREFERENCES_TASK_LIMIT);
+    self->thread_pool = g_thread_pool_new (execute_task, self,
+                                           self->task_limit, FALSE,
+                                           NULL);
+
+    g_signal_connect (nautilus_preferences,
+                      "changed::" NAUTILUS_PREFERENCES_TASK_LIMIT,
+                      G_CALLBACK (on_task_limit_changed), self);
+}
+
+void
+nautilus_task_manager_queue_task (NautilusTaskManager  *self,
+                                  NautilusTask         *task)
+{
+    g_return_if_fail (NAUTILUS_IS_TASK_MANAGER (self));
+    g_return_if_fail (NAUTILUS_IS_TASK (task));
+
+    g_signal_emit (self, signals[QUEUED], 0, task);
+
+    g_thread_pool_push (self->thread_pool, g_object_ref (task), NULL);
+}
+
+NautilusTaskManager *
+nautilus_task_manager_dup_singleton (void)
+{
+    return g_object_new (NAUTILUS_TYPE_TASK_MANAGER, NULL);
+}
+
diff --git a/src/nautilus-task-manager.h b/src/nautilus-task-manager.h
new file mode 100644
index 0000000..c24674d
--- /dev/null
+++ b/src/nautilus-task-manager.h
@@ -0,0 +1,19 @@
+#ifndef NAUTILUS_TASK_MANAGER_H
+#define NAUTILUS_TASK_MANAGER_H
+
+#include "nautilus-task.h"
+
+#include <glib-object.h>
+
+#define NAUTILUS_TYPE_TASK_MANAGER (nautilus_task_manager_get_type ())
+
+G_DECLARE_FINAL_TYPE (NautilusTaskManager, nautilus_task_manager,
+                      NAUTILUS, TASK_MANAGER,
+                      GObject)
+
+void nautilus_task_manager_queue_task (NautilusTaskManager  *self,
+                                       NautilusTask         *task);
+
+NautilusTaskManager *nautilus_task_manager_dup_singleton (void);
+
+#endif


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