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 BusClientPolicy *policy;
390 BusActivation *activation;
392 BusOwner *primary_owner;
396 if (!_dbus_validate_bus_name (service_name, 0,
397 _dbus_string_get_length (service_name)))
399 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
400 "Requested bus name \"%s\" is not valid",
401 _dbus_string_get_const_data (service_name));
403 _dbus_verbose ("Attempt to acquire invalid service name\n");
408 if (_dbus_string_get_byte (service_name, 0) == ':')
410 /* Not allowed; only base services can start with ':' */
411 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
412 "Cannot acquire a service starting with ':' such as \"%s\"",
413 _dbus_string_get_const_data (service_name));
415 _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"",
416 _dbus_string_get_const_data (service_name));
421 if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
423 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
424 "Connection \"%s\" is not allowed to own the service \"%s\"because "
425 "it is reserved for D-Bus' use only",
426 bus_connection_is_active (connection) ?
427 bus_connection_get_name (connection) :
433 policy = bus_connection_get_policy (connection);
434 _dbus_assert (policy != NULL);
436 /* Note that if sid is #NULL then the bus's own context gets used
437 * in bus_connection_selinux_allows_acquire_service()
439 sid = bus_selinux_id_table_lookup (registry->service_sid_table,
442 if (!bus_selinux_allows_acquire_service (connection, sid,
443 _dbus_string_get_const_data (service_name), error))
446 if (dbus_error_is_set (error) &&
447 dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
452 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
453 "Connection \"%s\" is not allowed to own the service \"%s\" due "
455 bus_connection_is_active (connection) ?
456 bus_connection_get_name (connection) :
458 _dbus_string_get_const_data (service_name));
462 if (!bus_client_policy_check_can_own (policy, connection,
465 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
466 "Connection \"%s\" is not allowed to own the service \"%s\" due "
467 "to security policies in the configuration file",
468 bus_connection_is_active (connection) ?
469 bus_connection_get_name (connection) :
471 _dbus_string_get_const_data (service_name));
475 if (bus_connection_get_n_services_owned (connection) >=
476 bus_context_get_max_services_per_connection (registry->context))
478 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
479 "Connection \"%s\" is not allowed to own more services "
480 "(increase limits in configuration file if required)",
481 bus_connection_is_active (connection) ?
482 bus_connection_get_name (connection) :
487 service = bus_registry_lookup (registry, service_name);
491 primary_owner = bus_service_get_primary_owner (service);
492 if (primary_owner != NULL)
493 old_owner_conn = primary_owner->conn;
495 old_owner_conn = NULL;
498 old_owner_conn = NULL;
502 service = bus_registry_ensure (registry,
503 service_name, connection, flags,
509 primary_owner = bus_service_get_primary_owner (service);
510 if (primary_owner == NULL)
513 if (old_owner_conn == NULL)
515 _dbus_assert (primary_owner->conn == connection);
517 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
519 else if (old_owner_conn == connection)
521 bus_owner_set_flags (primary_owner, flags);
522 *result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
524 else if (((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
525 !(bus_service_get_allow_replacement (service))) ||
526 ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
527 !(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)))
530 BusOwner *temp_owner;
531 /* Since we can't be queued if we are already in the queue
534 link = _bus_service_find_owner_link (service, connection);
537 _dbus_list_unlink (&service->owners, link);
538 temp_owner = (BusOwner *)link->data;
539 bus_owner_unref (temp_owner);
540 _dbus_list_free_link (link);
543 *result = DBUS_REQUEST_NAME_REPLY_EXISTS;
545 else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
546 (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
547 !(bus_service_get_allow_replacement (service))))
549 /* Queue the connection */
550 if (!bus_service_add_owner (service, connection,
555 *result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
559 /* Replace the current owner */
561 /* We enqueue the new owner and remove the first one because
562 * that will cause NameAcquired and NameLost messages to
566 if (!bus_service_add_owner (service, connection,
571 if (primary_owner->do_not_queue)
573 if (!bus_service_remove_owner (service, old_owner_conn,
579 if (!bus_service_swap_owner (service, old_owner_conn,
585 _dbus_assert (connection == bus_service_get_primary_owner (service)->conn);
586 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
589 activation = bus_context_get_activation (registry->context);
590 retval = bus_activation_send_pending_auto_activation_messages (activation,
600 bus_registry_release_service (BusRegistry *registry,
601 DBusConnection *connection,
602 const DBusString *service_name,
603 dbus_uint32_t *result,
604 BusTransaction *transaction,
612 if (!_dbus_validate_bus_name (service_name, 0,
613 _dbus_string_get_length (service_name)))
615 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
616 "Given bus name \"%s\" is not valid",
617 _dbus_string_get_const_data (service_name));
619 _dbus_verbose ("Attempt to release invalid service name\n");
624 if (_dbus_string_get_byte (service_name, 0) == ':')
626 /* Not allowed; the base service name cannot be created or released */
627 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
628 "Cannot release a service starting with ':' such as \"%s\"",
629 _dbus_string_get_const_data (service_name));
631 _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
632 _dbus_string_get_const_data (service_name));
637 if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
639 /* Not allowed; the base service name cannot be created or released */
640 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
641 "Cannot release the %s service because it is owned by the bus",
644 _dbus_verbose ("Attempt to release service name \"%s\"",
650 service = bus_registry_lookup (registry, service_name);
654 *result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
656 else if (!bus_service_has_owner (service, connection))
658 *result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
662 if (!bus_service_remove_owner (service, connection,
666 _dbus_assert (!bus_service_has_owner (service, connection));
667 *result = DBUS_RELEASE_NAME_REPLY_RELEASED;
677 bus_registry_set_service_context_table (BusRegistry *registry,
678 DBusHashTable *table)
680 DBusHashTable *new_table;
683 new_table = bus_selinux_id_table_new ();
687 _dbus_hash_iter_init (table, &iter);
688 while (_dbus_hash_iter_next (&iter))
690 const char *service = _dbus_hash_iter_get_string_key (&iter);
691 const char *context = _dbus_hash_iter_get_value (&iter);
693 if (!bus_selinux_id_table_insert (new_table,
699 if (registry->service_sid_table)
700 _dbus_hash_table_unref (registry->service_sid_table);
701 registry->service_sid_table = new_table;
706 bus_service_unlink_owner (BusService *service,
709 _dbus_list_remove_last (&service->owners, owner);
710 bus_owner_unref (owner);
714 bus_service_unlink (BusService *service)
716 _dbus_assert (service->owners == NULL);
718 /* the service may not be in the hash, if
719 * the failure causing transaction cancel
720 * was in the right place, but that's OK
722 _dbus_hash_table_remove_string (service->registry->service_hash,
725 bus_service_unref (service);
729 bus_service_relink (BusService *service,
730 DBusPreallocatedHash *preallocated)
732 _dbus_assert (service->owners == NULL);
733 _dbus_assert (preallocated != NULL);
735 _dbus_hash_table_insert_string_preallocated (service->registry->service_hash,
740 bus_service_ref (service);
744 * Data used to represent an ownership cancellation in
749 BusOwner *owner; /**< the owner */
750 BusService *service; /**< service to cancel ownership of */
751 } OwnershipCancelData;
754 cancel_ownership (void *data)
756 OwnershipCancelData *d = data;
758 /* We don't need to send messages notifying of these
759 * changes, since we're reverting something that was
760 * cancelled (effectively never really happened)
762 bus_service_unlink_owner (d->service, d->owner);
764 if (d->service->owners == NULL)
765 bus_service_unlink (d->service);
769 free_ownership_cancel_data (void *data)
771 OwnershipCancelData *d = data;
773 dbus_connection_unref (d->owner->conn);
774 bus_owner_unref (d->owner);
775 bus_service_unref (d->service);
781 add_cancel_ownership_to_transaction (BusTransaction *transaction,
785 OwnershipCancelData *d;
787 d = dbus_new (OwnershipCancelData, 1);
791 d->service = service;
794 if (!bus_transaction_add_cancel_hook (transaction, cancel_ownership, d,
795 free_ownership_cancel_data))
801 bus_service_ref (d->service);
802 bus_owner_ref (owner);
803 dbus_connection_ref (d->owner->conn);
808 /* this function is self-cancelling if you cancel the transaction */
810 bus_service_add_owner (BusService *service,
811 DBusConnection *connection,
813 BusTransaction *transaction,
817 DBusList *bus_owner_link;
819 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
821 /* Send service acquired message first, OOM will result
822 * in cancelling the transaction
824 if (service->owners == NULL)
826 if (!bus_driver_send_service_acquired (connection, service->name, transaction, error))
830 bus_owner_link = _bus_service_find_owner_link (service, connection);
832 if (bus_owner_link == NULL)
834 bus_owner = bus_owner_new (service, connection, flags);
835 if (bus_owner == NULL)
841 bus_owner_set_flags (bus_owner, flags);
842 if (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || service->owners == NULL)
844 if (!_dbus_list_append (&service->owners,
847 bus_owner_unref (bus_owner);
854 if (!_dbus_list_insert_after (&service->owners,
855 _dbus_list_get_first_link (&service->owners),
858 bus_owner_unref (bus_owner);
866 /* Update the link since we are already in the queue
867 * No need for operations that can produce OOM
870 bus_owner = (BusOwner *) bus_owner_link->data;
871 if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
874 _dbus_list_unlink (&service->owners, bus_owner_link);
875 link = _dbus_list_get_first_link (&service->owners);
876 _dbus_assert (link != NULL);
878 _dbus_list_insert_after_link (&service->owners, link, bus_owner_link);
881 bus_owner_set_flags (bus_owner, flags);
885 if (!add_cancel_ownership_to_transaction (transaction,
889 bus_service_unlink_owner (service, bus_owner);
901 BusOwner *before_owner; /* restore to position before this connection in owners list */
902 DBusList *owner_link;
903 DBusList *service_link;
904 DBusPreallocatedHash *hash_entry;
905 } OwnershipRestoreData;
908 restore_ownership (void *data)
910 OwnershipRestoreData *d = data;
913 _dbus_assert (d->service_link != NULL);
914 _dbus_assert (d->owner_link != NULL);
916 if (d->service->owners == NULL)
918 _dbus_assert (d->hash_entry != NULL);
919 bus_service_relink (d->service, d->hash_entry);
923 _dbus_assert (d->hash_entry == NULL);
926 /* We don't need to send messages notifying of these
927 * changes, since we're reverting something that was
928 * cancelled (effectively never really happened)
930 link = _dbus_list_get_first_link (&d->service->owners);
933 if (link->data == d->before_owner)
936 link = _dbus_list_get_next_link (&d->service->owners, link);
939 _dbus_list_insert_before_link (&d->service->owners, link, d->owner_link);
941 /* Note that removing then restoring this changes the order in which
942 * ServiceDeleted messages are sent on destruction of the
943 * connection. This should be OK as the only guarantee there is
944 * that the base service is destroyed last, and we never even
945 * tentatively remove the base service.
947 bus_connection_add_owned_service_link (d->owner->conn, d->service_link);
949 d->hash_entry = NULL;
950 d->service_link = NULL;
951 d->owner_link = NULL;
955 free_ownership_restore_data (void *data)
957 OwnershipRestoreData *d = data;
960 _dbus_list_free_link (d->service_link);
962 _dbus_list_free_link (d->owner_link);
964 _dbus_hash_table_free_preallocated_entry (d->service->registry->service_hash,
967 dbus_connection_unref (d->owner->conn);
968 bus_owner_unref (d->owner);
969 bus_service_unref (d->service);
975 add_restore_ownership_to_transaction (BusTransaction *transaction,
979 OwnershipRestoreData *d;
982 d = dbus_new (OwnershipRestoreData, 1);
986 d->service = service;
988 d->service_link = _dbus_list_alloc_link (service);
989 d->owner_link = _dbus_list_alloc_link (owner);
990 d->hash_entry = _dbus_hash_table_preallocate_entry (service->registry->service_hash);
992 bus_service_ref (d->service);
993 bus_owner_ref (d->owner);
994 dbus_connection_ref (d->owner->conn);
996 d->before_owner = NULL;
997 link = _dbus_list_get_first_link (&service->owners);
1000 if (link->data == owner)
1002 link = _dbus_list_get_next_link (&service->owners, link);
1005 d->before_owner = link->data;
1010 link = _dbus_list_get_next_link (&service->owners, link);
1013 if (d->service_link == NULL ||
1014 d->owner_link == NULL ||
1015 d->hash_entry == NULL ||
1016 !bus_transaction_add_cancel_hook (transaction, restore_ownership, d,
1017 free_ownership_restore_data))
1019 free_ownership_restore_data (d);
1027 bus_service_swap_owner (BusService *service,
1028 DBusConnection *connection,
1029 BusTransaction *transaction,
1032 DBusList *swap_link;
1033 BusOwner *primary_owner;
1035 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1037 /* We send out notifications before we do any work we
1038 * might have to undo if the notification-sending failed
1041 /* Send service lost message */
1042 primary_owner = bus_service_get_primary_owner (service);
1043 if (primary_owner == NULL || primary_owner->conn != connection)
1044 _dbus_assert_not_reached ("Tried to swap a non primary owner");
1047 if (!bus_driver_send_service_lost (connection, service->name,
1048 transaction, error))
1051 if (service->owners == NULL)
1053 _dbus_assert_not_reached ("Tried to swap owner of a service that has no owners");
1055 else if (_dbus_list_length_is_one (&service->owners))
1057 _dbus_assert_not_reached ("Tried to swap owner of a service that has no other owners in the queue");
1062 BusOwner *new_owner;
1063 DBusConnection *new_owner_conn;
1064 link = _dbus_list_get_first_link (&service->owners);
1065 _dbus_assert (link != NULL);
1066 link = _dbus_list_get_next_link (&service->owners, link);
1067 _dbus_assert (link != NULL);
1069 new_owner = (BusOwner *)link->data;
1070 new_owner_conn = new_owner->conn;
1072 if (!bus_driver_send_service_owner_changed (service->name,
1073 bus_connection_get_name (connection),
1074 bus_connection_get_name (new_owner_conn),
1075 transaction, error))
1078 /* This will be our new owner */
1079 if (!bus_driver_send_service_acquired (new_owner_conn,
1086 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1088 BUS_SET_OOM (error);
1092 /* unlink the primary and make it the second link */
1093 swap_link = _dbus_list_get_first_link (&service->owners);
1094 _dbus_list_unlink (&service->owners, swap_link);
1096 _dbus_list_insert_after_link (&service->owners,
1097 _dbus_list_get_first_link (&service->owners),
1103 /* this function is self-cancelling if you cancel the transaction */
1105 bus_service_remove_owner (BusService *service,
1106 DBusConnection *connection,
1107 BusTransaction *transaction,
1110 BusOwner *primary_owner;
1112 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1114 /* We send out notifications before we do any work we
1115 * might have to undo if the notification-sending failed
1118 /* Send service lost message */
1119 primary_owner = bus_service_get_primary_owner (service);
1120 if (primary_owner != NULL && primary_owner->conn == connection)
1122 if (!bus_driver_send_service_lost (connection, service->name,
1123 transaction, error))
1128 /* if we are not the primary owner then just remove us from the queue */
1130 BusOwner *temp_owner;
1132 link = _bus_service_find_owner_link (service, connection);
1133 _dbus_list_unlink (&service->owners, link);
1134 temp_owner = (BusOwner *)link->data;
1135 bus_owner_unref (temp_owner);
1136 _dbus_list_free_link (link);
1141 if (service->owners == NULL)
1143 _dbus_assert_not_reached ("Tried to remove owner of a service that has no owners");
1145 else if (_dbus_list_length_is_one (&service->owners))
1147 if (!bus_driver_send_service_owner_changed (service->name,
1148 bus_connection_get_name (connection),
1150 transaction, error))
1156 BusOwner *new_owner;
1157 DBusConnection *new_owner_conn;
1158 link = _dbus_list_get_first_link (&service->owners);
1159 _dbus_assert (link != NULL);
1160 link = _dbus_list_get_next_link (&service->owners, link);
1161 _dbus_assert (link != NULL);
1163 new_owner = (BusOwner *)link->data;
1164 new_owner_conn = new_owner->conn;
1166 if (!bus_driver_send_service_owner_changed (service->name,
1167 bus_connection_get_name (connection),
1168 bus_connection_get_name (new_owner_conn),
1169 transaction, error))
1172 /* This will be our new owner */
1173 if (!bus_driver_send_service_acquired (new_owner_conn,
1180 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1182 BUS_SET_OOM (error);
1186 bus_service_unlink_owner (service, primary_owner);
1188 if (service->owners == NULL)
1189 bus_service_unlink (service);
1195 bus_service_ref (BusService *service)
1197 _dbus_assert (service->refcount > 0);
1199 service->refcount += 1;
1205 bus_service_unref (BusService *service)
1207 _dbus_assert (service->refcount > 0);
1209 service->refcount -= 1;
1211 if (service->refcount == 0)
1213 _dbus_assert (service->owners == NULL);
1215 dbus_free (service->name);
1216 _dbus_mem_pool_dealloc (service->registry->service_pool, service);
1221 bus_service_get_primary_owners_connection (BusService *service)
1225 owner = bus_service_get_primary_owner (service);
1234 bus_service_get_primary_owner (BusService *service)
1236 return _dbus_list_get_first (&service->owners);
1240 bus_service_get_name (BusService *service)
1242 return service->name;
1246 bus_service_get_allow_replacement (BusService *service)
1251 _dbus_assert (service->owners != NULL);
1253 link = _dbus_list_get_first_link (&service->owners);
1254 owner = (BusOwner *) link->data;
1256 return owner->allow_replacement;
1260 bus_service_has_owner (BusService *service,
1261 DBusConnection *connection)
1265 link = _bus_service_find_owner_link (service, connection);
1274 bus_service_list_queued_owners (BusService *service,
1275 DBusList **return_list,
1280 _dbus_assert (*return_list == NULL);
1282 link = _dbus_list_get_first_link (&service->owners);
1283 _dbus_assert (link != NULL);
1285 while (link != NULL)
1290 owner = (BusOwner *) link->data;
1291 uname = bus_connection_get_name (owner->conn);
1293 if (!_dbus_list_append (return_list, (char *)uname))
1296 link = _dbus_list_get_next_link (&service->owners, link);
1302 _dbus_list_clear (return_list);
1303 BUS_SET_OOM (error);