[glib/wip/settings-backend: 2/7] GSettings: remove main context logic from backend
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/settings-backend: 2/7] GSettings: remove main context logic from backend
- Date: Fri, 30 Dec 2011 00:29:09 +0000 (UTC)
commit b4187cfa1a60b80dbe2083abf7c1c57aa8ee5ef9
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Dec 29 02:57:58 2011 -0500
GSettings: remove main context logic from backend
The main context dispatching logic substantially complicates the backend
and is only needed for the GSettings frontend. Move it there instead.
gio/gdelayedsettingsbackend.c | 3 +-
gio/gsettings.c | 82 +++++++++++++++++++++++++--------------
gio/gsettingsbackend.c | 75 ++----------------------------------
gio/gsettingsbackendinternal.h | 3 +-
4 files changed, 58 insertions(+), 105 deletions(-)
---
diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c
index b85d724..a891fe1 100644
--- a/gio/gdelayedsettingsbackend.c
+++ b/gio/gdelayedsettingsbackend.c
@@ -347,8 +347,7 @@ g_delayed_settings_backend_new (GSettingsBackend *backend,
g_object_weak_ref (owner, g_delayed_settings_backend_disown, delayed);
- g_settings_backend_watch (delayed->priv->backend,
- g_delayed_settings_got_event, G_OBJECT (delayed), NULL);
+ g_settings_backend_watch (delayed->priv->backend, g_delayed_settings_got_event, G_OBJECT (delayed));
return delayed;
}
diff --git a/gio/gsettings.c b/gio/gsettings.c
index 619d5a5..659f264 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -294,16 +294,22 @@ g_settings_real_writable_change_event (GSettings *settings,
return FALSE;
}
-static void
-g_settings_emit_signal (GSettings *settings,
- GSettingsEventType type,
- const GQuark *quarks,
- gint n_items)
+typedef struct
+{
+ GSettings *settings;
+ GSettingsEventType type;
+ GQuark *quarks;
+ gint n_items;
+} GSettingsSignalData;
+
+static gboolean
+g_settings_emit_signal (gpointer user_data)
{
+ GSettingsSignalData *data = user_data;
gboolean ignore_this;
guint signal_id;
- switch (type)
+ switch (data->type)
{
case G_SETTINGS_EVENT_CHANGE:
signal_id = g_settings_signals[SIGNAL_CHANGE_EVENT];
@@ -317,23 +323,49 @@ g_settings_emit_signal (GSettings *settings,
g_assert_not_reached ();
}
- /* writable-change-event signals are emitted in a different way */
+ /* this signal is presently emitted differently */
if (signal_id == g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT])
{
- if (n_items > 0)
+ if (data->n_items > 0)
{
gint i;
- for (i = 0; i < n_items; i++)
- g_signal_emit (settings, signal_id, 0, quarks[i], &ignore_this);
+ for (i = 0; i < data->n_items; i++)
+ g_signal_emit (data->settings, signal_id, 0, data->quarks[i], &ignore_this);
}
else
- g_signal_emit (settings, signal_id, 0, (GQuark) 0, &ignore_this);
+ g_signal_emit (data->settings, signal_id, 0, (GQuark) 0, &ignore_this);
- return;
+ goto out;
}
- g_signal_emit (settings, signal_id, 0, quarks, n_items, &ignore_this);
+ g_signal_emit (data->settings, signal_id, 0, data->quarks, data->n_items, &ignore_this);
+
+out:
+ g_object_unref (data->settings);
+ g_free (data->quarks);
+
+ g_slice_free (GSettingsSignalData, data);
+
+ return G_SOURCE_REMOVE;
+}
+
+/* consumes 'quarks' */
+static void
+g_settings_dispatch_signal (GSettings *settings,
+ GSettingsEventType type,
+ GQuark *quarks,
+ gint n_items)
+{
+ GSettingsSignalData *data;
+
+ data = g_slice_new (GSettingsSignalData);
+ data->settings = g_object_ref (settings);
+ data->type = type;
+ data->quarks = quarks;
+ data->n_items = n_items;
+
+ g_main_context_invoke (settings->priv->main_context, g_settings_emit_signal, data);
}
static void
@@ -403,7 +435,7 @@ g_settings_got_event (GObject *target,
GQuark quark;
quark = g_quark_from_string (prefix);
- g_settings_emit_signal (settings, event->type, &quark, 1);
+ g_settings_dispatch_signal (settings, event->type, g_memdup (&quark, sizeof quark), 1);
}
}
else
@@ -421,7 +453,7 @@ g_settings_got_event (GObject *target,
* this case since everything has changed.
*/
if (event->keys[0] == NULL)
- g_settings_emit_signal (settings, event->type, NULL, 0);
+ g_settings_dispatch_signal (settings, event->type, NULL, 0);
else
{
@@ -429,11 +461,7 @@ g_settings_got_event (GObject *target,
gint n, i, j;
n = g_strv_length (event->keys);
-
- if (20 < n)
- quarks = g_new (GQuark, n);
- else
- quarks = g_newa (GQuark, n);
+ quarks = g_new (GQuark, n);
j = 0;
for (i = 0; event->keys[i]; i++)
@@ -458,9 +486,8 @@ g_settings_got_event (GObject *target,
/* Only signal if we actually had a match. */
if (j > 0)
- g_settings_emit_signal (settings, event->type, quarks, j);
-
- if (20 < n)
+ g_settings_dispatch_signal (settings, event->type, quarks, j);
+ else
g_free (quarks);
}
}
@@ -600,10 +627,7 @@ g_settings_constructed (GObject *object)
if (settings->priv->backend == NULL)
settings->priv->backend = g_settings_backend_get_default ();
- g_settings_backend_watch (settings->priv->backend,
- g_settings_got_event,
- G_OBJECT (settings),
- settings->priv->main_context);
+ g_settings_backend_watch (settings->priv->backend, g_settings_got_event, G_OBJECT (settings));
g_settings_backend_subscribe (settings->priv->backend,
settings->priv->path);
}
@@ -1927,9 +1951,7 @@ g_settings_delay (GSettings *settings)
g_object_unref (settings->priv->backend);
settings->priv->backend = G_SETTINGS_BACKEND (settings->priv->delayed);
- g_settings_backend_watch (settings->priv->backend,
- g_settings_got_event, G_OBJECT (settings),
- settings->priv->main_context);
+ g_settings_backend_watch (settings->priv->backend, g_settings_got_event, G_OBJECT (settings));
g_object_notify (G_OBJECT (settings), "delay-apply");
}
diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c
index 62235d4..c09bba8 100644
--- a/gio/gsettingsbackend.c
+++ b/gio/gsettingsbackend.c
@@ -35,7 +35,6 @@
G_DEFINE_ABSTRACT_TYPE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT)
-typedef struct _GSettingsBackendClosure GSettingsBackendClosure;
typedef struct _GSettingsBackendWatch GSettingsBackendWatch;
struct _GSettingsBackendPrivate
@@ -128,18 +127,9 @@ struct _GSettingsBackendWatch
{
GObject *target;
GSettingsEventFunc function;
- GMainContext *context;
GSettingsBackendWatch *next;
};
-struct _GSettingsBackendClosure
-{
- GSettingsEventFunc function;
- GSettingsBackend *backend;
- GObject *target;
- GSettingsEvent event;
-};
-
static void
g_settings_backend_watch_weak_notify (gpointer data,
GObject *where_the_object_was)
@@ -169,31 +159,14 @@ g_settings_backend_watch_weak_notify (gpointer data,
* g_settings_backend_watch:
* @backend: a #GSettingsBackend
* @target: the GObject (typically GSettings instance) to call back to
- * @context: a #GMainContext, or %NULL
* ...: callbacks...
*
* Registers a new watch on a #GSettingsBackend.
- *
- * note: %NULL @context does not mean "default main context" but rather,
- * "it is okay to dispatch in any context". If the default main context
- * is specifically desired then it must be given.
- *
- * note also: if you want to get meaningful values for the @origin_tag
- * that appears as an argument to some of the callbacks, you *must* have
- * @context as %NULL. Otherwise, you are subject to cross-thread
- * dispatching and whatever owned @origin_tag at the time that the event
- * occurred may no longer own it. This is a problem if you consider that
- * you may now be the new owner of that address and mistakenly think
- * that the event in question originated from yourself.
- *
- * tl;dr: If you give a non-%NULL @context then you must ignore the
- * value of @origin_tag given to any callbacks.
**/
void
g_settings_backend_watch (GSettingsBackend *backend,
GSettingsEventFunc callback,
- GObject *target,
- GMainContext *context)
+ GObject *target)
{
GSettingsBackendWatch *watch;
@@ -220,19 +193,11 @@ g_settings_backend_watch (GSettingsBackend *backend,
* possible to keep the object alive using g_object_ref() and we would
* have no way of knowing this.
*
- * Note also that we do not need to hold a reference on the main
- * context here since the GSettings instance does that for us and we
- * will receive the weak notify long before it is dropped. We don't
- * even need to hold it during dispatches because our reference on the
- * GSettings will prevent the finalize from running and dropping the
- * ref on the context.
- *
* All access to the list holds a mutex. We have some strategies to
* avoid some of the pain that would be associated with that.
*/
watch = g_slice_new (GSettingsBackendWatch);
- watch->context = context;
watch->function = callback;
watch->target = target;
g_object_weak_ref (target, g_settings_backend_watch_weak_notify, backend);
@@ -255,23 +220,6 @@ g_settings_backend_unwatch (GSettingsBackend *backend,
g_settings_backend_watch_weak_notify (backend, target);
}
-static gboolean
-g_settings_backend_invoke_closure (gpointer user_data)
-{
- GSettingsBackendClosure *closure = user_data;
-
- closure->function (closure->target, &closure->event);
-
- g_object_unref (closure->backend);
- g_object_unref (closure->target);
- g_strfreev (closure->event.keys);
- g_free (closure->event.prefix);
-
- g_slice_free (GSettingsBackendClosure, closure);
-
- return FALSE;
-}
-
void
g_settings_backend_report_event (GSettingsBackend *backend,
const GSettingsEvent *event)
@@ -301,28 +249,13 @@ g_settings_backend_report_event (GSettingsBackend *backend,
/* The suffix is now immutable, so this is safe. */
for (watch = suffix; watch; watch = next)
{
- GSettingsBackendClosure *closure;
-
- closure = g_slice_new (GSettingsBackendClosure);
- closure->backend = g_object_ref (backend);
- closure->target = watch->target; /* we took our ref above */
- closure->function = watch->function;
- closure->event.type = event->type;
- closure->event.prefix = g_strdup (event->prefix);
- closure->event.keys = g_strdupv (event->keys);
- closure->event.origin_tag = event->origin_tag;
-
/* we do this here because 'watch' may not live to the end of this
- * iteration of the loop (since we may unref the target below).
+ * iteration of the loop (since we unref the target below).
*/
next = watch->next;
- if (watch->context)
- g_main_context_invoke (watch->context,
- g_settings_backend_invoke_closure,
- closure);
- else
- g_settings_backend_invoke_closure (closure);
+ watch->function (watch->target, event);
+ g_object_unref (watch->target); /* free the ref we acquired above */
}
}
diff --git a/gio/gsettingsbackendinternal.h b/gio/gsettingsbackendinternal.h
index 288b3b4..0587cab 100644
--- a/gio/gsettingsbackendinternal.h
+++ b/gio/gsettingsbackendinternal.h
@@ -32,8 +32,7 @@ typedef void (* GSettingsEventFunc) (GObject
G_GNUC_INTERNAL
void g_settings_backend_watch (GSettingsBackend *backend,
GSettingsEventFunc callback,
- GObject *target,
- GMainContext *context);
+ GObject *target);
G_GNUC_INTERNAL
void g_settings_backend_unwatch (GSettingsBackend *backend,
GObject *target);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]