[libnotify] notify: Use lazy snap readings and once per notify instance



commit e8ea0c39d04b6c127bbb4b1317f13e972850db72
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Wed May 11 22:05:10 2022 +0200

    notify: Use lazy snap readings and once per notify instance
    
    An application under snap confinement won't have a way of escaping from
    it, so we can just initialize the snap variables at the global notify
    scope once and just re-use them when needed.

 libnotify/internal.h     |   4 ++
 libnotify/notification.c | 124 +++--------------------------------
 libnotify/notify.c       | 165 +++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 174 insertions(+), 119 deletions(-)
---
diff --git a/libnotify/internal.h b/libnotify/internal.h
index 741d002..35683d6 100644
--- a/libnotify/internal.h
+++ b/libnotify/internal.h
@@ -36,6 +36,10 @@ gint            _notify_notification_get_timeout            (const NotifyNotific
 gboolean        _notify_notification_has_nondefault_actions (const NotifyNotification *n);
 gboolean        _notify_check_spec_version                  (int major, int minor);
 
+const char     * _notify_get_snap_name                      (void);
+const char     * _notify_get_snap_path                      (void);
+const char     * _notify_get_snap_app                       (void);
+
 G_END_DECLS
 
 #endif /* _LIBNOTIFY_INTERNAL_H_ */
diff --git a/libnotify/notification.c b/libnotify/notification.c
index 0276df5..c781069 100644
--- a/libnotify/notification.c
+++ b/libnotify/notification.c
@@ -70,10 +70,6 @@ struct _NotifyNotificationPrivate
         char           *body;
         char           *activation_token;
 
-        const char     *snap_path;
-        const char     *snap_name;
-        char           *snap_app;
-
         /* NULL to use icon data. Anything else to have server lookup icon */
         char           *icon_name;
 
@@ -356,104 +352,6 @@ destroy_pair (CallbackPair *pair)
         g_free (pair);
 }
 
-static void
-maybe_initialize_snap (NotifyNotification *obj)
-{
-        NotifyNotificationPrivate *priv = obj->priv;
-        gchar *cgroup_contents = NULL;
-
-        priv->snap_path = g_getenv ("SNAP");
-        if (priv->snap_path == NULL)
-                return;
-
-        if (*priv->snap_path == '\0' ||
-            !strchr (priv->snap_path, G_DIR_SEPARATOR)) {
-                priv->snap_path = NULL;
-                return;
-        }
-
-        priv->snap_name = g_getenv ("SNAP_NAME");
-        if (priv->snap_name && *priv->snap_name == '\0') {
-                priv->snap_name = NULL;
-        }
-
-        if (g_file_get_contents ("/proc/self/cgroup", &cgroup_contents,
-                                 NULL, NULL)) {
-                gchar **lines = g_strsplit (cgroup_contents, "\n", -1);
-                gchar *found_snap_name = NULL;
-                gint i;
-
-                for (i = 0; lines[i]; ++i) {
-                        gchar **parts = g_strsplit (lines[i], ":", 3);
-                        gchar *basename;
-                        gchar **ns;
-                        guint ns_length;
-
-                        if (g_strv_length (parts) != 3) {
-                                g_strfreev (parts);
-                                continue;
-                        }
-
-                        basename = g_path_get_basename (parts[2]);
-                        g_strfreev (parts);
-
-                        if (!basename) {
-                                continue;
-                        }
-
-                        ns = g_strsplit (basename, ".", -1);
-                        ns_length = g_strv_length (ns);
-                        g_free (basename);
-
-                        if (ns_length < 2 || !g_str_equal (ns[0], "snap")) {
-                                g_strfreev (ns);
-                                continue;
-                        }
-
-                        if (priv->snap_name == NULL) {
-                                g_free (found_snap_name);
-                                found_snap_name = g_strdup (ns[1]);
-                        }
-
-                        if (ns_length < 3) {
-                                g_strfreev (ns);
-                                continue;
-                        }
-
-                        if (priv->snap_name == NULL) {
-                                priv->snap_name = found_snap_name;
-                                found_snap_name = NULL;
-                        }
-
-                        if (g_str_equal (ns[1], priv->snap_name)) {
-                                priv->snap_app = g_strdup (ns[2]);
-                                g_strfreev (ns);
-                                break;
-                        }
-
-                        g_strfreev (ns);
-                }
-
-                if (priv->snap_name == NULL && found_snap_name != NULL) {
-                        priv->snap_name = found_snap_name;
-                        found_snap_name = NULL;
-                }
-
-                g_strfreev (lines);
-                g_free (found_snap_name);
-        }
-
-        if (priv->snap_app == NULL) {
-                priv->snap_app = g_strdup (priv->snap_name);
-        }
-
-        g_debug ("SNAP path: %s", priv->snap_path);
-        g_debug ("SNAP name: %s", priv->snap_name);
-        g_debug ("SNAP app: %s", priv->snap_app);
-
-        g_free (cgroup_contents);
-}
-
 static void
 notify_notification_init (NotifyNotification *obj)
 {
@@ -469,8 +367,6 @@ notify_notification_init (NotifyNotification *obj)
                                                        g_str_equal,
                                                        g_free,
                                                        (GDestroyNotify) destroy_pair);
