Commit 93f433a1 authored by Richard Hult's avatar Richard Hult

2004-03-16 Richard Hult <richard@imendio.com>

	* bus/activation.c: (bus_activation_service_created),
	(bus_activation_send_pending_auto_activation_messages),
	(bus_activation_activate_service):
	* bus/activation.h:
	* bus/dispatch.c: (bus_dispatch),
	(check_nonexistent_service_auto_activation),
	(check_service_auto_activated),
	(check_segfault_service_auto_activation),
	(check_existent_service_auto_activation), (bus_dispatch_test):
	* bus/driver.c: (bus_driver_handle_activate_service):
	* bus/services.c: (bus_registry_acquire_service):
	* dbus/dbus-message.c: (dbus_message_set_auto_activation),
	(dbus_message_get_auto_activation):
	* dbus/dbus-message.h:
	* dbus/dbus-protocol.h: Implement auto-activation.
parent 24ffe79c
2004-03-16 Richard Hult <richard@imendio.com>
* bus/activation.c: (bus_activation_service_created),
(bus_activation_send_pending_auto_activation_messages),
(bus_activation_activate_service):
* bus/activation.h:
* bus/dispatch.c: (bus_dispatch),
(check_nonexistent_service_auto_activation),
(check_service_auto_activated),
(check_segfault_service_auto_activation),
(check_existent_service_auto_activation), (bus_dispatch_test):
* bus/driver.c: (bus_driver_handle_activate_service):
* bus/services.c: (bus_registry_acquire_service):
* dbus/dbus-message.c: (dbus_message_set_auto_activation),
(dbus_message_get_auto_activation):
* dbus/dbus-message.h:
* dbus/dbus-protocol.h: Implement auto-activation.
* doc/dbus-specification.xml: Add auto-activation to the spec.
2004-03-12 Olivier Andrieu <oliv__a@users.sourceforge.net>
* dbus/dbus-marshal.c (_dbus_marshal_get_arg_end_pos):
......
......@@ -76,6 +76,8 @@ struct BusPendingActivationEntry
{
DBusMessage *activation_message;
DBusConnection *connection;
dbus_bool_t auto_activation;
};
typedef struct
......@@ -904,30 +906,90 @@ bus_activation_service_created (BusActivation *activation,
if (dbus_connection_get_is_connected (entry->connection))
{
message = dbus_message_new_method_return (entry->activation_message);
if (!message)
{
BUS_SET_OOM (error);
goto error;
}
if (!dbus_message_append_args (message,
DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ACTIVATED,
DBUS_TYPE_INVALID))
/* Only send activation replies to regular activation requests. */
if (!entry->auto_activation)
{
message = dbus_message_new_method_return (entry->activation_message);
if (!message)
{
BUS_SET_OOM (error);
goto error;
}
if (!dbus_message_append_args (message,
DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ACTIVATED,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
BUS_SET_OOM (error);
goto error;
}
if (!bus_transaction_send_from_driver (transaction, entry->connection, message))
{
dbus_message_unref (message);
BUS_SET_OOM (error);
goto error;
}
dbus_message_unref (message);
BUS_SET_OOM (error);
goto error;
}
if (!bus_transaction_send_from_driver (transaction, entry->connection, message))
}
link = next;
}
return TRUE;
error:
return FALSE;
}
dbus_bool_t
bus_activation_send_pending_auto_activation_messages (BusActivation *activation,
BusService *service,
BusTransaction *transaction,
DBusError *error)
{
BusPendingActivation *pending_activation;
DBusList *link;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
/* Check if it's a pending activation */
pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations,
bus_service_get_name (service));
if (!pending_activation)
return TRUE;
link = _dbus_list_get_first_link (&pending_activation->entries);
while (link != NULL)
{
BusPendingActivationEntry *entry = link->data;
DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
if (entry->auto_activation && dbus_connection_get_is_connected (entry->connection))
{
DBusConnection *addressed_recipient;
addressed_recipient = bus_service_get_primary_owner (service);
/* Check the security policy, which has the side-effect of adding an
* expected pending reply.
*/
if (!bus_context_check_security_policy (activation->context, transaction,
entry->connection,
addressed_recipient,
addressed_recipient,
entry->activation_message, error))
goto error;
if (!bus_transaction_send (transaction, addressed_recipient, entry->activation_message))
{
dbus_message_unref (message);
BUS_SET_OOM (error);
goto error;
}
dbus_message_unref (message);
}
link = next;
......@@ -940,7 +1002,7 @@ bus_activation_service_created (BusActivation *activation,
goto error;
}
_dbus_hash_table_remove_string (activation->pending_activations, service_name);
_dbus_hash_table_remove_string (activation->pending_activations, bus_service_get_name (service));
return TRUE;
......@@ -1225,6 +1287,7 @@ dbus_bool_t
bus_activation_activate_service (BusActivation *activation,
DBusConnection *connection,
BusTransaction *transaction,
dbus_bool_t auto_activation,
DBusMessage *activation_message,
const char *service_name,
DBusError *error)
......@@ -1300,6 +1363,8 @@ bus_activation_activate_service (BusActivation *activation,
return FALSE;
}
pending_activation_entry->auto_activation = auto_activation;
pending_activation_entry->activation_message = activation_message;
dbus_message_ref (activation_message);
pending_activation_entry->connection = connection;
......
......@@ -29,21 +29,28 @@
#include "bus.h"
BusActivation* bus_activation_new (BusContext *context,
const DBusString *address,
DBusList **directories,
DBusError *error);
const DBusString *address,
DBusList **directories,
DBusError *error);
BusActivation* bus_activation_ref (BusActivation *activation);
void bus_activation_unref (BusActivation *activation);
dbus_bool_t bus_activation_activate_service (BusActivation *activation,
DBusConnection *connection,
BusTransaction *transaction,
DBusMessage *activation_message,
const char *service_name,
DBusError *error);
DBusConnection *connection,
BusTransaction *transaction,
dbus_bool_t auto_activation,
DBusMessage *activation_message,
const char *service_name,
DBusError *error);
dbus_bool_t bus_activation_service_created (BusActivation *activation,
const char *service_name,
BusTransaction *transaction,
DBusError *error);
const char *service_name,
BusTransaction *transaction,
DBusError *error);
dbus_bool_t bus_activation_send_pending_auto_activation_messages (BusActivation *activation,
BusService *service,
BusTransaction *transaction,
DBusError *error);
#endif /* BUS_ACTIVATION_H */
This diff is collapsed.
......@@ -587,7 +587,7 @@ bus_driver_handle_activate_service (DBusConnection *connection,
retval = FALSE;
if (!bus_activation_activate_service (activation, connection, transaction,
if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
message, name, error))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
......
......@@ -262,6 +262,7 @@ bus_registry_acquire_service (BusRegistry *registry,
DBusConnection *current_owner;
BusClientPolicy *policy;
BusService *service;
BusActivation *activation;
retval = FALSE;
......@@ -376,7 +377,11 @@ bus_registry_acquire_service (BusRegistry *registry,
*result = DBUS_SERVICE_REPLY_PRIMARY_OWNER;
}
retval = TRUE;
activation = bus_context_get_activation (registry->context);
retval = bus_activation_send_pending_auto_activation_messages (activation,
service,
transaction,
error);
out:
return retval;
......
......@@ -4387,6 +4387,35 @@ dbus_message_get_no_reply (DBusMessage *message)
return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0;
}
void
dbus_message_set_auto_activation (DBusMessage *message,
dbus_bool_t auto_activation)
{
char *header;
_dbus_return_if_fail (message != NULL);
_dbus_return_if_fail (!message->locked);
header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
if (auto_activation)
*header |= DBUS_HEADER_FLAG_AUTO_ACTIVATION;
else
*header &= ~DBUS_HEADER_FLAG_AUTO_ACTIVATION;
}
dbus_bool_t
dbus_message_get_auto_activation (DBusMessage *message)
{
const char *header;
_dbus_return_val_if_fail (message != NULL, FALSE);
header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
return (*header & DBUS_HEADER_FLAG_AUTO_ACTIVATION) != 0;
}
/**
* Gets the service which originated this message,
* or #NULL if unknown or inapplicable.
......
......@@ -119,6 +119,10 @@ dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message,
dbus_uint32_t reply_serial);
dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message);
void dbus_message_set_auto_activation (DBusMessage *message,
dbus_bool_t auto_activation);
dbus_bool_t dbus_message_get_auto_activation (DBusMessage *message);
dbus_bool_t dbus_message_get_path_decomposed (DBusMessage *message,
char ***path);
......
......@@ -72,6 +72,7 @@ extern "C" {
/* Header flags */
#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1
#define DBUS_HEADER_FLAG_AUTO_ACTIVATION 0x2
/* Header fields */
#define DBUS_HEADER_FIELD_INVALID 0
......
......@@ -249,6 +249,12 @@
optimization. However, it is compliant with this specification
to return the reply despite this flag.</entry>
</row>
<row>
<entry>AUTO_ACTIVATION</entry>
<entry>0x2</entry>
<entry>This message automatically activates the
addressed service before the message is delivered.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
......@@ -674,6 +680,13 @@
However, it is also acceptable to ignore the NO_REPLY_EXPECTED
flag and reply anyway.
</para>
<para>
If a message has the flag AUTO_ACTIVATION, then the addressed
service will be activated before the message is delivered, if
not already active. The message will be held until the service
is successfully activated or has failed to activate; in case
of failure, an activation error will be returned.
</para>
<sect4 id="message-protocol-types-method-apis">
<title>Mapping method calls to native APIs</title>
<para>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment