*/
static DBusList *clients = NULL;
-static void
+static dbus_bool_t
client_watch_callback (DBusWatch *watch,
unsigned int condition,
void *data)
{
DBusConnection *connection = data;
-
+ dbus_bool_t retval;
+
dbus_connection_ref (connection);
- dbus_connection_handle_watch (connection, watch, condition);
+ retval = dbus_connection_handle_watch (connection, watch, condition);
dbus_connection_unref (connection);
+
+ return retval;
}
static dbus_bool_t
DBusConnection *connection = data;
dbus_connection_ref (connection);
-
+
+ /* can return FALSE on OOM but we just let it fire again later */
dbus_timeout_handle (timeout);
dbus_connection_unref (connection);
}
static int handler_slot = -1;
+static int handler_slot_refcount = 0;
+
+static dbus_bool_t
+handler_slot_ref (void)
+{
+ if (handler_slot < 0)
+ {
+ handler_slot = dbus_connection_allocate_data_slot ();
+
+ if (handler_slot < 0)
+ return FALSE;
+
+ _dbus_assert (handler_slot_refcount == 0);
+ }
+
+ handler_slot_refcount += 1;
+
+ return TRUE;
+
+}
+
+static void
+handler_slot_unref (void)
+{
+ _dbus_assert (handler_slot_refcount > 0);
+
+ handler_slot_refcount -= 1;
+
+ if (handler_slot_refcount == 0)
+ {
+ dbus_connection_free_data_slot (handler_slot);
+ handler_slot = -1;
+ }
+}
+
+static void
+free_handler (void *data)
+{
+ DBusMessageHandler *handler = data;
+
+ dbus_message_handler_unref (handler);
+ handler_slot_unref ();
+}
dbus_bool_t
bus_setup_debug_client (DBusConnection *connection)
DBusMessageHandler *disconnect_handler;
const char *to_handle[] = { DBUS_MESSAGE_LOCAL_DISCONNECT };
dbus_bool_t retval;
-
- if (handler_slot < 0)
- handler_slot = dbus_connection_allocate_data_slot ();
- if (handler_slot < 0)
- return FALSE;
disconnect_handler = dbus_message_handler_new (client_disconnect_handler,
NULL, NULL);
if (!_dbus_list_append (&clients, connection))
goto out;
- /* Set up handler to be destroyed */
+ if (!handler_slot_ref ())
+ goto out;
+
+ /* Set up handler to be destroyed */
if (!dbus_connection_set_data (connection, handler_slot,
disconnect_handler,
- (DBusFreeFunction)
- dbus_message_handler_unref))
- goto out;
+ free_handler))
+ {
+ handler_slot_unref ();
+ goto out;
+ }
retval = TRUE;
return FALSE;
}
+void
+bus_test_flush_bus (BusContext *context)
+{
+ /* This is race condition city, obviously. since we're all in one
+ * process we can't block, we just have to wait for data we put in
+ * one end of the debug pipe to come out the other end...
+ * a more robust setup would be good. Blocking on the other
+ * end of pipes we've pushed data into or something.
+ * A simple hack might be to just make the debug server always
+ * poll for read on the other end of the pipe after writing.
+ */
+ while (bus_loop_iterate (FALSE))
+ ;
+#if 0
+ _dbus_sleep_milliseconds (15);
+#endif
+ while (bus_loop_iterate (FALSE))
+ ;
+}
+
+BusContext*
+bus_context_new_test (const DBusString *test_data_dir,
+ const char *filename)
+{
+ DBusError error;
+ DBusString config_file;
+ DBusString relative;
+ BusContext *context;
+
+ if (!_dbus_string_init (&config_file))
+ {
+ _dbus_warn ("No memory\n");
+ return NULL;
+ }
+
+ if (!_dbus_string_copy (test_data_dir, 0,
+ &config_file, 0))
+ {
+ _dbus_warn ("No memory\n");
+ _dbus_string_free (&config_file);
+ return NULL;
+ }
+
+ _dbus_string_init_const (&relative, filename);
+
+ if (!_dbus_concat_dir_and_file (&config_file, &relative))
+ {
+ _dbus_warn ("No memory\n");
+ _dbus_string_free (&config_file);
+ return NULL;
+ }
+
+ dbus_error_init (&error);
+ context = bus_context_new (&config_file, &error);
+ if (context == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (&error);
+
+ _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n",
+ filename, error.message);
+
+ dbus_error_free (&error);
+
+ _dbus_string_free (&config_file);
+
+ return NULL;
+ }
+
+ _dbus_string_free (&config_file);
+
+ return context;
+}
+
#endif