[dconf/wip/reorg] Reimplement sync() functionality
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dconf/wip/reorg] Reimplement sync() functionality
- Date: Tue, 10 Jul 2012 17:59:15 +0000 (UTC)
commit 4860be9319e971da6a21fe9f0e83a86b2581314e
Author: Ryan Lortie <desrt desrt ca>
Date: Tue Jul 10 13:58:03 2012 -0400
Reimplement sync() functionality
Add dconf_engine_sync() that does the same thing as the code in the
GSettings backend used to do, in a cleaner way.
Update the GSettings backend to use the new call.
Add a new call to DConfClient wrapping the engine call as well.
client/dconf-client.c | 26 +++++++++++++++++++++++-
client/dconf-client.h | 2 +
docs/dconf-sections.txt | 1 +
engine/dconf-engine.c | 39 +++++++++++++++++++++++++++++++++++++-
engine/dconf-engine.h | 4 +++
gsettings/dconfsettingsbackend.c | 4 ++-
6 files changed, 72 insertions(+), 4 deletions(-)
---
diff --git a/client/dconf-client.c b/client/dconf-client.c
index fad445c..7a2a96c 100644
--- a/client/dconf-client.c
+++ b/client/dconf-client.c
@@ -305,7 +305,9 @@ dconf_client_is_writable (DConfClient *client,
*
* This call merely queues up the write and returns immediately, without
* blocking. The only errors that can be detected or reported at this
- * point are attempts to write to read-only keys.
+ * point are attempts to write to read-only keys. If the application
+ * exits immediately after this function returns then the queued call
+ * may never be sent; see dconf_client_sync().
*
* A local copy of the written value is kept so that calls to
* dconf_client_read() that occur before the service actually makes the
@@ -393,7 +395,9 @@ dconf_client_write_sync (DConfClient *client,
*
* This call merely queues up the write and returns immediately, without
* blocking. The only errors that can be detected or reported at this
- * point are attempts to write to read-only keys.
+ * point are attempts to write to read-only keys. If the application
+ * exits immediately after this function returns then the queued call
+ * may never be sent; see dconf_client_sync().
*
* A local copy of the written value is kept so that calls to
* dconf_client_read() that occur before the service actually makes the
@@ -546,3 +550,21 @@ dconf_client_unwatch_sync (DConfClient *client,
dconf_engine_unwatch_sync (client->engine, path);
}
+
+/**
+ * dconf_client_sync:
+ * @client: a #DConfClient
+ *
+ * Blocks until all outstanding "fast" change or write operations have
+ * been submitted to the service.
+ *
+ * Applications should generally call this before exiting on any
+ * #DConfClient that they wrote to.
+ **/
+void
+dconf_client_sync (DConfClient *client)
+{
+ g_return_if_fail (DCONF_IS_CLIENT (client));
+
+ dconf_engine_sync (client->engine);
+}
diff --git a/client/dconf-client.h b/client/dconf-client.h
index d09fdbd..3a606c2 100644
--- a/client/dconf-client.h
+++ b/client/dconf-client.h
@@ -78,6 +78,8 @@ void dconf_client_unwatch_fast (DConfCl
void dconf_client_unwatch_sync (DConfClient *client,
const gchar *path);
+void dconf_client_sync (DConfClient *client);
+
G_END_DECLS
#endif /* __dconf_client_h__ */
diff --git a/docs/dconf-sections.txt b/docs/dconf-sections.txt
index 693ecbc..4f924b7 100644
--- a/docs/dconf-sections.txt
+++ b/docs/dconf-sections.txt
@@ -13,6 +13,7 @@ dconf_client_watch_fast
dconf_client_watch_sync
dconf_client_unwatch_fast
dconf_client_unwatch_sync
+dconf_client_sync
<SUBSECTION Standard>
DConfClientClass
DCONF_CLIENT
diff --git a/engine/dconf-engine.c b/engine/dconf-engine.c
index c1410b6..8d9837a 100644
--- a/engine/dconf-engine.c
+++ b/engine/dconf-engine.c
@@ -161,7 +161,8 @@ struct _DConfEngine
DConfEngineSource **sources; /* Array never changes, but each source changes internally. */
gint n_sources;
- GMutex queue_lock; /* This lock is for pending, in_flight */
+ GMutex queue_lock; /* This lock is for pending, in_flight, queue_cond */
+ GCond queue_cond; /* Signalled when the queues empty */
GQueue pending; /* DConfChangeset */
GQueue in_flight; /* DConfChangeset */
@@ -233,6 +234,7 @@ dconf_engine_new (gpointer user_data,
g_mutex_init (&engine->sources_lock);
g_mutex_init (&engine->queue_lock);
+ g_cond_init (&engine->queue_cond);
engine->sources = dconf_engine_profile_open (NULL, &engine->n_sources);
@@ -279,6 +281,7 @@ dconf_engine_unref (DConfEngine *engine)
g_mutex_clear (&engine->sources_lock);
g_mutex_clear (&engine->queue_lock);
+ g_cond_clear (&engine->queue_cond);
g_free (engine->last_handled);
@@ -948,6 +951,16 @@ dconf_engine_manage_queue (DConfEngine *engine)
g_queue_push_tail (&engine->in_flight, oc->change);
}
+
+ if (g_queue_is_empty (&engine->in_flight))
+ {
+ /* The in-flight queue should not be empty if we have changes
+ * pending...
+ */
+ g_assert (g_queue_is_empty (&engine->pending));
+
+ g_cond_broadcast (&engine->queue_cond);
+ }
}
static gboolean
@@ -1123,3 +1136,27 @@ dconf_engine_handle_dbus_signal (GBusType type,
g_warning ("Need to handle writability changes"); /* XXX */
}
}
+
+gboolean
+dconf_engine_has_outstanding (DConfEngine *engine)
+{
+ gboolean has;
+
+ /* The in-flight queue will never be empty unless the pending queue is
+ * also empty, so we only really need to check one of them...
+ */
+ dconf_engine_lock_queues (engine);
+ has = !g_queue_is_empty (&engine->in_flight);
+ dconf_engine_unlock_queues (engine);
+
+ return has;
+}
+
+void
+dconf_engine_sync (DConfEngine *engine)
+{
+ dconf_engine_lock_queues (engine);
+ while (!g_queue_is_empty (&engine->in_flight))
+ g_cond_wait (&engine->queue_cond, &engine->queue_lock);
+ dconf_engine_unlock_queues (engine);
+}
diff --git a/engine/dconf-engine.h b/engine/dconf-engine.h
index bad8cf1..96ac42b 100644
--- a/engine/dconf-engine.h
+++ b/engine/dconf-engine.h
@@ -152,6 +152,10 @@ gboolean dconf_engine_change_sync (DConfEn
DConfChangeset *changeset,
gchar **tag,
GError **error);
+G_GNUC_INTERNAL
+gboolean dconf_engine_has_outstanding (DConfEngine *engine);
+G_GNUC_INTERNAL
+void dconf_engine_sync (DConfEngine *engine);
/* Asynchronous API: not implemented yet (and maybe never?) */
diff --git a/gsettings/dconfsettingsbackend.c b/gsettings/dconfsettingsbackend.c
index 32b2cab..11c123c 100644
--- a/gsettings/dconfsettingsbackend.c
+++ b/gsettings/dconfsettingsbackend.c
@@ -135,7 +135,9 @@ dconf_settings_backend_unsubscribe (GSettingsBackend *backend,
static void
dconf_settings_backend_sync (GSettingsBackend *backend)
{
- /* XXX implement sync */
+ DConfSettingsBackend *dcsb = (DConfSettingsBackend *) backend;
+
+ dconf_engine_sync (dcsb->engine);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]