summaryrefslogtreecommitdiff
path: root/gdbus
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2012-07-05 23:34:54 -0400
committerRyan Lortie <desrt@desrt.ca>2012-07-06 00:19:44 -0400
commitc700f20b765fc7324c14707607603615e93ec37a (patch)
tree8d9657a0ffb9f044cc9023c4a214696582f1ca9f /gdbus
parentdbf4f8cd7fd1804ec4bfb6780a6cc01d7feaf45b (diff)
downloaddconf-c700f20b765fc7324c14707607603615e93ec37a.tar.gz
GDBus filter backend: fix reply-serial handling
The handling of the reply serial number in the filter-based GDBus backend (disabled by default) was incorrect. This fixes it.
Diffstat (limited to 'gdbus')
-rw-r--r--gdbus/dconf-gdbus-filter.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/gdbus/dconf-gdbus-filter.c b/gdbus/dconf-gdbus-filter.c
index d0c0654..09ff43d 100644
--- a/gdbus/dconf-gdbus-filter.c
+++ b/gdbus/dconf-gdbus-filter.c
@@ -63,7 +63,7 @@ dconf_gdbus_handle_reply (ConnectionState *state,
DConfGDBusCall *call;
call = g_queue_pop_head (&state->queue);
- g_assert_cmpuint (g_dbus_message_get_serial (message), ==, call->serial);
+ g_assert_cmpuint (g_dbus_message_get_reply_serial (message), ==, call->serial);
handle = call->handle;
g_slice_free (DConfGDBusCall, call);
@@ -223,36 +223,49 @@ dconf_engine_dbus_call_async_func (GBusType bus_type,
g_dbus_message_set_body (message, parameters);
g_mutex_lock (&dconf_gdbus_lock);
+ {
+ volatile guint *serial_ptr;
+ guint my_serial;
+
+ /* We need to set the serial in call->serial. Sometimes we also
+ * need to set it in state->waiting_for_serial (in the case that no
+ * other items are queued yet).
+ *
+ * g_dbus_connection_send_message() only has one out_serial parameter
+ * so we can only set one of them atomically. If needed, we elect
+ * to set the waiting_for_serial because that is the one that is
+ * accessed from the filter function without holding the lock.
+ *
+ * The serial number in the call structure is only accessed after the
+ * lock is acquired which allows us to take our time setting it (for
+ * as long as we're still holding the lock).
+ *
+ * In the case that waiting_for_serial should not be set we just use
+ * a local variable and use that to fill call->serial.
+ *
+ * Also: the queue itself isn't accessed until after the lock is
+ * taken, so we can delay adding the call to the queue until we know
+ * that the sending of the message was successful.
+ */
+
+ if (g_queue_is_empty (&state->queue))
+ serial_ptr = &state->waiting_for_serial;
+ else
+ serial_ptr = &my_serial;
- /* We need to set the serial in two places: state->waiting_for_serial
- * and call->serial.
- *
- * g_dbus_connection_send_message() only has one out_serial parameter
- * so we can only set one of them atomically. We elect to set the
- * waiting_for_serial because that is the one that is accessed from
- * the filter function without holding the lock.
- *
- * The serial number in the call structure is only accessed after the
- * lock is acquired which allows us to take our time setting it (for
- * as long as we're still holding the lock).
- *
- * Also: the queue itself isn't accessed until after the lock is
- * taken, so we can delay adding the call to the queue until we know
- * that the sending of the message was successful.
- */
- success = g_dbus_connection_send_message (connection_state_get_connection (state), message,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE, &state->waiting_for_serial, error);
-
- if (success)
- {
- call = g_slice_new (DConfGDBusCall);
+ success = g_dbus_connection_send_message (connection_state_get_connection (state), message,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE, serial_ptr, error);
- call->handle = handle;
- call->serial = state->waiting_for_serial;
+ if (success)
+ {
+ call = g_slice_new (DConfGDBusCall);
- g_queue_push_tail (&state->queue, call);
- }
+ call->handle = handle;
+ call->serial = *serial_ptr;
+ g_queue_push_tail (&state->queue, call);
+ }
+ }
g_mutex_unlock (&dconf_gdbus_lock);
return success;