1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* services.c Service management
4 * Copyright (C) 2003 Red Hat, Inc.
5 * Copyright (C) 2003 CodeFactory AB
7 * Licensed under the Academic Free License version 2.1
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <dbus/dbus-hash.h>
25 #include <dbus/dbus-list.h>
26 #include <dbus/dbus-mempool.h>
27 #include <dbus/dbus-marshal-validate.h>
31 #include "connection.h"
33 #include "activation.h"
42 BusRegistry *registry;
54 unsigned int allow_replacement : 1;
55 unsigned int do_not_queue : 1;
64 DBusHashTable *service_hash;
65 DBusMemPool *service_pool;
66 DBusMemPool *owner_pool;
68 DBusHashTable *service_sid_table;
72 bus_registry_new (BusContext *context)
74 BusRegistry *registry;
76 registry = dbus_new0 (BusRegistry, 1);
80 registry->refcount = 1;
81 registry->context = context;
83 registry->service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
85 if (registry->service_hash == NULL)
88 registry->service_pool = _dbus_mem_pool_new (sizeof (BusService),
91 if (registry->service_pool == NULL)
94 registry->owner_pool = _dbus_mem_pool_new (sizeof (BusOwner),
97 if (registry->owner_pool == NULL)
100 registry->service_sid_table = NULL;
105 bus_registry_unref (registry);
110 bus_registry_ref (BusRegistry *registry)
112 _dbus_assert (registry->refcount > 0);
113 registry->refcount += 1;
119 bus_registry_unref (BusRegistry *registry)
121 _dbus_assert (registry->refcount > 0);
122 registry->refcount -= 1;
124 if (registry->refcount == 0)
126 if (registry->service_hash)
127 _dbus_hash_table_unref (registry->service_hash);
128 if (registry->service_pool)
129 _dbus_mem_pool_free (registry->service_pool);
130 if (registry->owner_pool)
131 _dbus_mem_pool_free (registry->owner_pool);
132 if (registry->service_sid_table)
133 _dbus_hash_table_unref (registry->service_sid_table);
135 dbus_free (registry);
140 bus_registry_lookup (BusRegistry *registry,
141 const DBusString *service_name)
145 service = _dbus_hash_table_lookup_string (registry->service_hash,
146 _dbus_string_get_const_data (service_name));
152 _bus_service_find_owner_link (BusService *service,
153 DBusConnection *connection)
157 link = _dbus_list_get_first_link (&service->owners);
163 bus_owner = (BusOwner *) link->data;
164 if (bus_owner->conn == connection)
167 link = _dbus_list_get_next_link (&service->owners, link);
174 bus_owner_set_flags (BusOwner *owner,
177 owner->allow_replacement =
178 (flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT) != FALSE;
180 owner->do_not_queue =
181 (flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) != FALSE;
185 bus_owner_new (BusService *service,
186 DBusConnection *conn,
191 result = _dbus_mem_pool_alloc (service->registry->owner_pool);
194 result->refcount = 1;
195 /* don't ref the connection because we don't want
196 to block the connection from going away.
197 transactions take care of reffing the connection
198 but we need to use refcounting on the owner
199 so that the owner does not get freed before
200 we can deref the connection in the transaction
203 result->service = service;
205 if (!bus_connection_add_owned_service (conn, service))
207 _dbus_mem_pool_dealloc (service->registry->owner_pool, result);
211 bus_owner_set_flags (result, flags);
217 bus_owner_ref (BusOwner *owner)
219 _dbus_assert (owner->refcount > 0);
220 owner->refcount += 1;
226 bus_owner_unref (BusOwner *owner)
228 _dbus_assert (owner->refcount > 0);
229 owner->refcount -= 1;
231 if (owner->refcount == 0)
233 bus_connection_remove_owned_service (owner->conn, owner->service);
234 _dbus_mem_pool_dealloc (owner->service->registry->owner_pool, owner);
239 bus_registry_ensure (BusRegistry *registry,
240 const DBusString *service_name,
241 DBusConnection *owner_connection_if_created,
243 BusTransaction *transaction,
248 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
250 _dbus_assert (owner_connection_if_created != NULL);
251 _dbus_assert (transaction != NULL);
253 service = _dbus_hash_table_lookup_string (registry->service_hash,
254 _dbus_string_get_const_data (service_name));
258 service = _dbus_mem_pool_alloc (registry->service_pool);
265 service->registry = registry;
266 service->refcount = 1;
268 _dbus_verbose ("copying string %p '%s' to service->name\n",
269 service_name, _dbus_string_get_const_data (service_name));
270 if (!_dbus_string_copy_data (service_name, &service->name))
272 _dbus_mem_pool_dealloc (registry->service_pool, service);
276 _dbus_verbose ("copied string %p '%s' to '%s'\n",
277 service_name, _dbus_string_get_const_data (service_name),
280 if (!bus_driver_send_service_owner_changed (service->name,
282 bus_connection_get_name (owner_connection_if_created),
285 bus_service_unref (service);
289 if (!bus_activation_service_created (bus_context_get_activation (registry->context),
290 service->name, transaction, error))
292 bus_service_unref (service);
296 if (!bus_service_add_owner (service, owner_connection_if_created, flags,
299 bus_service_unref (service);
303 if (!_dbus_hash_table_insert_string (registry->service_hash,
307 /* The add_owner gets reverted on transaction cancel */
316 bus_registry_foreach (BusRegistry *registry,
317 BusServiceForeachFunction function,
322 _dbus_hash_iter_init (registry->service_hash, &iter);
323 while (_dbus_hash_iter_next (&iter))
325 BusService *service = _dbus_hash_iter_get_value (&iter);
327 (* function) (service, data);
332 bus_registry_list_services (BusRegistry *registry,
340 len = _dbus_hash_table_get_n_entries (registry->service_hash);
341 retval = dbus_new (char *, len + 1);
346 _dbus_hash_iter_init (registry->service_hash, &iter);
348 while (_dbus_hash_iter_next (&iter))
350 BusService *service = _dbus_hash_iter_get_value (&iter);
352 retval[i] = _dbus_strdup (service->name);
353 if (retval[i] == NULL)
368 for (j = 0; j < i; j++)
369 dbus_free (retval[i]);
376 bus_registry_acquire_service (BusRegistry *registry,
377 DBusConnection *connection,
378 const DBusString *service_name,
380 dbus_uint32_t *result,
381 BusTransaction *transaction,
385 DBusConnection *old_owner_conn;
386 DBusConnection *current_owner_conn;
387 BusClientPolicy *policy;
389 BusActivation *activation;
391 BusOwner *primary_owner;
395 if (!_dbus_validate_bus_name (service_name, 0,
396 _dbus_string_get_length (service_name)))
398 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
399 "Requested bus name \"%s\" is not valid",
400 _dbus_string_get_const_data (service_name));
402 _dbus_verbose ("Attempt to acquire invalid service name\n");
407 if (_dbus_string_get_byte (service_name, 0) == ':')
409 /* Not allowed; only base services can start with ':' */
410 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
411 "Cannot acquire a service starting with ':' such as \"%s\"",
412 _dbus_string_get_const_data (service_name));
414 _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"",
415 _dbus_string_get_const_data (service_name));
420 if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
422 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
423 "Connection \"%s\" is not allowed to own the service \"%s\"because "
424 "it is reserved for D-Bus' use only",
425 bus_connection_is_active (connection) ?
426 bus_connection_get_name (connection) :
432 policy = bus_connection_get_policy (connection);
433 _dbus_assert (policy != NULL);
435 /* Note that if sid is #NULL then the bus's own context gets used
436 * in bus_connection_selinux_allows_acquire_service()
438 sid = bus_selinux_id_table_lookup (registry->service_sid_table,
441 if (!bus_selinux_allows_acquire_service (connection, sid,
442 _dbus_string_get_const_data (service_name), error))
445 if (dbus_error_is_set (error) &&
446 dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
451 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
452 "Connection \"%s\" is not allowed to own the service \"%s\" due "
454 bus_connection_is_active (connection) ?
455 bus_connection_get_name (connection) :
457 _dbus_string_get_const_data (service_name));
461 if (!bus_client_policy_check_can_own (policy, connection,
464 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
465 "Connection \"%s\" is not allowed to own the service \"%s\" due "
466 "to security policies in the configuration file",
467 bus_connection_is_active (connection) ?
468 bus_connection_get_name (connection) :
470 _dbus_string_get_const_data (service_name));
474 if (bus_connection_get_n_services_owned (connection) >=
475 bus_context_get_max_services_per_connection (registry->context))
477 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
478 "Connection \"%s\" is not allowed to own more services "
479 "(increase limits in configuration file if required)",
480 bus_connection_is_active (connection) ?
481 bus_connection_get_name (connection) :
486 service = bus_registry_lookup (registry, service_name);
490 primary_owner = bus_service_get_primary_owner (service);
491 if (primary_owner != NULL)
492 old_owner_conn = primary_owner->conn;
494 old_owner_conn = NULL;
497 old_owner_conn = NULL;
501 service = bus_registry_ensure (registry,
502 service_name, connection, flags,
508 primary_owner = bus_service_get_primary_owner (service);
509 if (primary_owner == NULL)
512 current_owner_conn = primary_owner->conn;
514 if (old_owner_conn == NULL)
516 _dbus_assert (current_owner_conn == connection);
518 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
520 else if (old_owner_conn == connection)
522 bus_owner_set_flags (primary_owner, flags);
523 *result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
525 else if (((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
526 !(bus_service_get_allow_replacement (service))) ||
527 ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
528 !(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)))
531 BusOwner *temp_owner;
532 /* Since we can't be queued if we are already in the queue
535 link = _bus_service_find_owner_link (service, connection);
538 _dbus_list_unlink (&service->owners, link);
539 temp_owner = (BusOwner *)link->data;
540 bus_owner_unref (temp_owner);
541 _dbus_list_free_link (link);
544 *result = DBUS_REQUEST_NAME_REPLY_EXISTS;
546 else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
547 (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
548 !(bus_service_get_allow_replacement (service))))
550 /* Queue the connection */
551 if (!bus_service_add_owner (service, connection,
556 *result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
560 /* Replace the current owner */
562 /* We enqueue the new owner and remove the first one because
563 * that will cause NameAcquired and NameLost messages to
567 if (!bus_service_add_owner (service, connection,
572 if (primary_owner->do_not_queue)
574 if (!bus_service_remove_owner (service, old_owner_conn,
580 if (!bus_service_swap_owner (service, old_owner_conn,
586 _dbus_assert (connection == bus_service_get_primary_owner (service)->conn);
587 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
590 activation = bus_context_get_activation (registry->context);
591 retval = bus_activation_send_pending_auto_activation_messages (activation,
601 bus_registry_release_service (BusRegistry *registry,
602 DBusConnection *connection,
603 const DBusString *service_name,
604 dbus_uint32_t *result,
605 BusTransaction *transaction,
613 if (!_dbus_validate_bus_name (service_name, 0,
614 _dbus_string_get_length (service_name)))
616 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
617 "Given bus name \"%s\" is not valid",
618 _dbus_string_get_const_data (service_name));
620 _dbus_verbose ("Attempt to release invalid service name\n");
625 if (_dbus_string_get_byte (service_name, 0) == ':')
627 /* Not allowed; the base service name cannot be created or released */
628 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
629 "Cannot release a service starting with ':' such as \"%s\"",
630 _dbus_string_get_const_data (service_name));
632 _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
633 _dbus_string_get_const_data (service_name));
638 if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
640 /* Not allowed; the base service name cannot be created or released */
641 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
642 "Cannot release the %s service because it is owned by the bus",
645 _dbus_verbose ("Attempt to release service name \"%s\"",
651 service = bus_registry_lookup (registry, service_name);
655 *result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
657 else if (!bus_service_has_owner (service, connection))
659 *result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
663 if (!bus_service_remove_owner (service, connection,
667 _dbus_assert (!bus_service_has_owner (service, connection));
668 *result = DBUS_RELEASE_NAME_REPLY_RELEASED;
678 bus_registry_set_service_context_table (BusRegistry *registry,
679 DBusHashTable *table)
681 DBusHashTable *new_table;
684 new_table = bus_selinux_id_table_new ();
688 _dbus_hash_iter_init (table, &iter);
689 while (_dbus_hash_iter_next (&iter))
691 const char *service = _dbus_hash_iter_get_string_key (&iter);
692 const char *context = _dbus_hash_iter_get_value (&iter);
694 if (!bus_selinux_id_table_insert (new_table,
700 if (registry->service_sid_table)
701 _dbus_hash_table_unref (registry->service_sid_table);
702 registry->service_sid_table = new_table;
707 bus_service_unlink_owner (BusService *service,
710 _dbus_list_remove_last (&service->owners, owner);
711 bus_owner_unref (owner);
715 bus_service_unlink (BusService *service)
717 _dbus_assert (service->owners == NULL);
719 /* the service may not be in the hash, if
720 * the failure causing transaction cancel
721 * was in the right place, but that's OK
723 _dbus_hash_table_remove_string (service->registry->service_hash,
726 bus_service_unref (service);
730 bus_service_relink (BusService *service,
731 DBusPreallocatedHash *preallocated)
733 _dbus_assert (service->owners == NULL);
734 _dbus_assert (preallocated != NULL);
736 _dbus_hash_table_insert_string_preallocated (service->registry->service_hash,
741 bus_service_ref (service);
745 * Data used to represent an ownership cancellation in
750 BusOwner *owner; /**< the owner */
751 BusService *service; /**< service to cancel ownership of */
752 } OwnershipCancelData;
755 cancel_ownership (void *data)
757 OwnershipCancelData *d = data;
759 /* We don't need to send messages notifying of these
760 * changes, since we're reverting something that was
761 * cancelled (effectively never really happened)
763 bus_service_unlink_owner (d->service, d->owner);
765 if (d->service->owners == NULL)
766 bus_service_unlink (d->service);
770 free_ownership_cancel_data (void *data)
772 OwnershipCancelData *d = data;
774 dbus_connection_unref (d->owner->conn);
775 bus_owner_unref (d->owner);
776 bus_service_unref (d->service);
782 add_cancel_ownership_to_transaction (BusTransaction *transaction,
786 OwnershipCancelData *d;
788 d = dbus_new (OwnershipCancelData, 1);
792 d->service = service;
795 if (!bus_transaction_add_cancel_hook (transaction, cancel_ownership, d,
796 free_ownership_cancel_data))
802 bus_service_ref (d->service);
803 bus_owner_ref (owner);
804 dbus_connection_ref (d->owner->conn);
809 /* this function is self-cancelling if you cancel the transaction */
811 bus_service_add_owner (BusService *service,
812 DBusConnection *connection,
814 BusTransaction *transaction,
818 DBusList *bus_owner_link;
820 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
822 /* Send service acquired message first, OOM will result
823 * in cancelling the transaction
825 if (service->owners == NULL)
827 if (!bus_driver_send_service_acquired (connection, service->name, transaction, error))
831 bus_owner_link = _bus_service_find_owner_link (service, connection);
833 if (bus_owner_link == NULL)
835 bus_owner = bus_owner_new (service, connection, flags);
836 if (bus_owner == NULL)
842 bus_owner_set_flags (bus_owner, flags);
843 if (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || service->owners == NULL)
845 if (!_dbus_list_append (&service->owners,
848 bus_owner_unref (bus_owner);
855 if (!_dbus_list_insert_after (&service->owners,
856 _dbus_list_get_first_link (&service->owners),
859 bus_owner_unref (bus_owner);
867 /* Update the link since we are already in the queue
868 * No need for operations that can produce OOM
871 bus_owner = (BusOwner *) bus_owner_link->data;
872 if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
875 _dbus_list_unlink (&service->owners, bus_owner_link);
876 link = _dbus_list_get_first_link (&service->owners);
877 _dbus_assert (link != NULL);
879 _dbus_list_insert_after_link (&service->owners, link, bus_owner_link);
882 bus_owner_set_flags (bus_owner, flags);
886 if (!add_cancel_ownership_to_transaction (transaction,
890 bus_service_unlink_owner (service, bus_owner);
902 BusOwner *before_owner; /* restore to position before this connection in owners list */
903 DBusList *owner_link;
904 DBusList *service_link;
905 DBusPreallocatedHash *hash_entry;
906 } OwnershipRestoreData;
909 restore_ownership (void *data)
911 OwnershipRestoreData *d = data;
914 _dbus_assert (d->service_link != NULL);
915 _dbus_assert (d->owner_link != NULL);
917 if (d->service->owners == NULL)
919 _dbus_assert (d->hash_entry != NULL);
920 bus_service_relink (d->service, d->hash_entry);
924 _dbus_assert (d->hash_entry == NULL);
927 /* We don't need to send messages notifying of these
928 * changes, since we're reverting something that was
929 * cancelled (effectively never really happened)
931 link = _dbus_list_get_first_link (&d->service->owners);
934 if (link->data == d->before_owner)
937 link = _dbus_list_get_next_link (&d->service->owners, link);
940 _dbus_list_insert_before_link (&d->service->owners, link, d->owner_link);
942 /* Note that removing then restoring this changes the order in which
943 * ServiceDeleted messages are sent on destruction of the
944 * connection. This should be OK as the only guarantee there is
945 * that the base service is destroyed last, and we never even
946 * tentatively remove the base service.
948 bus_connection_add_owned_service_link (d->owner->conn, d->service_link);
950 d->hash_entry = NULL;
951 d->service_link = NULL;
952 d->owner_link = NULL;
956 free_ownership_restore_data (void *data)
958 OwnershipRestoreData *d = data;
961 _dbus_list_free_link (d->service_link);
963 _dbus_list_free_link (d->owner_link);
965 _dbus_hash_table_free_preallocated_entry (d->service->registry->service_hash,
968 dbus_connection_unref (d->owner->conn);
969 bus_owner_unref (d->owner);
970 bus_service_unref (d->service);
976 add_restore_ownership_to_transaction (BusTransaction *transaction,
980 OwnershipRestoreData *d;
983 d = dbus_new (OwnershipRestoreData, 1);
987 d->service = service;
989 d->service_link = _dbus_list_alloc_link (service);
990 d->owner_link = _dbus_list_alloc_link (owner);
991 d->hash_entry = _dbus_hash_table_preallocate_entry (service->registry->service_hash);
993 bus_service_ref (d->service);
994 bus_owner_ref (d->owner);
995 dbus_connection_ref (d->owner->conn);
997 d->before_owner = NULL;
998 link = _dbus_list_get_first_link (&service->owners);
1001 if (link->data == owner)
1003 link = _dbus_list_get_next_link (&service->owners, link);
1006 d->before_owner = link->data;
1011 link = _dbus_list_get_next_link (&service->owners, link);
1014 if (d->service_link == NULL ||
1015 d->owner_link == NULL ||
1016 d->hash_entry == NULL ||
1017 !bus_transaction_add_cancel_hook (transaction, restore_ownership, d,
1018 free_ownership_restore_data))
1020 free_ownership_restore_data (d);
1028 bus_service_swap_owner (BusService *service,
1029 DBusConnection *connection,
1030 BusTransaction *transaction,
1033 DBusList *swap_link;
1034 BusOwner *primary_owner;
1036 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1038 /* We send out notifications before we do any work we
1039 * might have to undo if the notification-sending failed
1042 /* Send service lost message */
1043 primary_owner = bus_service_get_primary_owner (service);
1044 if (primary_owner == NULL || primary_owner->conn != connection)
1045 _dbus_assert_not_reached ("Tried to swap a non primary owner");
1048 if (!bus_driver_send_service_lost (connection, service->name,
1049 transaction, error))
1052 if (service->owners == NULL)
1054 _dbus_assert_not_reached ("Tried to swap owner of a service that has no owners");
1056 else if (_dbus_list_length_is_one (&service->owners))
1058 _dbus_assert_not_reached ("Tried to swap owner of a service that has no other owners in the queue");
1063 BusOwner *new_owner;
1064 DBusConnection *new_owner_conn;
1065 link = _dbus_list_get_first_link (&service->owners);
1066 _dbus_assert (link != NULL);
1067 link = _dbus_list_get_next_link (&service->owners, link);
1068 _dbus_assert (link != NULL);
1070 new_owner = (BusOwner *)link->data;
1071 new_owner_conn = new_owner->conn;
1073 if (!bus_driver_send_service_owner_changed (service->name,
1074 bus_connection_get_name (connection),
1075 bus_connection_get_name (new_owner_conn),
1076 transaction, error))
1079 /* This will be our new owner */
1080 if (!bus_driver_send_service_acquired (new_owner_conn,
1087 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1089 BUS_SET_OOM (error);
1093 /* unlink the primary and make it the second link */
1094 swap_link = _dbus_list_get_first_link (&service->owners);
1095 _dbus_list_unlink (&service->owners, swap_link);
1097 _dbus_list_insert_after_link (&service->owners,
1098 _dbus_list_get_first_link (&service->owners),
1104 /* this function is self-cancelling if you cancel the transaction */
1106 bus_service_remove_owner (BusService *service,
1107 DBusConnection *connection,
1108 BusTransaction *transaction,
1111 BusOwner *primary_owner;
1113 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1115 /* We send out notifications before we do any work we
1116 * might have to undo if the notification-sending failed
1119 /* Send service lost message */
1120 primary_owner = bus_service_get_primary_owner (service);
1121 if (primary_owner != NULL && primary_owner->conn == connection)
1123 if (!bus_driver_send_service_lost (connection, service->name,
1124 transaction, error))
1129 /* if we are not the primary owner then just remove us from the queue */
1131 BusOwner *temp_owner;
1133 link = _bus_service_find_owner_link (service, connection);
1134 _dbus_list_unlink (&service->owners, link);
1135 temp_owner = (BusOwner *)link->data;
1136 bus_owner_unref (temp_owner);
1137 _dbus_list_free_link (link);
1142 if (service->owners == NULL)
1144 _dbus_assert_not_reached ("Tried to remove owner of a service that has no owners");
1146 else if (_dbus_list_length_is_one (&service->owners))
1148 if (!bus_driver_send_service_owner_changed (service->name,
1149 bus_connection_get_name (connection),
1151 transaction, error))
1157 BusOwner *new_owner;
1158 DBusConnection *new_owner_conn;
1159 link = _dbus_list_get_first_link (&service->owners);
1160 _dbus_assert (link != NULL);
1161 link = _dbus_list_get_next_link (&service->owners, link);
1162 _dbus_assert (link != NULL);
1164 new_owner = (BusOwner *)link->data;
1165 new_owner_conn = new_owner->conn;
1167 if (!bus_driver_send_service_owner_changed (service->name,
1168 bus_connection_get_name (connection),
1169 bus_connection_get_name (new_owner_conn),
1170 transaction, error))
1173 /* This will be our new owner */
1174 if (!bus_driver_send_service_acquired (new_owner_conn,
1181 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1183 BUS_SET_OOM (error);
1187 bus_service_unlink_owner (service, primary_owner);
1189 if (service->owners == NULL)
1190 bus_service_unlink (service);
1196 bus_service_ref (BusService *service)
1198 _dbus_assert (service->refcount > 0);
1200 service->refcount += 1;
1206 bus_service_unref (BusService *service)
1208 _dbus_assert (service->refcount > 0);
1210 service->refcount -= 1;
1212 if (service->refcount == 0)
1214 _dbus_assert (service->owners == NULL);
1216 dbus_free (service->name);
1217 _dbus_mem_pool_dealloc (service->registry->service_pool, service);
1222 bus_service_get_primary_owners_connection (BusService *service)
1226 owner = bus_service_get_primary_owner (service);
1235 bus_service_get_primary_owner (BusService *service)
1237 return _dbus_list_get_first (&service->owners);
1241 bus_service_get_name (BusService *service)
1243 return service->name;
1247 bus_service_get_allow_replacement (BusService *service)
1252 _dbus_assert (service->owners != NULL);
1254 link = _dbus_list_get_first_link (&service->owners);
1255 owner = (BusOwner *) link->data;
1257 return owner->allow_replacement;
1261 bus_service_has_owner (BusService *service,
1262 DBusConnection *connection)
1266 link = _bus_service_find_owner_link (service, connection);
1275 bus_service_list_queued_owners (BusService *service,
1276 DBusList **return_list,
1281 _dbus_assert (*return_list == NULL);
1283 link = _dbus_list_get_first_link (&service->owners);
1284 _dbus_assert (link != NULL);
1286 while (link != NULL)
1291 owner = (BusOwner *) link->data;
1292 uname = bus_connection_get_name (owner->conn);
1294 if (!_dbus_list_append (return_list, (char *)uname))
1297 link = _dbus_list_get_next_link (&service->owners, link);
1303 _dbus_list_clear (return_list);
1304 BUS_SET_OOM (error);