1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <dbus/dbus-hash.h>
27 #include <dbus/dbus-list.h>
28 #include <dbus/dbus-mempool.h>
29 #include <dbus/dbus-marshal-validate.h>
33 #include "connection.h"
35 #include "activation.h"
44 BusRegistry *registry;
56 unsigned int allow_replacement : 1;
57 unsigned int do_not_queue : 1;
66 DBusHashTable *service_hash;
67 DBusMemPool *service_pool;
68 DBusMemPool *owner_pool;
70 DBusHashTable *service_sid_table;
74 bus_registry_new (BusContext *context)
76 BusRegistry *registry;
78 registry = dbus_new0 (BusRegistry, 1);
82 registry->refcount = 1;
83 registry->context = context;
85 registry->service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
87 if (registry->service_hash == NULL)
90 registry->service_pool = _dbus_mem_pool_new (sizeof (BusService),
93 if (registry->service_pool == NULL)
96 registry->owner_pool = _dbus_mem_pool_new (sizeof (BusOwner),
99 if (registry->owner_pool == NULL)
102 registry->service_sid_table = NULL;
107 bus_registry_unref (registry);
112 bus_registry_ref (BusRegistry *registry)
114 _dbus_assert (registry->refcount > 0);
115 registry->refcount += 1;
121 bus_registry_unref (BusRegistry *registry)
123 _dbus_assert (registry->refcount > 0);
124 registry->refcount -= 1;
126 if (registry->refcount == 0)
128 if (registry->service_hash)
129 _dbus_hash_table_unref (registry->service_hash);
130 if (registry->service_pool)
131 _dbus_mem_pool_free (registry->service_pool);
132 if (registry->owner_pool)
133 _dbus_mem_pool_free (registry->owner_pool);
134 if (registry->service_sid_table)
135 _dbus_hash_table_unref (registry->service_sid_table);
137 dbus_free (registry);
142 bus_registry_lookup (BusRegistry *registry,
143 const DBusString *service_name)
147 service = _dbus_hash_table_lookup_string (registry->service_hash,
148 _dbus_string_get_const_data (service_name));
154 _bus_service_find_owner_link (BusService *service,
155 DBusConnection *connection)
159 link = _dbus_list_get_first_link (&service->owners);
165 bus_owner = (BusOwner *) link->data;
166 if (bus_owner->conn == connection)
169 link = _dbus_list_get_next_link (&service->owners, link);
176 bus_owner_set_flags (BusOwner *owner,
179 owner->allow_replacement =
180 (flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT) != FALSE;
182 owner->do_not_queue =
183 (flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) != FALSE;
187 bus_owner_new (BusService *service,
188 DBusConnection *conn,
193 result = _dbus_mem_pool_alloc (service->registry->owner_pool);
196 result->refcount = 1;
197 /* don't ref the connection because we don't want
198 to block the connection from going away.
199 transactions take care of reffing the connection
200 but we need to use refcounting on the owner
201 so that the owner does not get freed before
202 we can deref the connection in the transaction
205 result->service = service;
207 if (!bus_connection_add_owned_service (conn, service))
209 _dbus_mem_pool_dealloc (service->registry->owner_pool, result);
213 bus_owner_set_flags (result, flags);
219 bus_owner_ref (BusOwner *owner)
221 _dbus_assert (owner->refcount > 0);
222 owner->refcount += 1;
228 bus_owner_unref (BusOwner *owner)
230 _dbus_assert (owner->refcount > 0);
231 owner->refcount -= 1;
233 if (owner->refcount == 0)
235 bus_connection_remove_owned_service (owner->conn, owner->service);
236 _dbus_mem_pool_dealloc (owner->service->registry->owner_pool, owner);
241 bus_registry_ensure (BusRegistry *registry,
242 const DBusString *service_name,
243 DBusConnection *owner_connection_if_created,
245 BusTransaction *transaction,
250 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
252 _dbus_assert (owner_connection_if_created != NULL);
253 _dbus_assert (transaction != NULL);
255 service = _dbus_hash_table_lookup_string (registry->service_hash,
256 _dbus_string_get_const_data (service_name));
260 service = _dbus_mem_pool_alloc (registry->service_pool);
267 service->registry = registry;
268 service->refcount = 1;
270 _dbus_verbose ("copying string %p '%s' to service->name\n",
271 service_name, _dbus_string_get_const_data (service_name));
272 if (!_dbus_string_copy_data (service_name, &service->name))
274 _dbus_mem_pool_dealloc (registry->service_pool, service);
278 _dbus_verbose ("copied string %p '%s' to '%s'\n",
279 service_name, _dbus_string_get_const_data (service_name),
282 if (!bus_driver_send_service_owner_changed (service->name,
284 bus_connection_get_name (owner_connection_if_created),
287 bus_service_unref (service);
291 if (!bus_activation_service_created (bus_context_get_activation (registry->context),
292 service->name, transaction, error))
294 bus_service_unref (service);
298 if (!bus_service_add_owner (service, owner_connection_if_created, flags,
301 bus_service_unref (service);
305 if (!_dbus_hash_table_insert_string (registry->service_hash,
309 /* The add_owner gets reverted on transaction cancel */
318 bus_registry_foreach (BusRegistry *registry,
319 BusServiceForeachFunction function,
324 _dbus_hash_iter_init (registry->service_hash, &iter);
325 while (_dbus_hash_iter_next (&iter))
327 BusService *service = _dbus_hash_iter_get_value (&iter);
329 (* function) (service, data);
334 bus_registry_list_services (BusRegistry *registry,
342 len = _dbus_hash_table_get_n_entries (registry->service_hash);
343 retval = dbus_new (char *, len + 1);
348 _dbus_hash_iter_init (registry->service_hash, &iter);
350 while (_dbus_hash_iter_next (&iter))
352 BusService *service = _dbus_hash_iter_get_value (&iter);
354 retval[i] = _dbus_strdup (service->name);
355 if (retval[i] == NULL)
370 for (j = 0; j < i; j++)
371 dbus_free (retval[i]);
378 bus_registry_acquire_service (BusRegistry *registry,
379 DBusConnection *connection,
380 const DBusString *service_name,
382 dbus_uint32_t *result,
383 BusTransaction *transaction,
387 DBusConnection *old_owner_conn;
388 DBusConnection *current_owner_conn;
389 BusClientPolicy *policy;
391 BusActivation *activation;
393 BusOwner *primary_owner;
397 if (!_dbus_validate_bus_name (service_name, 0,
398 _dbus_string_get_length (service_name)))
400 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
401 "Requested bus name \"%s\" is not valid",
402 _dbus_string_get_const_data (service_name));
404 _dbus_verbose ("Attempt to acquire invalid service name\n");
409 if (_dbus_string_get_byte (service_name, 0) == ':')
411 /* Not allowed; only base services can start with ':' */
412 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
413 "Cannot acquire a service starting with ':' such as \"%s\"",
414 _dbus_string_get_const_data (service_name));
416 _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"",
417 _dbus_string_get_const_data (service_name));
422 if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
424 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
425 "Connection \"%s\" is not allowed to own the service \"%s\"because "
426 "it is reserved for D-Bus' use only",
427 bus_connection_is_active (connection) ?
428 bus_connection_get_name (connection) :
434 policy = bus_connection_get_policy (connection);
435 _dbus_assert (policy != NULL);
437 /* Note that if sid is #NULL then the bus's own context gets used
438 * in bus_connection_selinux_allows_acquire_service()
440 sid = bus_selinux_id_table_lookup (registry->service_sid_table,
443 if (!bus_selinux_allows_acquire_service (connection, sid,
444 _dbus_string_get_const_data (service_name), error))
447 if (dbus_error_is_set (error) &&
448 dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
453 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
454 "Connection \"%s\" is not allowed to own the service \"%s\" due "
456 bus_connection_is_active (connection) ?
457 bus_connection_get_name (connection) :
459 _dbus_string_get_const_data (service_name));
463 if (!bus_client_policy_check_can_own (policy, connection,
466 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
467 "Connection \"%s\" is not allowed to own the service \"%s\" due "
468 "to security policies in the configuration file",
469 bus_connection_is_active (connection) ?
470 bus_connection_get_name (connection) :
472 _dbus_string_get_const_data (service_name));
476 if (bus_connection_get_n_services_owned (connection) >=
477 bus_context_get_max_services_per_connection (registry->context))
479 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
480 "Connection \"%s\" is not allowed to own more services "
481 "(increase limits in configuration file if required)",
482 bus_connection_is_active (connection) ?
483 bus_connection_get_name (connection) :
488 service = bus_registry_lookup (registry, service_name);
492 primary_owner = bus_service_get_primary_owner (service);
493 if (primary_owner != NULL)
494 old_owner_conn = primary_owner->conn;
496 old_owner_conn = NULL;
499 old_owner_conn = NULL;
503 service = bus_registry_ensure (registry,
504 service_name, connection, flags,
510 primary_owner = bus_service_get_primary_owner (service);
511 if (primary_owner == NULL)
514 current_owner_conn = primary_owner->conn;
516 if (old_owner_conn == NULL)
518 _dbus_assert (current_owner_conn == connection);
520 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
522 else if (old_owner_conn == connection)
524 bus_owner_set_flags (primary_owner, flags);
525 *result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
527 else if (((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
528 !(bus_service_get_allow_replacement (service))) ||
529 ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
530 !(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)))
533 BusOwner *temp_owner;
534 /* Since we can't be queued if we are already in the queue
537 link = _bus_service_find_owner_link (service, connection);
540 _dbus_list_unlink (&service->owners, link);
541 temp_owner = (BusOwner *)link->data;
542 bus_owner_unref (temp_owner);
543 _dbus_list_free_link (link);
546 *result = DBUS_REQUEST_NAME_REPLY_EXISTS;
548 else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
549 (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
550 !(bus_service_get_allow_replacement (service))))
552 /* Queue the connection */
553 if (!bus_service_add_owner (service, connection,
558 *result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
562 /* Replace the current owner */
564 /* We enqueue the new owner and remove the first one because
565 * that will cause NameAcquired and NameLost messages to
569 if (!bus_service_add_owner (service, connection,
574 if (primary_owner->do_not_queue)
576 if (!bus_service_remove_owner (service, old_owner_conn,
582 if (!bus_service_swap_owner (service, old_owner_conn,
588 _dbus_assert (connection == bus_service_get_primary_owner (service)->conn);
589 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
592 activation = bus_context_get_activation (registry->context);
593 retval = bus_activation_send_pending_auto_activation_messages (activation,
603 bus_registry_release_service (BusRegistry *registry,
604 DBusConnection *connection,
605 const DBusString *service_name,
606 dbus_uint32_t *result,
607 BusTransaction *transaction,
615 if (!_dbus_validate_bus_name (service_name, 0,
616 _dbus_string_get_length (service_name)))
618 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
619 "Given bus name \"%s\" is not valid",
620 _dbus_string_get_const_data (service_name));
622 _dbus_verbose ("Attempt to release invalid service name\n");
627 if (_dbus_string_get_byte (service_name, 0) == ':')
629 /* Not allowed; the base service name cannot be created or released */
630 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
631 "Cannot release a service starting with ':' such as \"%s\"",
632 _dbus_string_get_const_data (service_name));
634 _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
635 _dbus_string_get_const_data (service_name));
640 if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
642 /* Not allowed; the base service name cannot be created or released */
643 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
644 "Cannot release the %s service because it is owned by the bus",
647 _dbus_verbose ("Attempt to release service name \"%s\"",
653 service = bus_registry_lookup (registry, service_name);
657 *result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
659 else if (!bus_service_has_owner (service, connection))
661 *result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
665 if (!bus_service_remove_owner (service, connection,
669 _dbus_assert (!bus_service_has_owner (service, connection));
670 *result = DBUS_RELEASE_NAME_REPLY_RELEASED;
680 bus_registry_set_service_context_table (BusRegistry *registry,
681 DBusHashTable *table)
683 DBusHashTable *new_table;
686 new_table = bus_selinux_id_table_new ();
690 _dbus_hash_iter_init (table, &iter);
691 while (_dbus_hash_iter_next (&iter))
693 const char *service = _dbus_hash_iter_get_string_key (&iter);
694 const char *context = _dbus_hash_iter_get_value (&iter);
696 if (!bus_selinux_id_table_insert (new_table,
702 if (registry->service_sid_table)
703 _dbus_hash_table_unref (registry->service_sid_table);
704 registry->service_sid_table = new_table;
709 bus_service_unlink_owner (BusService *service,
712 _dbus_list_remove_last (&service->owners, owner);
713 bus_owner_unref (owner);
717 bus_service_unlink (BusService *service)
719 _dbus_assert (service->owners == NULL);
721 /* the service may not be in the hash, if
722 * the failure causing transaction cancel
723 * was in the right place, but that's OK
725 _dbus_hash_table_remove_string (service->registry->service_hash,
728 bus_service_unref (service);
732 bus_service_relink (BusService *service,
733 DBusPreallocatedHash *preallocated)
735 _dbus_assert (service->owners == NULL);
736 _dbus_assert (preallocated != NULL);
738 _dbus_hash_table_insert_string_preallocated (service->registry->service_hash,
743 bus_service_ref (service);
747 * Data used to represent an ownership cancellation in
752 BusOwner *owner; /**< the owner */
753 BusService *service; /**< service to cancel ownership of */
754 } OwnershipCancelData;
757 cancel_ownership (void *data)
759 OwnershipCancelData *d = data;
761 /* We don't need to send messages notifying of these
762 * changes, since we're reverting something that was
763 * cancelled (effectively never really happened)
765 bus_service_unlink_owner (d->service, d->owner);
767 if (d->service->owners == NULL)
768 bus_service_unlink (d->service);
772 free_ownership_cancel_data (void *data)
774 OwnershipCancelData *d = data;
776 dbus_connection_unref (d->owner->conn);
777 bus_owner_unref (d->owner);
778 bus_service_unref (d->service);
784 add_cancel_ownership_to_transaction (BusTransaction *transaction,
788 OwnershipCancelData *d;
790 d = dbus_new (OwnershipCancelData, 1);
794 d->service = service;
797 if (!bus_transaction_add_cancel_hook (transaction, cancel_ownership, d,
798 free_ownership_cancel_data))
804 bus_service_ref (d->service);
805 bus_owner_ref (owner);
806 dbus_connection_ref (d->owner->conn);
811 /* this function is self-cancelling if you cancel the transaction */
813 bus_service_add_owner (BusService *service,
814 DBusConnection *connection,
816 BusTransaction *transaction,
820 DBusList *bus_owner_link;
822 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
824 /* Send service acquired message first, OOM will result
825 * in cancelling the transaction
827 if (service->owners == NULL)
829 if (!bus_driver_send_service_acquired (connection, service->name, transaction, error))
833 bus_owner_link = _bus_service_find_owner_link (service, connection);
835 if (bus_owner_link == NULL)
837 bus_owner = bus_owner_new (service, connection, flags);
838 if (bus_owner == NULL)
844 bus_owner_set_flags (bus_owner, flags);
845 if (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || service->owners == NULL)
847 if (!_dbus_list_append (&service->owners,
850 bus_owner_unref (bus_owner);
857 if (!_dbus_list_insert_after (&service->owners,
858 _dbus_list_get_first_link (&service->owners),
861 bus_owner_unref (bus_owner);
869 /* Update the link since we are already in the queue
870 * No need for operations that can produce OOM
873 bus_owner = (BusOwner *) bus_owner_link->data;
874 if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
877 _dbus_list_unlink (&service->owners, bus_owner_link);
878 link = _dbus_list_get_first_link (&service->owners);
879 _dbus_assert (link != NULL);
881 _dbus_list_insert_after_link (&service->owners, link, bus_owner_link);
884 bus_owner_set_flags (bus_owner, flags);
888 if (!add_cancel_ownership_to_transaction (transaction,
892 bus_service_unlink_owner (service, bus_owner);
904 BusOwner *before_owner; /* restore to position before this connection in owners list */
905 DBusList *owner_link;
906 DBusList *service_link;
907 DBusPreallocatedHash *hash_entry;
908 } OwnershipRestoreData;
911 restore_ownership (void *data)
913 OwnershipRestoreData *d = data;
916 _dbus_assert (d->service_link != NULL);
917 _dbus_assert (d->owner_link != NULL);
919 if (d->service->owners == NULL)
921 _dbus_assert (d->hash_entry != NULL);
922 bus_service_relink (d->service, d->hash_entry);
926 _dbus_assert (d->hash_entry == NULL);
929 /* We don't need to send messages notifying of these
930 * changes, since we're reverting something that was
931 * cancelled (effectively never really happened)
933 link = _dbus_list_get_first_link (&d->service->owners);
936 if (link->data == d->before_owner)
939 link = _dbus_list_get_next_link (&d->service->owners, link);
942 _dbus_list_insert_before_link (&d->service->owners, link, d->owner_link);
944 /* Note that removing then restoring this changes the order in which
945 * ServiceDeleted messages are sent on destruction of the
946 * connection. This should be OK as the only guarantee there is
947 * that the base service is destroyed last, and we never even
948 * tentatively remove the base service.
950 bus_connection_add_owned_service_link (d->owner->conn, d->service_link);
952 d->hash_entry = NULL;
953 d->service_link = NULL;
954 d->owner_link = NULL;
958 free_ownership_restore_data (void *data)
960 OwnershipRestoreData *d = data;
963 _dbus_list_free_link (d->service_link);
965 _dbus_list_free_link (d->owner_link);
967 _dbus_hash_table_free_preallocated_entry (d->service->registry->service_hash,
970 dbus_connection_unref (d->owner->conn);
971 bus_owner_unref (d->owner);
972 bus_service_unref (d->service);
978 add_restore_ownership_to_transaction (BusTransaction *transaction,
982 OwnershipRestoreData *d;
985 d = dbus_new (OwnershipRestoreData, 1);
989 d->service = service;
991 d->service_link = _dbus_list_alloc_link (service);
992 d->owner_link = _dbus_list_alloc_link (owner);
993 d->hash_entry = _dbus_hash_table_preallocate_entry (service->registry->service_hash);
995 bus_service_ref (d->service);
996 bus_owner_ref (d->owner);
997 dbus_connection_ref (d->owner->conn);
999 d->before_owner = NULL;
1000 link = _dbus_list_get_first_link (&service->owners);
1001 while (link != NULL)
1003 if (link->data == owner)
1005 link = _dbus_list_get_next_link (&service->owners, link);
1008 d->before_owner = link->data;
1013 link = _dbus_list_get_next_link (&service->owners, link);
1016 if (d->service_link == NULL ||
1017 d->owner_link == NULL ||
1018 d->hash_entry == NULL ||
1019 !bus_transaction_add_cancel_hook (transaction, restore_ownership, d,
1020 free_ownership_restore_data))
1022 free_ownership_restore_data (d);
1030 bus_service_swap_owner (BusService *service,
1031 DBusConnection *connection,
1032 BusTransaction *transaction,
1035 DBusList *swap_link;
1036 BusOwner *primary_owner;
1038 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1040 /* We send out notifications before we do any work we
1041 * might have to undo if the notification-sending failed
1044 /* Send service lost message */
1045 primary_owner = bus_service_get_primary_owner (service);
1046 if (primary_owner == NULL || primary_owner->conn != connection)
1047 _dbus_assert_not_reached ("Tried to swap a non primary owner");
1050 if (!bus_driver_send_service_lost (connection, service->name,
1051 transaction, error))
1054 if (service->owners == NULL)
1056 _dbus_assert_not_reached ("Tried to swap owner of a service that has no owners");
1058 else if (_dbus_list_length_is_one (&service->owners))
1060 _dbus_assert_not_reached ("Tried to swap owner of a service that has no other owners in the queue");
1065 BusOwner *new_owner;
1066 DBusConnection *new_owner_conn;
1067 link = _dbus_list_get_first_link (&service->owners);
1068 _dbus_assert (link != NULL);
1069 link = _dbus_list_get_next_link (&service->owners, link);
1070 _dbus_assert (link != NULL);
1072 new_owner = (BusOwner *)link->data;
1073 new_owner_conn = new_owner->conn;
1075 if (!bus_driver_send_service_owner_changed (service->name,
1076 bus_connection_get_name (connection),
1077 bus_connection_get_name (new_owner_conn),
1078 transaction, error))
1081 /* This will be our new owner */
1082 if (!bus_driver_send_service_acquired (new_owner_conn,
1089 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1091 BUS_SET_OOM (error);
1095 /* unlink the primary and make it the second link */
1096 swap_link = _dbus_list_get_first_link (&service->owners);
1097 _dbus_list_unlink (&service->owners, swap_link);
1099 _dbus_list_insert_after_link (&service->owners,
1100 _dbus_list_get_first_link (&service->owners),
1106 /* this function is self-cancelling if you cancel the transaction */
1108 bus_service_remove_owner (BusService *service,
1109 DBusConnection *connection,
1110 BusTransaction *transaction,
1113 BusOwner *primary_owner;
1115 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1117 /* We send out notifications before we do any work we
1118 * might have to undo if the notification-sending failed
1121 /* Send service lost message */
1122 primary_owner = bus_service_get_primary_owner (service);
1123 if (primary_owner != NULL && primary_owner->conn == connection)
1125 if (!bus_driver_send_service_lost (connection, service->name,
1126 transaction, error))
1131 /* if we are not the primary owner then just remove us from the queue */
1133 BusOwner *temp_owner;
1135 link = _bus_service_find_owner_link (service, connection);
1136 _dbus_list_unlink (&service->owners, link);
1137 temp_owner = (BusOwner *)link->data;
1138 bus_owner_unref (temp_owner);
1139 _dbus_list_free_link (link);
1144 if (service->owners == NULL)
1146 _dbus_assert_not_reached ("Tried to remove owner of a service that has no owners");
1148 else if (_dbus_list_length_is_one (&service->owners))
1150 if (!bus_driver_send_service_owner_changed (service->name,
1151 bus_connection_get_name (connection),
1153 transaction, error))
1159 BusOwner *new_owner;
1160 DBusConnection *new_owner_conn;
1161 link = _dbus_list_get_first_link (&service->owners);
1162 _dbus_assert (link != NULL);
1163 link = _dbus_list_get_next_link (&service->owners, link);
1164 _dbus_assert (link != NULL);
1166 new_owner = (BusOwner *)link->data;
1167 new_owner_conn = new_owner->conn;
1169 if (!bus_driver_send_service_owner_changed (service->name,
1170 bus_connection_get_name (connection),
1171 bus_connection_get_name (new_owner_conn),
1172 transaction, error))
1175 /* This will be our new owner */
1176 if (!bus_driver_send_service_acquired (new_owner_conn,
1183 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1185 BUS_SET_OOM (error);
1189 bus_service_unlink_owner (service, primary_owner);
1191 if (service->owners == NULL)
1192 bus_service_unlink (service);
1198 bus_service_ref (BusService *service)
1200 _dbus_assert (service->refcount > 0);
1202 service->refcount += 1;
1208 bus_service_unref (BusService *service)
1210 _dbus_assert (service->refcount > 0);
1212 service->refcount -= 1;
1214 if (service->refcount == 0)
1216 _dbus_assert (service->owners == NULL);
1218 dbus_free (service->name);
1219 _dbus_mem_pool_dealloc (service->registry->service_pool, service);
1224 bus_service_get_primary_owners_connection (BusService *service)
1228 owner = bus_service_get_primary_owner (service);
1237 bus_service_get_primary_owner (BusService *service)
1239 return _dbus_list_get_first (&service->owners);
1243 bus_service_get_name (BusService *service)
1245 return service->name;
1249 bus_service_get_allow_replacement (BusService *service)
1254 _dbus_assert (service->owners != NULL);
1256 link = _dbus_list_get_first_link (&service->owners);
1257 owner = (BusOwner *) link->data;
1259 return owner->allow_replacement;
1263 bus_service_has_owner (BusService *service,
1264 DBusConnection *connection)
1268 link = _bus_service_find_owner_link (service, connection);
1277 bus_service_list_queued_owners (BusService *service,
1278 DBusList **return_list,
1283 _dbus_assert (*return_list == NULL);
1285 link = _dbus_list_get_first_link (&service->owners);
1286 _dbus_assert (link != NULL);
1288 while (link != NULL)
1293 owner = (BusOwner *) link->data;
1294 uname = bus_connection_get_name (owner->conn);
1296 if (!_dbus_list_append (return_list, (char *)uname))
1299 link = _dbus_list_get_next_link (&service->owners, link);
1305 _dbus_list_clear (return_list);
1306 BUS_SET_OOM (error);