diff options
author | Havoc Pennington <hp@redhat.com> | 2003-04-11 00:03:06 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2003-04-11 00:03:06 +0000 |
commit | 6be547d32f018c23ba56426a0bccd08baa2cf440 (patch) | |
tree | 00edf1d2628538d66d3f5db7a998c18ffc30ce04 /bus/connection.c | |
parent | 7074a2469521949c706f3b9d789d7c8eb9f3ac85 (diff) | |
download | dbus-6be547d32f018c23ba56426a0bccd08baa2cf440.tar.gz |
2003-04-10 Havoc Pennington <hp@redhat.com>
* dbus/dbus-connection.c (dbus_connection_flush): don't spin on
the connection if it's disconnected
* bus/activation.c (bus_activation_service_created): use new
transaction features to roll back removal of pending activation if
we don't successfully create the service after all. Don't remove
pending activation if the function fails.
* dbus/dbus-list.c (_dbus_list_insert_before_link)
(_dbus_list_insert_after_link): new code to facilitate
services.c fixes
* dbus/dbus-hash.c (_dbus_hash_table_insert_string_preallocated):
new functionality, so we can preallocate the ability to insert
into a hash table.
* bus/connection.c (bus_transaction_add_cancel_hook): new function
allowing us to put custom hooks in a transaction to be used for
cancelling said transaction
* doc/dbus-specification.sgml: add some discussion of secondary
service owners, and disallow zero-length service names
* bus/services.c (bus_registry_acquire_service): new function,
splits out part of bus_driver_handle_acquire_service() and fixes
a bug where we didn't remove the service doing the acquiring
from the secondary queue if we failed to remove the current owner
from the front of the queue.
Diffstat (limited to 'bus/connection.c')
-rw-r--r-- | bus/connection.c | 113 |
1 files changed, 107 insertions, 6 deletions
diff --git a/bus/connection.c b/bus/connection.c index 80a9ae7a..2cfbeb27 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -139,6 +139,8 @@ bus_connection_disconnected (DBusConnection *connection) if (!bus_service_remove_owner (service, connection, transaction, &error)) { + _DBUS_ASSERT_ERROR_IS_SET (&error); + if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) { dbus_error_free (&error); @@ -147,7 +149,11 @@ bus_connection_disconnected (DBusConnection *connection) goto retry; } else - _dbus_assert_not_reached ("Removing service owner failed for non-memory-related reason"); + { + _dbus_verbose ("Failed to remove service owner: %s %s\n", + error.name, error.message); + _dbus_assert_not_reached ("Removing service owner failed for non-memory-related reason"); + } } bus_transaction_execute_and_free (transaction); @@ -746,19 +752,31 @@ bus_connection_send_oom_error (DBusConnection *connection, d->oom_preallocated = NULL; } -dbus_bool_t -bus_connection_add_owned_service (DBusConnection *connection, - BusService *service) +void +bus_connection_add_owned_service_link (DBusConnection *connection, + DBusList *link) { BusConnectionData *d; d = BUS_CONNECTION_DATA (connection); _dbus_assert (d != NULL); - if (!_dbus_list_append (&d->services_owned, - service)) + _dbus_list_append_link (&d->services_owned, link); +} + +dbus_bool_t +bus_connection_add_owned_service (DBusConnection *connection, + BusService *service) +{ + DBusList *link; + + link = _dbus_list_alloc_link (service); + + if (link == NULL) return FALSE; + bus_connection_add_owned_service_link (connection, link); + return TRUE; } @@ -805,6 +823,13 @@ bus_connection_get_name (DBusConnection *connection) return d->name; } +/** + * Transactions + * + * Note that this is fairly fragile; in particular, don't try to use + * one transaction across any main loop iterations. + */ + typedef struct { BusTransaction *transaction; @@ -812,10 +837,18 @@ typedef struct DBusPreallocatedSend *preallocated; } MessageToSend; +typedef struct +{ + BusTransactionCancelFunction cancel_function; + DBusFreeFunction free_data_function; + void *data; +} CancelHook; + struct BusTransaction { DBusList *connections; BusContext *context; + DBusList *cancel_hooks; }; static void @@ -831,6 +864,39 @@ message_to_send_free (DBusConnection *connection, dbus_free (to_send); } +static void +cancel_hook_cancel (void *element, + void *data) +{ + CancelHook *ch = element; + + _dbus_verbose ("Running transaction cancel hook\n"); + + if (ch->cancel_function) + (* ch->cancel_function) (ch->data); +} + +static void +cancel_hook_free (void *element, + void *data) +{ + CancelHook *ch = element; + + if (ch->free_data_function) + (* ch->free_data_function) (ch->data); + + dbus_free (ch); +} + +static void +free_cancel_hooks (BusTransaction *transaction) +{ + _dbus_list_foreach (&transaction->cancel_hooks, + cancel_hook_free, NULL); + + _dbus_list_clear (&transaction->cancel_hooks); +} + BusTransaction* bus_transaction_new (BusContext *context) { @@ -980,6 +1046,11 @@ bus_transaction_cancel_and_free (BusTransaction *transaction) _dbus_assert (transaction->connections == NULL); + _dbus_list_foreach (&transaction->cancel_hooks, + cancel_hook_cancel, NULL); + + free_cancel_hooks (transaction); + dbus_free (transaction); } @@ -1036,6 +1107,8 @@ bus_transaction_execute_and_free (BusTransaction *transaction) _dbus_assert (transaction->connections == NULL); + free_cancel_hooks (transaction); + dbus_free (transaction); } @@ -1090,3 +1163,31 @@ bus_transaction_send_error_reply (BusTransaction *transaction, return TRUE; } + +dbus_bool_t +bus_transaction_add_cancel_hook (BusTransaction *transaction, + BusTransactionCancelFunction cancel_function, + void *data, + DBusFreeFunction free_data_function) +{ + CancelHook *ch; + + ch = dbus_new (CancelHook, 1); + if (ch == NULL) + return FALSE; + + ch->cancel_function = cancel_function; + ch->data = data; + ch->free_data_function = free_data_function; + + /* It's important that the hooks get run in reverse order that they + * were added + */ + if (!_dbus_list_prepend (&transaction->cancel_hooks, ch)) + { + dbus_free (ch); + return FALSE; + } + + return TRUE; +} |