-
-        maybe_initialize_snap (obj);
 }
 
 static void
@@ -487,7 +383,6 @@ notify_notification_finalize (GObject *object)
         g_free (priv->body);
         g_free (priv->icon_name);
         g_free (priv->activation_token);
-        g_free (priv->snap_app);
 
         if (priv->actions != NULL) {
                 g_slist_foreach (priv->actions, (GFunc) g_free, NULL);
@@ -596,7 +491,6 @@ static gchar *
 try_prepend_snap_desktop (NotifyNotification *notification,
                           const gchar        *desktop)
 {
-        NotifyNotificationPrivate *priv = notification->priv;
         gchar *ret = NULL;
 
         /*
@@ -604,11 +498,11 @@ try_prepend_snap_desktop (NotifyNotification *notification,
          * ${SNAP_NAME}_; snap .desktop files are in the format
          * ${SNAP_NAME}_desktop_file_name
          */
-        ret = try_prepend_path (desktop, priv->snap_path);
+        ret = try_prepend_path (desktop, _notify_get_snap_path ());
 
-        if (ret == NULL && priv->snap_name != NULL &&
+        if (ret == NULL && _notify_get_snap_name () != NULL &&
             strchr (desktop, G_DIR_SEPARATOR) == NULL) {
-                ret = g_strdup_printf ("%s_%s", priv->snap_name, desktop);
+                ret = g_strdup_printf ("%s_%s", _notify_get_snap_name (), desktop);
         }
 
         return ret;
@@ -619,7 +513,7 @@ try_prepend_snap (NotifyNotification *notification,
                   const gchar        *value)
 {
         /* hardcoded paths to icons might be relocated under $SNAP */
-        return try_prepend_path (value, notification->priv->snap_path);
+        return try_prepend_path (value, _notify_get_snap_path ());
 }
 
 
@@ -831,13 +725,13 @@ notify_notification_show (NotifyNotification *notification,
                                        g_variant_new_int64 (getpid ()));
         }
 
-        if (priv->snap_app &&
+        if (_notify_get_snap_app () &&
             g_hash_table_lookup (priv->hints, "desktop-entry") == NULL) {
                 gchar *snap_desktop;
 
                 snap_desktop = g_strdup_printf ("%s_%s",
-                                                priv->snap_name,
-                                                priv->snap_app);
+                                                _notify_get_snap_name (),
+                                                _notify_get_snap_app ());
 
                 g_debug ("Using desktop entry: %s", snap_desktop);
                 g_variant_builder_add (&hints_builder, "{sv}",
@@ -846,7 +740,7 @@ notify_notification_show (NotifyNotification *notification,
         }
 
 #ifdef GLIB_VERSION_2_32
-        if (!priv->snap_app) {
+        if (!_notify_get_snap_app ()) {
                 application = g_application_get_default ();
         }
 
@@ -1078,7 +972,7 @@ maybe_parse_snap_hint_value (NotifyNotification *notification,
 {
         StringParserFunc parse_func = NULL;
 
-        if (!notification->priv->snap_path)
+        if (!_notify_get_snap_path ())
                 return value;
 
         if (g_strcmp0 (key, "desktop-entry") == 0) {
diff --git a/libnotify/notify.c b/libnotify/notify.c
index ce5a97b..ffe8d62 100644
--- a/libnotify/notify.c
+++ b/libnotify/notify.c
@@ -43,6 +43,8 @@
 
 static gboolean         _initted = FALSE;
 static char            *_app_name = NULL;
+static char            *_snap_name = NULL;
+static char            *_snap_app = NULL;
 static GDBusProxy      *_proxy = NULL;
 static GList           *_active_notifications = NULL;
 static int              _spec_version_major = 0;
@@ -151,13 +153,20 @@ notify_init (const char *app_name)
         if (_initted)
                 return TRUE;
 
+        if (app_name == NULL) {
 #ifdef GLIB_VERSION_2_32
-        if (app_name == NULL && g_application_get_default ()) {
-                GApplication *application = g_application_get_default ();
+                GApplication *application;
+#endif
 
-                app_name = g_application_get_application_id (application);
-        }
+                app_name = _notify_get_snap_app ();
+
+#ifdef GLIB_VERSION_2_32
+                if (app_name == NULL &&
+                    (application = g_application_get_default ())) {
+                        app_name = g_application_get_application_id (application);
+                }
 #endif
+        }
 
         notify_set_app_name (app_name);
 
@@ -170,6 +179,148 @@ notify_init (const char *app_name)
         return TRUE;
 }
 
+static void
+_initialize_snap_names (void)
+{
+        gchar *cgroup_contents = NULL;
+        gchar *found_snap_name = NULL;
+        gchar **lines;
+        gint i;
+
+        if (!g_file_get_contents ("/proc/self/cgroup", &cgroup_contents,
+                                  NULL, NULL)) {
+                g_free (cgroup_contents);
+                return;
+        }
+
+        lines = g_strsplit (cgroup_contents, "\n", -1);
+        g_free (cgroup_contents);
+
+        for (i = 0; lines[i]; ++i) {
+                gchar **parts = g_strsplit (lines[i], ":", 3);
+                gchar *basename;
+                gchar **ns;
+                guint ns_length;
+
+                if (g_strv_length (parts) != 3) {
+                        g_strfreev (parts);
+                        continue;
+                }
+
+                basename = g_path_get_basename (parts[2]);
+                g_strfreev (parts);
+
+                if (!basename) {
+                        continue;
+                }
+
+                ns = g_strsplit (basename, ".", -1);
+                ns_length = g_strv_length (ns);
+                g_free (basename);
+
+                if (ns_length < 2 || !g_str_equal (ns[0], "snap")) {
+                        g_strfreev (ns);
+                        continue;
+                }
+
+                if (_snap_name == NULL) {
+                        g_free (found_snap_name);
+                        found_snap_name = g_strdup (ns[1]);
+                }
+
+                if (ns_length < 3) {
+                        g_strfreev (ns);
+                        continue;
+                }
+
+                if (_snap_name == NULL) {
+                        _snap_name = found_snap_name;
+                        found_snap_name = NULL;
+                        g_debug ("SNAP name: %s", _snap_name);
+                }
+
+                if (g_str_equal (ns[1], _snap_name)) {
+                        _snap_app = g_strdup (ns[2]);
+                        g_strfreev (ns);
+                        break;
+                }
+
+                g_strfreev (ns);
+        }
+
+        if (_snap_name == NULL && found_snap_name != NULL) {
+                _snap_name = found_snap_name;
+                found_snap_name = NULL;
+                g_debug ("SNAP name: %s", _snap_name);
+        }
+
+        if (_snap_app == NULL) {
+                _snap_app = g_strdup (_snap_name);
+        }
+
+        g_debug ("SNAP app: %s", _snap_app);
+
+        g_strfreev (lines);
+        g_free (found_snap_name);
+}
+
+const char *
+_notify_get_snap_path (void)
+{
+        static const char *snap_path = NULL;
+        static gsize snap_path_set = FALSE;
+
+        if (g_once_init_enter (&snap_path_set)) {
+                snap_path = g_getenv ("SNAP");
+
+                if (!snap_path || *snap_path == '\0' ||
+                    !strchr (snap_path, G_DIR_SEPARATOR)) {
+                        snap_path = NULL;
+                } else {
+                        g_debug ("SNAP path: %s", snap_path);
+                }
+
+                g_once_init_leave (&snap_path_set, TRUE);
+        }
+
+        return snap_path;
+}
+
+const char *
+_notify_get_snap_name (void)
+{
+        static gsize snap_name_set = FALSE;
+
+        if (g_once_init_enter (&snap_name_set)) {
+                if (!_snap_name) {
+                        const char *snap_name_env = g_getenv ("SNAP_NAME");
+
+                        if (!snap_name_env || *snap_name_env == '\0')
+                                snap_name_env = NULL;
+
+                        _snap_name = g_strdup (snap_name_env);
+                        g_debug ("SNAP name: %s", _snap_name);
+                }
+
+                g_once_init_leave (&snap_name_set, TRUE);
+        }
+
+        return _snap_name;
+}
+
+const char *
+_notify_get_snap_app (void)
+{
+        static gsize snap_app_set = FALSE;
+
+        if (g_once_init_enter (&snap_app_set)) {
+                _initialize_snap_names ();
+                g_once_init_leave (&snap_app_set, TRUE);
+        }
+
+        return _snap_app;
+}
+
 /**
  * notify_get_app_name:
  *
@@ -219,6 +370,12 @@ notify_uninit (void)
             _proxy = NULL;
         }
 
+        g_free (_snap_name);
+        _snap_name = NULL;
+
+        g_free (_snap_app);
+        _snap_app = NULL;
+
         _initted = FALSE;
 }
 


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