[tracker-miners/wip/carlosg/monitor-thread: 1/5] libtracker-miner: Make TrackerMonitor an initable




commit 2122d8a8635e0d6eddb71cc039bc9c5a245f3e1b
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Mar 6 20:27:07 2021 +0100

    libtracker-miner: Make TrackerMonitor an initable
    
    This object can produce initialization errors, so propagate them
    further instead of erroring out in place.

 src/libtracker-miner/tracker-file-notifier.c  |  36 +++--
 src/libtracker-miner/tracker-monitor.c        | 203 ++++++++++++++------------
 tests/libtracker-miner/tracker-monitor-test.c |   6 +
 3 files changed, 135 insertions(+), 110 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-file-notifier.c b/src/libtracker-miner/tracker-file-notifier.c
index b085da348..06e9a1c63 100644
--- a/src/libtracker-miner/tracker-file-notifier.c
+++ b/src/libtracker-miner/tracker-file-notifier.c
@@ -1670,6 +1670,7 @@ static void
 tracker_file_notifier_init (TrackerFileNotifier *notifier)
 {
        TrackerFileNotifierPrivate *priv;
+       GError *error = NULL;
 
        priv = tracker_file_notifier_get_instance_private (notifier);
        priv->timer = g_timer_new ();
@@ -1678,21 +1679,26 @@ tracker_file_notifier_init (TrackerFileNotifier *notifier)
        /* Set up monitor */
        priv->monitor = tracker_monitor_new ();
 
-       g_signal_connect (priv->monitor, "item-created",
-                         G_CALLBACK (monitor_item_created_cb),
-                         notifier);
-       g_signal_connect (priv->monitor, "item-updated",
-                         G_CALLBACK (monitor_item_updated_cb),
-                         notifier);
-       g_signal_connect (priv->monitor, "item-attribute-updated",
-                         G_CALLBACK (monitor_item_attribute_updated_cb),
-                         notifier);
-       g_signal_connect (priv->monitor, "item-deleted",
-                         G_CALLBACK (monitor_item_deleted_cb),
-                         notifier);
-       g_signal_connect (priv->monitor, "item-moved",
-                         G_CALLBACK (monitor_item_moved_cb),
-                         notifier);
+       if (!g_initable_init (G_INITABLE (priv->monitor), NULL, &error)) {
+               g_warning ("Could not init monitor: %s", error->message);
+               g_error_free (error);
+       } else {
+               g_signal_connect (priv->monitor, "item-created",
+                                 G_CALLBACK (monitor_item_created_cb),
+                                 notifier);
+               g_signal_connect (priv->monitor, "item-updated",
+                                 G_CALLBACK (monitor_item_updated_cb),
+                                 notifier);
+               g_signal_connect (priv->monitor, "item-attribute-updated",
+                                 G_CALLBACK (monitor_item_attribute_updated_cb),
+                                 notifier);
+               g_signal_connect (priv->monitor, "item-deleted",
+                                 G_CALLBACK (monitor_item_deleted_cb),
+                                 notifier);
+               g_signal_connect (priv->monitor, "item-moved",
+                                 G_CALLBACK (monitor_item_moved_cb),
+                                 notifier);
+       }
 
        g_queue_init (&priv->queue);
        priv->cache = g_hash_table_new_full (g_file_hash,
diff --git a/src/libtracker-miner/tracker-monitor.c b/src/libtracker-miner/tracker-monitor.c
index 65e722384..459008978 100644
--- a/src/libtracker-miner/tracker-monitor.c
+++ b/src/libtracker-miner/tracker-monitor.c
@@ -113,7 +113,114 @@ static gboolean       monitor_cancel_recursively   (TrackerMonitor *monitor,
 
 static guint signals[LAST_SIGNAL] = { 0, };
 
-G_DEFINE_TYPE_WITH_PRIVATE (TrackerMonitor, tracker_monitor, G_TYPE_OBJECT)
+static void tracker_monitor_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (TrackerMonitor, tracker_monitor, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                                tracker_monitor_initable_iface_init)
+                         G_ADD_PRIVATE (TrackerMonitor))
+
+static gboolean
+tracker_monitor_initable_init (GInitable     *initable,
+                               GCancellable  *cancellable,
+                               GError       **error)
+{
+       GType monitor_backend;
+       const gchar *name;
+       GError *inner_error = NULL;
+       TrackerMonitorPrivate *priv;
+       GFile *file;
+       GFileMonitor *monitor;
+
+       priv = tracker_monitor_get_instance_private (TRACKER_MONITOR (initable));
+
+       /* For the first monitor we get the type and find out if we
+        * are using inotify, FAM, polling, etc.
+        */
+       file = g_file_new_for_path (g_get_home_dir ());
+       monitor = g_file_monitor_directory (file,
+                                           G_FILE_MONITOR_WATCH_MOVES,
+                                           NULL,
+                                           &inner_error);
+       if (inner_error) {
+               g_propagate_error (error, inner_error);
+               return FALSE;
+       }
+
+       monitor_backend = G_OBJECT_TYPE (monitor);
+
+       /* We use the name because the type itself is actually
+        * private and not available publically. Note this is
+        * subject to change, but unlikely of course.
+        */
+       name = g_type_name (monitor_backend);
+
+       /* Set limits based on backend... */
+       if (strcmp (name, "GInotifyDirectoryMonitor") == 0 ||
+           strcmp (name, "GInotifyFileMonitor") == 0) {
+               /* Using inotify */
+               TRACKER_NOTE (MONITORS, g_message ("Monitor backend is Inotify"));
+
+               /* Setting limit based on kernel
+                * settings in /proc...
+                */
+               priv->monitor_limit = get_inotify_limit ();
+
+               /* We don't use 100% of the monitors, we allow other
+                * applications to have at least 500 or so to use
+                * between them selves. This only
+                * applies to inotify because it is a
+                * user shared resource.
+                */
+               priv->monitor_limit -= 500;
+
+               /* Make sure we don't end up with a
+                * negative maximum.
+                */
+               priv->monitor_limit = MAX (priv->monitor_limit, 0);
+       } else if (strcmp (name, "GKqueueDirectoryMonitor") == 0 ||
+                  strcmp (name, "GKqueueFileMonitor") == 0) {
+               /* Using kqueue(2) */
+               TRACKER_NOTE (MONITORS, g_message ("Monitor backend is kqueue"));
+
+               priv->monitor_limit = get_kqueue_limit ();
+       } else if (strcmp (name, "GFamDirectoryMonitor") == 0) {
+               /* Using Fam */
+               TRACKER_NOTE (MONITORS, g_message ("Monitor backend is Fam"));
+
+               /* Setting limit to an arbitary limit
+                * based on testing
+                */
+               priv->monitor_limit = 400;
+               priv->use_changed_event = TRUE;
+       } else if (strcmp (name, "GWin32DirectoryMonitor") == 0) {
+               /* Using Windows */
+               TRACKER_NOTE (MONITORS, g_message ("Monitor backend is Windows"));
+
+               /* Guessing limit... */
+               priv->monitor_limit = 8192;
+       } else {
+               /* Unknown */
+               g_warning ("Monitor backend:'%s' is unhandled. Monitoring will be disabled",
+                          name);
+               priv->enabled = FALSE;
+       }
+
+       if (priv->enabled)
+               TRACKER_NOTE (MONITORS, g_message ("Monitor limit is %d", priv->monitor_limit));
+
+       g_file_monitor_cancel (monitor);
+       g_object_unref (monitor);
+       g_object_unref (file);
+
+       return TRUE;
+}
+
+static void
+tracker_monitor_initable_iface_init (GInitableIface *iface)
+{
+       iface->init = tracker_monitor_initable_init;
+}
 
 static void
 tracker_monitor_class_init (TrackerMonitorClass *klass)
@@ -207,9 +314,6 @@ static void
 tracker_monitor_init (TrackerMonitor *object)
 {
        TrackerMonitorPrivate *priv;
-       GFile                 *file;
-       GFileMonitor          *monitor;
-       GError                *error = NULL;
 
        priv = tracker_monitor_get_instance_private (object);
 
@@ -228,97 +332,6 @@ tracker_monitor_init (TrackerMonitor *object)
                                       (GEqualFunc) g_file_equal,
                                       g_object_unref,
                                       (GDestroyNotify) cached_event_free);
-
-       /* For the first monitor we get the type and find out if we
-        * are using inotify, FAM, polling, etc.
-        */
-       file = g_file_new_for_path (g_get_home_dir ());
-       monitor = g_file_monitor_directory (file,
-                                           G_FILE_MONITOR_WATCH_MOVES,
-                                           NULL,
-                                           &error);
-
-       if (error) {
-               g_critical ("Could not create sample directory monitor: %s", error->message);
-               g_error_free (error);
-
-               /* Guessing limit... */
-               priv->monitor_limit = 100;
-       } else {
-               GType monitor_backend;
-               const gchar *name;
-
-               monitor_backend = G_OBJECT_TYPE (monitor);
-
-               /* We use the name because the type itself is actually
-                * private and not available publically. Note this is
-                * subject to change, but unlikely of course.
-                */
-               name = g_type_name (monitor_backend);
-
-               /* Set limits based on backend... */
-               if (strcmp (name, "GInotifyDirectoryMonitor") == 0 ||
-                   strcmp (name, "GInotifyFileMonitor") == 0) {
-                       /* Using inotify */
-                       TRACKER_NOTE (MONITORS, g_message ("Monitor backend is Inotify"));
-
-                       /* Setting limit based on kernel
-                        * settings in /proc...
-                        */
-                       priv->monitor_limit = get_inotify_limit ();
-
-                       /* We don't use 100% of the monitors, we allow other
-                        * applications to have at least 500 or so to use
-                        * between them selves. This only
-                        * applies to inotify because it is a
-                        * user shared resource.
-                        */
-                       priv->monitor_limit -= 500;
-
-                       /* Make sure we don't end up with a
-                        * negative maximum.
-                        */
-                       priv->monitor_limit = MAX (priv->monitor_limit, 0);
-               }
-               else if (strcmp (name, "GKqueueDirectoryMonitor") == 0 ||
-                        strcmp (name, "GKqueueFileMonitor") == 0) {
-                       /* Using kqueue(2) */
-                       TRACKER_NOTE (MONITORS, g_message ("Monitor backend is kqueue"));
-
-                       priv->monitor_limit = get_kqueue_limit ();
-               }
-               else if (strcmp (name, "GFamDirectoryMonitor") == 0) {
-                       /* Using Fam */
-                       TRACKER_NOTE (MONITORS, g_message ("Monitor backend is Fam"));
-
-                       /* Setting limit to an arbitary limit
-                        * based on testing
-                        */
-                       priv->monitor_limit = 400;
-                       priv->use_changed_event = TRUE;
-               }
-               else if (strcmp (name, "GWin32DirectoryMonitor") == 0) {
-                       /* Using Windows */
-                       TRACKER_NOTE (MONITORS, g_message ("Monitor backend is Windows"));
-
-                       /* Guessing limit... */
-                       priv->monitor_limit = 8192;
-               }
-               else {
-                       /* Unknown */
-                       g_warning ("Monitor backend:'%s' is unhandled. Monitoring will be disabled",
-                                  name);
-                       priv->enabled = FALSE;
-               }
-
-               g_file_monitor_cancel (monitor);
-               g_object_unref (monitor);
-       }
-
-       g_object_unref (file);
-
-       if (priv->enabled)
-               TRACKER_NOTE (MONITORS, g_message ("Monitor limit is %d", priv->monitor_limit));
 }
 
 static void
diff --git a/tests/libtracker-miner/tracker-monitor-test.c b/tests/libtracker-miner/tracker-monitor-test.c
index a52af9208..df0039c52 100644
--- a/tests/libtracker-miner/tracker-monitor-test.c
+++ b/tests/libtracker-miner/tracker-monitor-test.c
@@ -384,6 +384,7 @@ static void
 test_monitor_common_setup (TrackerMonitorTestFixture *fixture,
                            gconstpointer              data)
 {
+       GError *error = NULL;
        gchar *basename;
 
        /* Create hash tables to store expected results */
@@ -404,6 +405,8 @@ test_monitor_common_setup (TrackerMonitorTestFixture *fixture,
 
        /* Create and setup the tracker monitor */
        fixture->monitor = tracker_monitor_new ();
+       g_initable_init (G_INITABLE (fixture->monitor), NULL, &error);
+       g_assert_no_error (error);
        g_assert_true (fixture->monitor != NULL);
 
        g_signal_connect (fixture->monitor, "item-created",
@@ -1262,6 +1265,7 @@ test_monitor_basic (void)
        gchar *path_for_monitor;
        GFile *file_for_monitor;
        GFile *file_for_tmp;
+       GError *error = NULL;
 
        /* Setup directories */
        basename = g_strdup_printf ("monitor-test-%d", getpid ());
@@ -1277,6 +1281,8 @@ test_monitor_basic (void)
 
        /* Create a monitor */
        monitor = tracker_monitor_new ();
+       g_initable_init (G_INITABLE (monitor), NULL, &error);
+       g_assert_no_error (error);
        g_assert_true (monitor != NULL);
 
        /* Test general API with monitors enabled */


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