summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2011-03-09 15:10:27 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2011-03-09 15:10:27 +0000
commitcf7f29846557636aee7903aab8cd24cb5ea97691 (patch)
treec6cf9deba90f07d578ee4ce8b75a11983031b3fb
parent65ed81add89a6dfea01b255dd401190f9dc9cf89 (diff)
-rw-r--r--bus/dispatch.c29
-rw-r--r--dbus/dbus-bus.c50
-rw-r--r--dbus/dbus-connection.c78
-rw-r--r--dbus/dbus-connection.h6
-rw-r--r--tools/dbus-spam.c2
5 files changed, 119 insertions, 46 deletions
diff --git a/bus/dispatch.c b/bus/dispatch.c
index a80476cd..05b44362 100644
--- a/bus/dispatch.c
+++ b/bus/dispatch.c
@@ -259,21 +259,30 @@ bus_dispatch (DBusConnection *connection,
/* Assign a sender to the message */
if (bus_connection_is_active (connection))
{
+ const char *old_sender;
+
sender = bus_connection_get_name (connection);
_dbus_assert (sender != NULL);
- if (!dbus_message_set_sender (message, sender))
+ /* hopefully the sending connection already got this right - if it did,
+ * we can skip resetting it, saving a realloc */
+ old_sender = dbus_message_get_sender (message);
+
+ if (old_sender == NULL || strcmp (old_sender, sender) != 0)
{
- BUS_SET_OOM (&error);
- goto out;
- }
+ if (!dbus_message_set_sender (message, sender))
+ {
+ BUS_SET_OOM (&error);
+ goto out;
+ }
- /* We need to refetch the service name here, because
- * dbus_message_set_sender can cause the header to be
- * reallocated, and thus the service_name pointer will become
- * invalid.
- */
- service_name = dbus_message_get_destination (message);
+ /* We need to refetch the service name here, because
+ * dbus_message_set_sender can cause the header to be
+ * reallocated, and thus the service_name pointer will become
+ * invalid.
+ */
+ service_name = dbus_message_get_destination (message);
+ }
}
if (service_name &&
diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c
index 9218e12e..90ccc6d0 100644
--- a/dbus/dbus-bus.c
+++ b/dbus/dbus-bus.c
@@ -76,7 +76,6 @@
typedef struct
{
DBusConnection *connection; /**< Connection we're associated with */
- char *unique_name; /**< Unique name of this connection */
unsigned int is_well_known : 1; /**< Is one of the well-known connections in our global array */
} BusData;
@@ -347,7 +346,6 @@ bus_data_free (void *data)
_DBUS_UNLOCK (bus);
}
- dbus_free (bd->unique_name);
dbus_free (bd);
dbus_connection_free_data_slot (&bus_data_slot);
@@ -653,7 +651,7 @@ dbus_bus_register (DBusConnection *connection,
DBusError *error)
{
DBusMessage *message, *reply;
- char *name;
+ const char *name;
BusData *bd;
dbus_bool_t retval;
@@ -673,10 +671,12 @@ dbus_bus_register (DBusConnection *connection,
goto out;
}
- if (bd->unique_name != NULL)
+ name = dbus_connection_get_sender (connection);
+
+ if (name != NULL)
{
_dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
- bd->unique_name);
+ name);
/* Success! */
retval = TRUE;
goto out;
@@ -704,8 +704,7 @@ dbus_bus_register (DBusConnection *connection,
DBUS_TYPE_INVALID))
goto out;
- bd->unique_name = _dbus_strdup (name);
- if (bd->unique_name == NULL)
+ if (!dbus_connection_set_sender (connection, name))
{
_DBUS_SET_OOM (error);
goto out;
@@ -732,7 +731,8 @@ dbus_bus_register (DBusConnection *connection,
/**
* Sets the unique name of the connection, as assigned by the message
* bus. Can only be used if you registered with the bus manually
- * (i.e. if you did not call dbus_bus_register()). Can only be called
+ * (i.e. if you did not call dbus_bus_register()). You can only call
+ * either dbus_bus_set_unique_name() or dbus_connection_set_sender()
* once per connection. After the unique name is set, you can get it
* with dbus_bus_get_unique_name().
*
@@ -767,26 +767,16 @@ dbus_bool_t
dbus_bus_set_unique_name (DBusConnection *connection,
const char *unique_name)
{
- BusData *bd;
- dbus_bool_t success = FALSE;
+ dbus_bool_t success;
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (unique_name != NULL, FALSE);
+ _dbus_return_val_if_fail (dbus_connection_get_sender (connection) != NULL, FALSE);
_DBUS_LOCK (bus_datas);
-
- bd = ensure_bus_data (connection);
- if (bd == NULL)
- goto out;
-
- _dbus_assert (bd->unique_name == NULL);
-
- bd->unique_name = _dbus_strdup (unique_name);
- success = bd->unique_name != NULL;
-
-out:
+ success = dbus_connection_set_sender (connection, unique_name);
_DBUS_UNLOCK (bus_datas);
-
+
return success;
}
@@ -799,9 +789,9 @@ out:
* The name remains valid until the connection is freed, and
* should not be freed by the caller.
*
- * Other than dbus_bus_get(), there are two ways to set the unique
- * name; one is dbus_bus_register(), the other is
- * dbus_bus_set_unique_name(). You are responsible for calling
+ * Other than dbus_bus_get(), there are three ways to set the unique
+ * name: dbus_bus_register(), dbus_bus_set_unique_name() and
+ * dbus_connection_set_sender(). You are responsible for calling
* dbus_bus_set_unique_name() if you register by hand instead of using
* dbus_bus_register().
*
@@ -811,20 +801,12 @@ out:
const char*
dbus_bus_get_unique_name (DBusConnection *connection)
{
- BusData *bd;
const char *unique_name = NULL;
_dbus_return_val_if_fail (connection != NULL, NULL);
_DBUS_LOCK (bus_datas);
-
- bd = ensure_bus_data (connection);
- if (bd == NULL)
- goto out;
-
- unique_name = bd->unique_name;
-
-out:
+ unique_name = dbus_connection_get_sender (connection);
_DBUS_UNLOCK (bus_datas);
return unique_name;
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index 79c8fc9e..4ccfa40a 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -289,6 +289,7 @@ struct DBusConnection
DBusObjectTree *objects; /**< Object path handlers registered with this connection */
char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */
+ char *sender; /**< If not NULL, set this as the sender for all messages */
/* These two MUST be bools and not bitfields, because they are protected by a separate lock
* from connection->mutex and all bitfields in a word have to be read/written together.
@@ -1992,7 +1993,7 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con
dbus_free (preallocated);
preallocated = NULL;
-
+
dbus_message_ref (message);
connection->n_outgoing += 1;
@@ -2031,7 +2032,15 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con
_dbus_verbose ("Message %p serial is %u\n",
message, dbus_message_get_serial (message));
-
+
+ /* If we're a connection to a bus, or have otherwise been told to force a
+ * sender, try to set the message's sender before we send it: this saves a
+ * realloc (and moving memory around) in dbus-daemon. If we fail due to OOM,
+ * never mind; that just moves the message onto a slower path in the bus
+ * daemon. */
+ if (connection->sender != NULL)
+ dbus_message_set_sender (message, connection->sender);
+
dbus_message_lock (message);
/* Now we need to run an iteration to hopefully just write the messages
@@ -6048,6 +6057,71 @@ dbus_connection_set_max_message_size (DBusConnection *connection,
}
/**
+ * Sets a sender unique name to be used for all messages sent by this
+ * connection. dbus_bus_register() and dbus_bus_set_unique_name() both
+ * set this automatically.
+ *
+ * @param connection a #DBusConnection
+ * @param sender the sending name to use for all messages, or #NULL to not change the sender
+ * @returns #TRUE if there was enough memory to change the sender
+ */
+dbus_bool_t
+dbus_connection_set_sender (DBusConnection *connection,
+ const char *sender)
+{
+ dbus_bool_t res = TRUE;
+
+ _dbus_return_if_fail (connection != NULL);
+
+ CONNECTION_LOCK (connection);
+
+ if (sender == NULL)
+ {
+ dbus_free (connection->sender);
+ connection->sender = NULL;
+ }
+ else if (connection->sender == NULL ||
+ strcmp (sender, connection->sender) != 0)
+ {
+ char *copy;
+
+ copy = _dbus_strdup (sender);
+
+ if (copy == NULL)
+ {
+ res = FALSE;
+ goto out;
+ }
+
+ dbus_free (connection->sender);
+ connection->sender = copy;
+ }
+
+out:
+ CONNECTION_UNLOCK (connection);
+ return res;
+}
+
+/**
+ * Get whether a non-#NULL sender has been set with dbus_connection_set_sender().
+ *
+ * @returns #TRUE if dbus_connection_set_sender() has been used to set a non-#NULL sender
+ */
+dbus_bool_t
+dbus_connection_has_sender (DBusConnection *connection)
+{
+ dbus_bool_t has;
+
+ _dbus_return_val_if_fail (connection != NULL, NULL);
+
+ CONNECTION_LOCK (connection);
+ has = connection->sender;
+ CONNECTION_UNLOCK (connection);
+
+ return has;
+}
+
+/**
* Gets the value set by dbus_connection_set_max_message_size().
*
* @param connection the connection
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index 3e2a7d8d..50afe609 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -346,6 +346,12 @@ DBUS_EXPORT
long dbus_connection_get_outgoing_unix_fds (DBusConnection *connection);
DBUS_EXPORT
+const char *dbus_connection_get_sender (DBusConnection *connection);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_set_sender (DBusConnection *connection,
+ const char *sender);
+
+DBUS_EXPORT
DBusPreallocatedSend* dbus_connection_preallocate_send (DBusConnection *connection);
DBUS_EXPORT
void dbus_connection_free_preallocated_send (DBusConnection *connection,
diff --git a/tools/dbus-spam.c b/tools/dbus-spam.c
index ab886354..6572f0e9 100644
--- a/tools/dbus-spam.c
+++ b/tools/dbus-spam.c
@@ -294,6 +294,8 @@ main (int argc, char **argv)
payload_len = strlen (payload);
}
+ srand (seed);
+
VERBOSE (stderr, "Will send up to %d messages, with up to %d queued\n",
count, queue_len);