summaryrefslogtreecommitdiffstats
path: root/bus/driver.c
diff options
context:
space:
mode:
authorJohn (J5) Palmieri <johnp@redhat.com>2005-11-22 20:37:00 +0000
committerJohn (J5) Palmieri <johnp@redhat.com>2005-11-22 20:37:00 +0000
commit1a163e765c0d6a86d2aa2ffb18a1d7e29a052e7a (patch)
treef03b91de2eea70ffcb02aebcb265e3552dd9e48d /bus/driver.c
parentc33af17b934fcc8528b393ed2dca603e4940e6b3 (diff)
* configure.in: Add test/name-test/Makefile to the generated
Makefile list * dbus/dbus-shared.h (#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT): New flag which replaces DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT (#define DBUS_NAME_FLAG_DO_NOT_QUEUE): New flag for specifying not to queue an ower if it can't be the primary owner * bus/bus.h: Add new internal BusOwner struct * bus/driver.c (bus_driver_handle_hello): Send flags (0 for default) to bus_registry_ensure and don't set the prohibit_replacement flag since they are now set per BusOwner and not per name. (bus_driver_handle_list_queued_owners): bus method (ListQueuedOwners) that returns the list of connections in a name's connection queue * bus/services.c (struct BusService): remove prohibit_replacement field (struct BusOwner): new struct for keeping track of queued connections and their associated flags for the queue (struct BusRegistry): add a BusOwner memory pool (bus_registry_new): initialize the BusOwner memory pool (bus_registry_unref): free the BusOwner memory pool (_bus_service_find_owner_link): new internal method for searching the queue for a specific connection (bus_owner_set_flags): new method for adding setting the flags on a bus owner (bus_owner_new): new method that creates a BusOwner object from the pool and sets its flags (bus_owner_ref, bus_owner_unref): ref counting for BusOwner objects (bus_registry_ensure): Add the flags parameter (bus_registry_acquire_service): Switch from using raw connections to using the BusOwner struct Add new state machine for dealing with the new set of flags (bus_registry_set_service_context_table, struct OwnershipCancelData, cancel_ownership, free_ownership_cancel_data, add_cancel_ownership_to_transaction, struct OwnershipRestoreData, restore_ownership, free_ownership_restore_data, add_restore_ownership_to_transaction): Switch to using BusOwner instead of raw connections (bus_service_add_owner): Add flags parameter Switch to using BusOwner instead of raw connections Add state machine for dealing with the new set of flags (bus_service_swap_owner): Swaps the first and second owners in the queue. Used to make sure proper signals are sent when a service looses or gains primary ownership. We never insert an owner at the top of the queue. Instead we insert it in the second position and then swap. (bus_service_remove_owner): Remove the owner from the queue sending out the NameLost and NameOwnerChanged signals if the we were the primary owner (bus_service_get_primary_owners_connection): New method that extracts the connection from the primary owner (bus_service_get_primary_owner): Returns the BusOwner instead of the connection (bus_service_get_allow_replacement): Changed from the old bus_service_get_prohibit_replacement method. Checks the flags of the primary owner and returns if it can be replaced or not (bus_service_set_prohibit_replacement): removed (bus_service_has_owner): returns TRUE if and owner with the specified connection exists in the queue * dbus/dbus-bus.c (dbus_bus_connection_get_unique_name): New helper method that only compiles if tests are enabled. Allows us to get the unique name of a connection so we can check it against the queue when doing regression tests * bus/activation.c (bus_activation_send_pending_auto_activate), bus/dispatch.c (bus_dispatch), bus/driver.c (bus_driver_handle_get_service_owner, bus_driver_handle_get_connection_unix_user, bus_driver_handle_get_connection_unix_process_id, bus_driver_handle_get_connection_selinux_security_context), bus/signals.c (connection_is_primary_owner): use bus_service_get_primary_owners_connection instead of bus_service_get_primary_owner * dbus/dbus-sysdeps.c (_dbus_connect_unix_socket, _dbus_listen_unix_socket): Calculate the length of the socket path and use that instead of using a fixed length which was causing socket names to contain many trailing Nul bytes. * dbus/dbus-glib-lowlevel.h, glib/dbus-gobject.c (dbus_g_method_get_sender): New method for extracting the sender from a DBusGMethodInvocation (dbus_g_method_return_get_reply): changed name to dbus_g_method_get_reply (dbus_g_method_return_send_reply): changed name to dbus_g_method_send reply * doc/dbus-specification.xml: New docs that describe how the new queueing system works and talks about the changes to the how we specify socket names * glib/examples/example-service.c, glib/examples/example-signal-emitter.c, glib/examples/statemachine/statemachine-server.c: Changed the RequestName flags to the new system * test/name-test/ (test-names.c, run-test.sh, Makefile.am): New regression test suite for testing various states of the new queueing system
Diffstat (limited to 'bus/driver.c')
-rw-r--r--bus/driver.c123
1 files changed, 116 insertions, 7 deletions
diff --git a/bus/driver.c b/bus/driver.c
index bc63e7c2..10f37bd2 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -308,12 +308,10 @@ bus_driver_handle_hello (DBusConnection *connection,
/* Create the service */
service = bus_registry_ensure (registry,
- &unique_name, connection, transaction, error);
+ &unique_name, connection, 0, transaction, error);
if (service == NULL)
goto out_0;
- bus_service_set_prohibit_replacement (service, TRUE);
-
_dbus_assert (bus_connection_is_active (connection));
retval = TRUE;
@@ -883,7 +881,7 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,
}
else
{
- base_name = bus_connection_get_name (bus_service_get_primary_owner (service));
+ base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service));
if (base_name == NULL)
{
/* FIXME - how is this error possible? */
@@ -924,6 +922,113 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,
}
static dbus_bool_t
+bus_driver_handle_list_queued_owners (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ const char *text;
+ DBusList *base_names;
+ DBusList *link;
+ DBusString str;
+ BusRegistry *registry;
+ BusService *service;
+ DBusMessage *reply;
+ DBusMessageIter iter, array_iter;
+ char *dbus_service_name = DBUS_SERVICE_DBUS;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ registry = bus_connection_get_registry (connection);
+
+ base_names = NULL;
+ text = NULL;
+ reply = NULL;
+
+ if (! dbus_message_get_args (message, error,
+ DBUS_TYPE_STRING, &text,
+ DBUS_TYPE_INVALID))
+ goto failed;
+
+ _dbus_string_init_const (&str, text);
+ service = bus_registry_lookup (registry, &str);
+ if (service == NULL &&
+ _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS))
+ {
+ /* ORG_FREEDESKTOP_DBUS owns itself */
+ if (! _dbus_list_append (&base_names, dbus_service_name))
+ goto oom;
+ }
+ else if (service == NULL)
+ {
+ dbus_set_error (error,
+ DBUS_ERROR_NAME_HAS_NO_OWNER,
+ "Could not get owners of name '%s': no such name", text);
+ goto failed;
+ }
+ else
+ {
+ if (!bus_service_list_queued_owners (service,
+ &base_names,
+ error))
+ goto failed;
+ }
+
+ _dbus_assert (base_names != NULL);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ goto oom;
+
+ dbus_message_iter_init_append (reply, &iter);
+ if (!dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &array_iter))
+ goto oom;
+
+ link = _dbus_list_get_first_link (&base_names);
+ while (link != NULL)
+ {
+ char *uname;
+
+ _dbus_assert (link->data != NULL);
+ uname = (char *)link->data;
+
+ if (!dbus_message_iter_append_basic (&array_iter,
+ DBUS_TYPE_STRING,
+ &uname))
+ goto oom;
+
+ link = _dbus_list_get_next_link (&base_names, link);
+ }
+
+ if (! dbus_message_iter_close_container (&iter, &array_iter))
+ goto oom;
+
+
+ if (! bus_transaction_send_from_driver (transaction, connection, reply))
+ goto oom;
+
+ dbus_message_unref (reply);
+
+ return TRUE;
+
+ oom:
+ BUS_SET_OOM (error);
+
+ failed:
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ if (reply)
+ dbus_message_unref (reply);
+
+ if (base_names)
+ _dbus_list_clear (&base_names);
+
+ return FALSE;
+}
+
+static dbus_bool_t
bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
BusTransaction *transaction,
DBusMessage *message,
@@ -962,7 +1067,7 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
goto failed;
}
- conn = bus_service_get_primary_owner (serv);
+ conn = bus_service_get_primary_owners_connection (serv);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
@@ -1038,7 +1143,7 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
goto failed;
}
- conn = bus_service_get_primary_owner (serv);
+ conn = bus_service_get_primary_owners_connection (serv);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
@@ -1113,7 +1218,7 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne
goto failed;
}
- conn = bus_service_get_primary_owner (serv);
+ conn = bus_service_get_primary_owners_connection (serv);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
@@ -1235,6 +1340,10 @@ struct
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_STRING_AS_STRING,
bus_driver_handle_get_service_owner },
+ { "ListQueuedOwners",
+ DBUS_TYPE_STRING_AS_STRING,
+ DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
+ bus_driver_handle_list_queued_owners },
{ "GetConnectionUnixUser",
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_UINT32_AS_STRING,