[dconf] Bug 396998 - asynchronous early-error dispatch
- From: Ryan Lortie <ryanl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [dconf] Bug 396998 - asynchronous early-error dispatch
- Date: Wed, 7 Oct 2009 01:37:12 +0000 (UTC)
commit e7498e478932975569a85fb1c209e94b8f780d15
Author: Ryan Lortie <desrt desrt ca>
Date: Tue Oct 6 21:36:02 2009 -0400
Bug 396998 - asynchronous early-error dispatch
Add code to dbus backend to dispatch errors.
dconf/dconf-core.c | 12 +++--
dconf/dconf-dbus.c | 122 +++++++++++++++++++++++++++++++++++-----------------
dconf/dconf-dbus.h | 4 +-
3 files changed, 94 insertions(+), 44 deletions(-)
---
diff --git a/dconf/dconf-core.c b/dconf/dconf-core.c
index 95059b4..e62acb3 100644
--- a/dconf/dconf-core.c
+++ b/dconf/dconf-core.c
@@ -565,8 +565,10 @@ dconf_merge_async (const gchar *prefix,
if (!dconf_check_tree_writable (mount, prefix, tree, &error))
{
- g_assert_not_reached ();
- // XXX dispatch in idle...
+ dconf_dbus_dispatch_error ((DConfDBusAsyncReadyCallback) callback,
+ user_data, error);
+ g_error_free (error);
+ return;
}
}
@@ -634,8 +636,10 @@ dconf_set_async (const gchar *key,
if (!dconf_check_writable (mount, key, &error))
{
- g_assert_not_reached ();
- // XXX dispatch in idle...
+ dconf_dbus_dispatch_error ((DConfDBusAsyncReadyCallback) callback,
+ user_data, error);
+ g_error_free (error);
+ return;
}
}
diff --git a/dconf/dconf-dbus.c b/dconf/dconf-dbus.c
index f2d5ac7..a174eda 100644
--- a/dconf/dconf-dbus.c
+++ b/dconf/dconf-dbus.c
@@ -525,6 +525,7 @@ dconf_dbus_blocking_call (DConfDBus *bus,
typedef struct
{
DConfDBus *bus;
+ GError *error;
DConfDBusAsyncReadyCallback callback;
GMainContext *context;
DBusPendingCall *pending;
@@ -534,25 +535,43 @@ typedef struct
struct OPAQUE_TYPE__DConfDBusAsyncResult
{
DConfDBus *bus;
+ GError *error;
DBusPendingCall *pending;
};
static DConfDBusClosure *
dconf_dbus_closure_new (DConfDBus *bus,
- DConfDBusAsyncReadyCallback callback,
DBusPendingCall *pending,
+ GError *error,
+ DConfDBusAsyncReadyCallback callback,
gpointer user_data)
{
DConfDBusClosure *closure;
+ GMainContext *context;
+
+ g_assert ((error == NULL) ^ (pending == NULL));
+
+ context = g_main_context_get_thread_default ();
closure = g_slice_new (DConfDBusClosure);
closure->bus = bus;
closure->callback = callback;
- closure->pending = dbus_pending_call_ref (pending);
closure->user_data = user_data;
- closure->context = g_main_context_get_thread_default ();
- if (closure->context)
- g_main_context_ref (closure->context);
+
+ if (context)
+ closure->context = g_main_context_ref (context);
+ else
+ closure->context = NULL;
+
+ if (error)
+ closure->error = g_error_copy (error);
+ else
+ closure->error = NULL;
+
+ if (pending)
+ closure->pending = dbus_pending_call_ref (pending);
+ else
+ closure->pending = NULL;
return closure;
}
@@ -565,12 +584,17 @@ dconf_dbus_closure_fire (gpointer user_data)
result.bus = closure->bus;
result.pending = closure->pending;
+ result.error = closure->error;
closure->callback (&result, closure->user_data);
- dbus_pending_call_unref (closure->pending);
+ if (closure->pending)
+ dbus_pending_call_unref (closure->pending);
if (closure->context)
g_main_context_unref (closure->context);
+ if (closure->error)
+ g_error_free (closure->error);
+
g_slice_free (DConfDBusClosure, closure);
return FALSE;
@@ -600,8 +624,8 @@ dconf_dbus_async_call (DConfDBus *bus,
dbus_connection_send_with_reply (bus->connection, message, &pending, -1);
dbus_pending_call_set_notify (pending, dconf_dbus_async_ready,
- dconf_dbus_closure_new (bus, callback,
- pending, user_data),
+ dconf_dbus_closure_new (bus, pending, NULL,
+ callback, user_data),
NULL);
dbus_pending_call_unref (pending);
dbus_message_unref (message);
@@ -817,51 +841,71 @@ dconf_dbus_async_finish (DConfDBusAsyncResult *result,
DBusMessage *reply;
gboolean success;
- reply = dbus_pending_call_steal_reply (result->pending);
- if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
- {
- const gchar *code, *message;
- gboolean have_message;
-
- code = dbus_message_get_error_name (reply);
-
- have_message = dbus_message_get_args (reply, NULL,
- DBUS_TYPE_STRING, &message,
- DBUS_TYPE_INVALID);
-
- if (have_message)
- g_set_error (error, 0, 0, "%s: %s", code, message);
- else
- g_set_error (error, 0, 0, "DBus error: %s", code);
-
- success = FALSE;
- }
- else if (!dbus_message_has_signature (reply, signature))
+ if (result->error)
{
- g_set_error (error, 0, 0, "unexpected signature in DBus reply");
+ g_propagate_error (error, result->error);
+ result->error = NULL;
success = FALSE;
}
else
{
- if (event_id)
+ reply = dbus_pending_call_steal_reply (result->pending);
+ if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
{
- guint32 sequence;
+ const gchar *code, *message;
+ gboolean have_message;
+
+ code = dbus_message_get_error_name (reply);
+
+ have_message = dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_STRING, &message,
+ DBUS_TYPE_INVALID);
+
+ if (have_message)
+ g_set_error (error, 0, 0, "%s: %s", code, message);
+ else
+ g_set_error (error, 0, 0, "DBus error: %s", code);
- dbus_message_get_args (reply, NULL,
- DBUS_TYPE_UINT32, &sequence,
- DBUS_TYPE_INVALID);
- *event_id = dconf_dbus_format_event_id (result->bus,
- reply, sequence);
+ success = FALSE;
+ }
+ else if (!dbus_message_has_signature (reply, signature))
+ {
+ g_set_error (error, 0, 0, "unexpected signature in DBus reply");
+ success = FALSE;
+ }
+ else
+ {
+ if (event_id)
+ {
+ guint32 sequence;
+
+ dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_UINT32, &sequence,
+ DBUS_TYPE_INVALID);
+ *event_id = dconf_dbus_format_event_id (result->bus,
+ reply, sequence);
+ }
+
+ success = TRUE;
}
- success = TRUE;
+ dbus_message_unref (reply);
}
- dbus_message_unref (reply);
-
return success;
}
+void
+dconf_dbus_dispatch_error (DConfDBusAsyncReadyCallback callback,
+ gpointer user_data,
+ GError *error)
+{
+ DConfDBusClosure *closure;
+
+ closure = dconf_dbus_closure_new (NULL, NULL, error, callback, user_data);
+ g_idle_add (dconf_dbus_closure_fire, closure);
+}
+
/* ------------------------------------------------------------------------ */
/* all code past this point is for mainloop integration.
*
diff --git a/dconf/dconf-dbus.h b/dconf/dconf-dbus.h
index d9351fd..b506c22 100644
--- a/dconf/dconf-dbus.h
+++ b/dconf/dconf-dbus.h
@@ -82,6 +82,8 @@ void dconf_dbus_unwatch (DConfDB
const gchar *prefix,
DConfDBusNotify callback,
gpointer user_data);
-
+void dconf_dbus_dispatch_error (DConfDBusAsyncReadyCallback callback,
+ gpointer user_data,
+ GError *error);
#endif /* _dconf_dbus_h_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]