Commit 3cad2c06 authored by Gaël Bonithon's avatar Gaël Bonithon
Browse files

Flatpak: Add lifecycle manager patch to Xfconf dependency

And move patches to a dedicated directory.

Related to xfce/xfconf!19.
parent c50f1237
Pipeline #12755 passed with stages
in 1 minute and 20 seconds
......@@ -91,7 +91,9 @@ modules:
project-id: 14854
tag-template: xfconf-$version
- type: patch
path: Xfconf-Allow-to-choose-an-alternative-service-name-prefix.patch
path: patches/Xfconf-Allow-to-choose-an-alternative-service-name-prefix.patch
- type: patch
path: patches/Add-a-lifecycle-manager-to-xfconfd.patch
- name: libxfce4ui
cleanup:
......@@ -162,7 +164,7 @@ modules:
timestamp-query: .published_at
# see https://github.com/flathub/org.gimp.GIMP/blob/master/org.gimp.GIMP.json
- type: patch
path: libwmf-autoheader.patch
path: patches/libwmf-autoheader.patch
modules:
- name: freetype
buildsystem: meson
......@@ -281,7 +283,7 @@ modules:
project-id: 5014
tag-template: tumbler-$version
- type: patch
path: Tumbler-Allow-to-choose-an-alternative-service-name-prefix.patch
path: patches/Tumbler-Allow-to-choose-an-alternative-service-name-prefix.patch
- name: ristretto
config-opts:
......
From 45824fe4f5297e59e6c240f36a1566d30855554b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= <gael@xfce.org>
Date: Tue, 11 Jan 2022 11:04:52 +0100
Subject: [PATCH] Add a lifecycle manager to xfconfd
Copied from Tumbler, with some adjustments.
Closes #28, see !19 for more details.
---
xfconfd/Makefile.am | 2 +
xfconfd/main.c | 16 ++-
xfconfd/xfconf-daemon.c | 77 +++++-----
xfconfd/xfconf-daemon.h | 2 +
xfconfd/xfconf-lifecycle-manager.c | 224 +++++++++++++++++++++++++++++
xfconfd/xfconf-lifecycle-manager.h | 51 +++++++
6 files changed, 336 insertions(+), 36 deletions(-)
create mode 100644 xfconfd/xfconf-lifecycle-manager.c
create mode 100644 xfconfd/xfconf-lifecycle-manager.h
diff --git a/xfconfd/Makefile.am b/xfconfd/Makefile.am
index f33c0fc..7b19150 100644
--- a/xfconfd/Makefile.am
+++ b/xfconfd/Makefile.am
@@ -26,6 +26,8 @@ xfconfd_SOURCES = \
xfconf-backend.h \
xfconf-daemon.c \
xfconf-daemon.h \
+ xfconf-lifecycle-manager.c \
+ xfconf-lifecycle-manager.h \
xfconf-locking-utils.c \
xfconf-locking-utils.h \
$(xfconf_backend_sources) \
diff --git a/xfconfd/main.c b/xfconfd/main.c
index 4c8faae..01129b1 100644
--- a/xfconfd/main.c
+++ b/xfconfd/main.c
@@ -136,6 +136,7 @@ main(int argc,
{
GMainLoop *mloop;
XfconfDaemon *xfconfd;
+ XfconfLifecycleManager *manager;
GError *error = NULL;
struct sigaction act = {0};
GIOChannel *signal_io;
@@ -220,15 +221,21 @@ main(int argc,
backends = g_new0(gchar *, 2);
backends[0] = g_strdup(DEFAULT_BACKEND);
}
-
- xfconfd = xfconf_daemon_new_unique(backends, &error);
+
+ manager = xfconf_lifecycle_manager_new ();
+ xfconfd = xfconf_daemon_new_unique (backends, manager, &error);
if(!xfconfd) {
g_critical("Xfconfd failed to start: %s\n", error->message);
+ g_object_unref (manager);
g_error_free(error);
return EXIT_FAILURE;
}
g_strfreev(backends);
-
+
+ /* quit the main loop when the xfconf daemon asks us to shutdown */
+ g_signal_connect_swapped (manager, "shutdown", G_CALLBACK (g_main_loop_quit), mloop);
+ xfconf_lifecycle_manager_start (manager);
+
/* acquire name */
is_test_mode = g_getenv ("XFCONF_RUN_IN_TEST_MODE");
g_bus_own_name (G_BUS_TYPE_SESSION,
@@ -256,7 +263,8 @@ main(int argc,
g_main_loop_run(mloop);
- g_object_unref(G_OBJECT(xfconfd));
+ g_object_unref (xfconfd);
+ g_object_unref (manager);
xfconf_backend_factory_cleanup();
diff --git a/xfconfd/xfconf-daemon.c b/xfconfd/xfconf-daemon.c
index ddc1d7b..3f2e7ec 100644
--- a/xfconfd/xfconf-daemon.c
+++ b/xfconfd/xfconf-daemon.c
@@ -175,7 +175,7 @@ xfconf_set_property(XfconfExported *skeleton,
if(error) {
g_dbus_method_invocation_return_gerror(invocation, error);
g_error_free(error);
- return FALSE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
}
}
@@ -192,7 +192,7 @@ xfconf_set_property(XfconfExported *skeleton,
g_value_unset (value);
g_free (value);
- return TRUE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
}
@@ -225,13 +225,13 @@ xfconf_get_property(XfconfExported *skeleton,
g_error_free(error);
}
g_value_unset(&value);
- return TRUE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
} else if(l->next)
g_clear_error(&error);
}
g_dbus_method_invocation_return_gerror(invocation, error);
g_error_free(error);
- return TRUE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
}
static gboolean
@@ -248,7 +248,7 @@ xfconf_get_all_properties(XfconfExported *skeleton,
properties = g_hash_table_new_full(g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)_xfconf_gvalue_free);
- /* get all properties from all backends. if they all fail, return FALSE */
+ /* get all properties from all backends */
for(l = xfconfd->backends; l; l = l->next) {
if(xfconf_backend_get_all(l->data, channel, property_base,
properties, &error))
@@ -268,7 +268,7 @@ xfconf_get_all_properties(XfconfExported *skeleton,
if(error)
g_error_free(error);
g_hash_table_destroy(properties);
- return TRUE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
}
static gboolean
@@ -282,8 +282,7 @@ xfconf_property_exists(XfconfExported *skeleton,
gboolean succeed = FALSE;
GList *l;
GError *error = NULL;
- /* if at least one backend returns TRUE (regardles if |*exists| gets set
- * to TRUE or FALSE), we'll return TRUE from this function */
+
for(l = xfconfd->backends; !exists && l; l = l->next) {
if(xfconf_backend_exists(l->data, channel, property, &exists, &error))
succeed = TRUE;
@@ -297,7 +296,7 @@ xfconf_property_exists(XfconfExported *skeleton,
g_dbus_method_invocation_return_gerror(invocation, error);
g_error_free(error);
}
- return TRUE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
}
static gboolean
@@ -330,7 +329,7 @@ xfconf_reset_property(XfconfExported *skeleton,
if(error)
g_error_free(error);
- return TRUE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
}
static gboolean
@@ -370,7 +369,7 @@ xfconf_list_channels(XfconfExported *skeleton,
if(error)
g_error_free(error);
- return TRUE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
}
static gboolean xfconf_is_property_locked(XfconfExported *skeleton,
@@ -399,7 +398,7 @@ static gboolean xfconf_is_property_locked(XfconfExported *skeleton,
if(error)
g_error_free(error);
- return TRUE;
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
}
static void
@@ -491,8 +490,39 @@ xfconf_daemon_load_config(XfconfDaemon *xfconfd,
}
+#define XFCONF_DAEMON_CONNECT(signal_name, signal_handler) \
+ G_STMT_START{ \
+ g_signal_connect_swapped (xfconfd, signal_name, \
+ G_CALLBACK (xfconf_lifecycle_manager_increment_use_count), \
+ manager); \
+ g_signal_connect (xfconfd, signal_name, signal_handler, xfconfd); \
+ g_signal_connect_swapped (xfconfd, signal_name, \
+ G_CALLBACK (xfconf_lifecycle_manager_keep_alive), manager); \
+ g_signal_connect_swapped (xfconfd, signal_name, \
+ G_CALLBACK (xfconf_lifecycle_manager_decrement_use_count), \
+ manager); \
+ }G_STMT_END
+
+typedef struct
+{
+ gchar *name;
+ GCallback handler;
+} XfconfExportedSignal;
+
+static const XfconfExportedSignal xfconf_exported_signals[] =
+{
+ { "handle-get-all-properties", G_CALLBACK (xfconf_get_all_properties) },
+ { "handle-get-property", G_CALLBACK (xfconf_get_property) },
+ { "handle-is-property-locked", G_CALLBACK (xfconf_is_property_locked) },
+ { "handle-list-channels", G_CALLBACK (xfconf_list_channels) },
+ { "handle-property-exists", G_CALLBACK (xfconf_property_exists) },
+ { "handle-reset-property", G_CALLBACK (xfconf_reset_property) },
+ { "handle-set-property", G_CALLBACK (xfconf_set_property) },
+};
+
XfconfDaemon *
xfconf_daemon_new_unique(gchar * const *backend_ids,
+ XfconfLifecycleManager *manager,
GError **error)
{
XfconfDaemon *xfconfd;
@@ -508,26 +538,9 @@ xfconf_daemon_new_unique(gchar * const *backend_ids,
return NULL;
}
- g_signal_connect (xfconfd, "handle-get-all-properties",
- G_CALLBACK(xfconf_get_all_properties), xfconfd);
-
- g_signal_connect (xfconfd, "handle-get-property",
- G_CALLBACK(xfconf_get_property), xfconfd);
-
- g_signal_connect (xfconfd, "handle-is-property-locked",
- G_CALLBACK(xfconf_is_property_locked), xfconfd);
-
- g_signal_connect (xfconfd, "handle-list-channels",
- G_CALLBACK(xfconf_list_channels), xfconfd);
+ for (guint n = 0; n < G_N_ELEMENTS (xfconf_exported_signals); n++)
+ XFCONF_DAEMON_CONNECT (xfconf_exported_signals[n].name,
+ xfconf_exported_signals[n].handler);
- g_signal_connect (xfconfd, "handle-property-exists",
- G_CALLBACK(xfconf_property_exists), xfconfd);
-
- g_signal_connect (xfconfd, "handle-reset-property",
- G_CALLBACK(xfconf_reset_property), xfconfd);
-
- g_signal_connect (xfconfd, "handle-set-property",
- G_CALLBACK(xfconf_set_property), xfconfd);
-
return xfconfd;
}
diff --git a/xfconfd/xfconf-daemon.h b/xfconfd/xfconf-daemon.h
index aaddb2a..1735ee7 100644
--- a/xfconfd/xfconf-daemon.h
+++ b/xfconfd/xfconf-daemon.h
@@ -21,6 +21,7 @@
#define __XFCONF_DAEMON_H__
#include <glib-object.h>
+#include "xfconf-lifecycle-manager.h"
#include "xfconf/xfconf-errors.h"
#define XFCONF_TYPE_DAEMON (xfconf_daemon_get_type())
@@ -37,6 +38,7 @@ typedef struct _XfconfDaemon XfconfDaemon;
GType xfconf_daemon_get_type(void) G_GNUC_CONST;
XfconfDaemon *xfconf_daemon_new_unique(gchar * const *backend_ids,
+ XfconfLifecycleManager *manager,
GError **error);
G_END_DECLS
diff --git a/xfconfd/xfconf-lifecycle-manager.c b/xfconfd/xfconf-lifecycle-manager.c
new file mode 100644
index 0000000..794f3ad
--- /dev/null
+++ b/xfconfd/xfconf-lifecycle-manager.c
@@ -0,0 +1,224 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+
+#include <xfconf-lifecycle-manager.h>
+
+
+
+#define SHUTDOWN_TIMEOUT_SECONDS 300
+
+
+
+enum
+{
+ SIGNAL_SHUTDOWN,
+ N_SIGNALS,
+};
+
+
+
+static void xfconf_lifecycle_manager_finalize (GObject *object);
+
+
+
+struct _XfconfLifecycleManagerPrivate
+{
+ GMutex lock;
+
+ guint timeout_id;
+ guint use_count;
+ gboolean shutdown_emitted;
+};
+
+
+
+static guint lifecycle_manager_signals[N_SIGNALS];
+
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (XfconfLifecycleManager, xfconf_lifecycle_manager, G_TYPE_OBJECT)
+
+
+
+static void
+xfconf_lifecycle_manager_class_init (XfconfLifecycleManagerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = xfconf_lifecycle_manager_finalize;
+
+ lifecycle_manager_signals[SIGNAL_SHUTDOWN] =
+ g_signal_new ("shutdown", XFCONF_TYPE_LIFECYCLE_MANAGER, G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+
+
+static void
+xfconf_lifecycle_manager_init (XfconfLifecycleManager *manager)
+{
+ manager->priv = xfconf_lifecycle_manager_get_instance_private (manager);
+ g_mutex_init (&manager->priv->lock);
+ manager->priv->timeout_id = 0;
+ manager->priv->use_count = 0;
+ manager->priv->shutdown_emitted = FALSE;
+}
+
+
+
+static void
+xfconf_lifecycle_manager_finalize (GObject *object)
+{
+ XfconfLifecycleManager *manager = XFCONF_LIFECYCLE_MANAGER (object);
+
+ g_mutex_clear (&manager->priv->lock);
+
+ G_OBJECT_CLASS (xfconf_lifecycle_manager_parent_class)->finalize (object);
+}
+
+
+
+static gboolean
+xfconf_lifecycle_manager_timeout (gpointer user_data)
+{
+ XfconfLifecycleManager *manager = user_data;
+
+ g_mutex_lock (&manager->priv->lock);
+
+ /* reschedule the timeout if the daemon is currently in use */
+ if (manager->priv->use_count > 0)
+ {
+ g_mutex_unlock (&manager->priv->lock);
+ return TRUE;
+ }
+
+ /* reset the timeout id */
+ manager->priv->timeout_id = 0;
+
+ /* emit the shutdown signal */
+ g_signal_emit (manager, lifecycle_manager_signals[SIGNAL_SHUTDOWN], 0);
+
+ /* set the shutdown emitted flag to force other threads not to reschedule
+ * the timeout */
+ manager->priv->shutdown_emitted = TRUE;
+
+ g_mutex_unlock (&manager->priv->lock);
+
+ return FALSE;
+}
+
+
+
+XfconfLifecycleManager *
+xfconf_lifecycle_manager_new (void)
+{
+ return g_object_new (XFCONF_TYPE_LIFECYCLE_MANAGER, NULL);
+}
+
+
+
+void
+xfconf_lifecycle_manager_start (XfconfLifecycleManager *manager)
+{
+ g_return_if_fail (XFCONF_IS_LIFECYCLE_MANAGER (manager));
+
+ g_mutex_lock (&manager->priv->lock);
+
+ /* ignore if there already is a timeout scheduled */
+ if (manager->priv->timeout_id != 0)
+ {
+ g_mutex_unlock (&manager->priv->lock);
+ return;
+ }
+
+ manager->priv->timeout_id =
+ g_timeout_add_seconds (SHUTDOWN_TIMEOUT_SECONDS,
+ xfconf_lifecycle_manager_timeout,
+ manager);
+
+ g_mutex_unlock (&manager->priv->lock);
+}
+
+
+
+gboolean
+xfconf_lifecycle_manager_keep_alive (XfconfLifecycleManager *manager)
+{
+ g_return_val_if_fail (XFCONF_IS_LIFECYCLE_MANAGER (manager), G_DBUS_METHOD_INVOCATION_UNHANDLED);
+
+ g_mutex_lock (&manager->priv->lock);
+
+ /* if the shutdown signal has been emitted, there's nothing we can do to prevent
+ * a shutdown anymore */
+ if (manager->priv->shutdown_emitted)
+ {
+ g_mutex_unlock (&manager->priv->lock);
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
+ }
+
+ /* drop existing timeout, if any */
+ if (manager->priv->timeout_id != 0)
+ g_source_remove (manager->priv->timeout_id);
+
+ /* reschedule the shutdown timeout */
+ manager->priv->timeout_id =
+ g_timeout_add_seconds (SHUTDOWN_TIMEOUT_SECONDS,
+ xfconf_lifecycle_manager_timeout,
+ manager);
+
+ g_mutex_unlock (&manager->priv->lock);
+
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
+}
+
+
+
+gboolean
+xfconf_lifecycle_manager_increment_use_count (XfconfLifecycleManager *manager)
+{
+ g_return_val_if_fail (XFCONF_IS_LIFECYCLE_MANAGER (manager), G_DBUS_METHOD_INVOCATION_UNHANDLED);
+
+ g_mutex_lock (&manager->priv->lock);
+
+ manager->priv->use_count++;
+
+ g_mutex_unlock (&manager->priv->lock);
+
+ return G_DBUS_METHOD_INVOCATION_UNHANDLED;
+}
+
+
+
+gboolean
+xfconf_lifecycle_manager_decrement_use_count (XfconfLifecycleManager *manager)
+{
+ g_return_val_if_fail (XFCONF_IS_LIFECYCLE_MANAGER (manager), G_DBUS_METHOD_INVOCATION_HANDLED);
+
+ g_mutex_lock (&manager->priv->lock);
+
+ /* decrement the use count, make sure not to drop below zero */
+ if (manager->priv->use_count > 0)
+ manager->priv->use_count--;
+
+ g_mutex_unlock (&manager->priv->lock);
+
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
+}
diff --git a/xfconfd/xfconf-lifecycle-manager.h b/xfconfd/xfconf-lifecycle-manager.h
new file mode 100644
index 0000000..5c4b6ad
--- /dev/null
+++ b/xfconfd/xfconf-lifecycle-manager.h
@@ -0,0 +1,51 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __XFCONF_LIFECYCLE_MANAGER_H__
+#define __XFCONF_LIFECYCLE_MANAGER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#if ! GLIB_CHECK_VERSION (2, 68, 0)
+#define G_DBUS_METHOD_INVOCATION_HANDLED TRUE
+#define G_DBUS_METHOD_INVOCATION_UNHANDLED FALSE
+#endif
+
+#define XFCONF_TYPE_LIFECYCLE_MANAGER xfconf_lifecycle_manager_get_type ()
+G_DECLARE_FINAL_TYPE (XfconfLifecycleManager, xfconf_lifecycle_manager, XFCONF, LIFECYCLE_MANAGER, GObject)
+
+typedef struct _XfconfLifecycleManagerPrivate XfconfLifecycleManagerPrivate;
+
+struct _XfconfLifecycleManager
+{
+ GObject parent;
+ XfconfLifecycleManagerPrivate *priv;
+};
+
+XfconfLifecycleManager* xfconf_lifecycle_manager_new (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+void xfconf_lifecycle_manager_start (XfconfLifecycleManager *manager);
+
+gboolean xfconf_lifecycle_manager_keep_alive (XfconfLifecycleManager *manager);
+
+gboolean xfconf_lifecycle_manager_increment_use_count (XfconfLifecycleManager *manager);
+
+gboolean xfconf_lifecycle_manager_decrement_use_count (XfconfLifecycleManager *manager);
+
+G_END_DECLS
+
+#endif /* !__XFCONF_LIFECYCLE_MANAGER_H__ */
--
2.34.1
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment