static void verify_list (DBusList **list) { DBusList *link; int length; link = *list; if (link == NULL) return; if (link->next == link) { _dbus_assert (link->prev == link); _dbus_assert (*list == link); return; } length = 0; do { length += 1; _dbus_assert (link->prev->next == link); _dbus_assert (link->next->prev == link); link = link->next; } while (link != *list); _dbus_assert (length == _dbus_list_get_length (list)); if (length == 1) _dbus_assert (_dbus_list_length_is_one (list)); else _dbus_assert (!_dbus_list_length_is_one (list)); }
/* this function is self-cancelling if you cancel the transaction */ dbus_bool_t bus_service_remove_owner (BusService *service, DBusConnection *connection, BusTransaction *transaction, DBusError *error) { BusOwner *primary_owner; _DBUS_ASSERT_ERROR_IS_CLEAR (error); /* We send out notifications before we do any work we * might have to undo if the notification-sending failed */ /* Send service lost message */ primary_owner = bus_service_get_primary_owner (service); if (primary_owner != NULL && primary_owner->conn == connection) { if (!bus_driver_send_service_lost (connection, service->name, transaction, error)) return FALSE; } else { /* if we are not the primary owner then just remove us from the queue */ DBusList *link; BusOwner *temp_owner; link = _bus_service_find_owner_link (service, connection); _dbus_list_unlink (&service->owners, link); temp_owner = (BusOwner *)link->data; bus_owner_unref (temp_owner); _dbus_list_free_link (link); return TRUE; } if (service->owners == NULL) { _dbus_assert_not_reached ("Tried to remove owner of a service that has no owners"); } else if (_dbus_list_length_is_one (&service->owners)) { if (!bus_driver_send_service_owner_changed (service->name, bus_connection_get_name (connection), NULL, transaction, error)) return FALSE; } else { DBusList *link; BusOwner *new_owner; DBusConnection *new_owner_conn; link = _dbus_list_get_first_link (&service->owners); _dbus_assert (link != NULL); link = _dbus_list_get_next_link (&service->owners, link); _dbus_assert (link != NULL); new_owner = (BusOwner *)link->data; new_owner_conn = new_owner->conn; if (!bus_driver_send_service_owner_changed (service->name, bus_connection_get_name (connection), bus_connection_get_name (new_owner_conn), transaction, error)) return FALSE; /* This will be our new owner */ if (!bus_driver_send_service_acquired (new_owner_conn, service->name, transaction, error)) return FALSE; } if (!add_restore_ownership_to_transaction (transaction, service, primary_owner)) { BUS_SET_OOM (error); return FALSE; } bus_service_unlink_owner (service, primary_owner); if (service->owners == NULL) bus_service_unlink (service); return TRUE; }
dbus_bool_t bus_service_swap_owner (BusService *service, DBusConnection *connection, BusTransaction *transaction, DBusError *error) { DBusList *swap_link; BusOwner *primary_owner; _DBUS_ASSERT_ERROR_IS_CLEAR (error); /* We send out notifications before we do any work we * might have to undo if the notification-sending failed */ /* Send service lost message */ primary_owner = bus_service_get_primary_owner (service); if (primary_owner == NULL || primary_owner->conn != connection) _dbus_assert_not_reached ("Tried to swap a non primary owner"); if (!bus_driver_send_service_lost (connection, service->name, transaction, error)) return FALSE; if (service->owners == NULL) { _dbus_assert_not_reached ("Tried to swap owner of a service that has no owners"); } else if (_dbus_list_length_is_one (&service->owners)) { _dbus_assert_not_reached ("Tried to swap owner of a service that has no other owners in the queue"); } else { DBusList *link; BusOwner *new_owner; DBusConnection *new_owner_conn; link = _dbus_list_get_first_link (&service->owners); _dbus_assert (link != NULL); link = _dbus_list_get_next_link (&service->owners, link); _dbus_assert (link != NULL); new_owner = (BusOwner *)link->data; new_owner_conn = new_owner->conn; if (!bus_driver_send_service_owner_changed (service->name, bus_connection_get_name (connection), bus_connection_get_name (new_owner_conn), transaction, error)) return FALSE; /* This will be our new owner */ if (!bus_driver_send_service_acquired (new_owner_conn, service->name, transaction, error)) return FALSE; } if (!add_restore_ownership_to_transaction (transaction, service, primary_owner)) { BUS_SET_OOM (error); return FALSE; } /* unlink the primary and make it the second link */ swap_link = _dbus_list_get_first_link (&service->owners); _dbus_list_unlink (&service->owners, swap_link); _dbus_list_insert_after_link (&service->owners, _dbus_list_get_first_link (&service->owners), swap_link); return TRUE; }