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, service_name))
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 if (old_owner_conn == NULL)
514 _dbus_assert (primary_owner->conn == connection);
516 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
518 else if (old_owner_conn == connection)
520 bus_owner_set_flags (primary_owner, flags);
521 *result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
523 else if (((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
524 !(bus_service_get_allow_replacement (service))) ||
525 ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
526 !(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)))
529 BusOwner *temp_owner;
530 /* Since we can't be queued if we are already in the queue
533 link = _bus_service_find_owner_link (service, connection);
536 _dbus_list_unlink (&service->owners, link);
537 temp_owner = (BusOwner *)link->data;
538 bus_owner_unref (temp_owner);
539 _dbus_list_free_link (link);
542 *result = DBUS_REQUEST_NAME_REPLY_EXISTS;
544 else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
545 (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
546 !(bus_service_get_allow_replacement (service))))
548 /* Queue the connection */
549 if (!bus_service_add_owner (service, connection,
554 *result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
558 /* Replace the current owner */
560 /* We enqueue the new owner and remove the first one because
561 * that will cause NameAcquired and NameLost messages to
565 if (!bus_service_add_owner (service, connection,
570 if (primary_owner->do_not_queue)
572 if (!bus_service_remove_owner (service, old_owner_conn,
578 if (!bus_service_swap_owner (service, old_owner_conn,
584 _dbus_assert (connection == bus_service_get_primary_owner (service)->conn);
585 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
588 activation = bus_context_get_activation (registry->context);
589 retval = bus_activation_send_pending_auto_activation_messages (activation,
599 bus_registry_release_service (BusRegistry *registry,
600 DBusConnection *connection,
601 const DBusString *service_name,
602 dbus_uint32_t *result,
603 BusTransaction *transaction,
611 if (!_dbus_validate_bus_name (service_name, 0,
612 _dbus_string_get_length (service_name)))
614 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
615 "Given bus name \"%s\" is not valid",
616 _dbus_string_get_const_data (service_name));
618 _dbus_verbose ("Attempt to release invalid service name\n");
623 if (_dbus_string_get_byte (service_name, 0) == ':')
625 /* Not allowed; the base service name cannot be created or released */
626 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
627 "Cannot release a service starting with ':' such as \"%s\"",
628 _dbus_string_get_const_data (service_name));
630 _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
631 _dbus_string_get_const_data (service_name));
636 if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
638 /* Not allowed; the base service name cannot be created or released */
639 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
640 "Cannot release the %s service because it is owned by the bus",
643 _dbus_verbose ("Attempt to release service name \"%s\"",
649 service = bus_registry_lookup (registry, service_name);
653 *result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
655 else if (!bus_service_has_owner (service, connection))
657 *result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
661 if (!bus_service_remove_owner (service, connection,
665 _dbus_assert (!bus_service_has_owner (service, connection));
666 *result = DBUS_RELEASE_NAME_REPLY_RELEASED;
676 bus_registry_set_service_context_table (BusRegistry *registry,
677 DBusHashTable *table)
679 DBusHashTable *new_table;
682 new_table = bus_selinux_id_table_new ();
686 _dbus_hash_iter_init (table, &iter);
687 while (_dbus_hash_iter_next (&iter))
689 const char *service = _dbus_hash_iter_get_string_key (&iter);
690 const char *context = _dbus_hash_iter_get_value (&iter);
692 if (!bus_selinux_id_table_insert (new_table,
698 if (registry->service_sid_table)
699 _dbus_hash_table_unref (registry->service_sid_table);
700 registry->service_sid_table = new_table;
705 bus_service_unlink_owner (BusService *service,
708 _dbus_list_remove_last (&service->owners, owner);
709 bus_owner_unref (owner);
713 bus_service_unlink (BusService *service)
715 _dbus_assert (service->owners == NULL);
717 /* the service may not be in the hash, if
718 * the failure causing transaction cancel
719 * was in the right place, but that's OK
721 _dbus_hash_table_remove_string (service->registry->service_hash,
724 bus_service_unref (service);
728 bus_service_relink (BusService *service,
729 DBusPreallocatedHash *preallocated)
731 _dbus_assert (service->owners == NULL);
732 _dbus_assert (preallocated != NULL);
734 _dbus_hash_table_insert_string_preallocated (service->registry->service_hash,
739 bus_service_ref (service);
743 * Data used to represent an ownership cancellation in
748 BusOwner *owner; /**< the owner */
749 BusService *service; /**< service to cancel ownership of */
750 } OwnershipCancelData;
753 cancel_ownership (void *data)
755 OwnershipCancelData *d = data;
757 /* We don't need to send messages notifying of these
758 * changes, since we're reverting something that was
759 * cancelled (effectively never really happened)
761 bus_service_unlink_owner (d->service, d->owner);
763 if (d->service->owners == NULL)
764 bus_service_unlink (d->service);
768 free_ownership_cancel_data (void *data)
770 OwnershipCancelData *d = data;
772 dbus_connection_unref (d->owner->conn);
773 bus_owner_unref (d->owner);
774 bus_service_unref (d->service);
780 add_cancel_ownership_to_transaction (BusTransaction *transaction,
784 OwnershipCancelData *d;
786 d = dbus_new (OwnershipCancelData, 1);
790 d->service = service;
793 if (!bus_transaction_add_cancel_hook (transaction, cancel_ownership, d,
794 free_ownership_cancel_data))
800 bus_service_ref (d->service);
801 bus_owner_ref (owner);
802 dbus_connection_ref (d->owner->conn);
807 /* this function is self-cancelling if you cancel the transaction */
809 bus_service_add_owner (BusService *service,
810 DBusConnection *connection,
812 BusTransaction *transaction,
816 DBusList *bus_owner_link;
818 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
820 /* Send service acquired message first, OOM will result
821 * in cancelling the transaction
823 if (service->owners == NULL)
825 if (!bus_driver_send_service_acquired (connection, service->name, transaction, error))
829 bus_owner_link = _bus_service_find_owner_link (service, connection);
831 if (bus_owner_link == NULL)
833 bus_owner = bus_owner_new (service, connection, flags);
834 if (bus_owner == NULL)
840 bus_owner_set_flags (bus_owner, flags);
841 if (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || service->owners == NULL)
843 if (!_dbus_list_append (&service->owners,
846 bus_owner_unref (bus_owner);
853 if (!_dbus_list_insert_after (&service->owners,
854 _dbus_list_get_first_link (&service->owners),
857 bus_owner_unref (bus_owner);
865 /* Update the link since we are already in the queue
866 * No need for operations that can produce OOM
869 bus_owner = (BusOwner *) bus_owner_link->data;
870 if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
873 _dbus_list_unlink (&service->owners, bus_owner_link);
874 link = _dbus_list_get_first_link (&service->owners);
875 _dbus_assert (link != NULL);
877 _dbus_list_insert_after_link (&service->owners, link, bus_owner_link);
880 bus_owner_set_flags (bus_owner, flags);
884 if (!add_cancel_ownership_to_transaction (transaction,
888 bus_service_unlink_owner (service, bus_owner);
900 BusOwner *before_owner; /* restore to position before this connection in owners list */
901 DBusList *owner_link;
902 DBusList *service_link;
903 DBusPreallocatedHash *hash_entry;
904 } OwnershipRestoreData;
907 restore_ownership (void *data)
909 OwnershipRestoreData *d = data;
912 _dbus_assert (d->service_link != NULL);
913 _dbus_assert (d->owner_link != NULL);
915 if (d->service->owners == NULL)
917 _dbus_assert (d->hash_entry != NULL);
918 bus_service_relink (d->service, d->hash_entry);
922 _dbus_assert (d->hash_entry == NULL);
925 /* We don't need to send messages notifying of these
926 * changes, since we're reverting something that was
927 * cancelled (effectively never really happened)
929 link = _dbus_list_get_first_link (&d->service->owners);
932 if (link->data == d->before_owner)
935 link = _dbus_list_get_next_link (&d->service->owners, link);
938 _dbus_list_insert_before_link (&d->service->owners, link, d->owner_link);
940 /* Note that removing then restoring this changes the order in which
941 * ServiceDeleted messages are sent on destruction of the
942 * connection. This should be OK as the only guarantee there is
943 * that the base service is destroyed last, and we never even
944 * tentatively remove the base service.
946 bus_connection_add_owned_service_link (d->owner->conn, d->service_link);
948 d->hash_entry = NULL;
949 d->service_link = NULL;
950 d->owner_link = NULL;
954 free_ownership_restore_data (void *data)
956 OwnershipRestoreData *d = data;
959 _dbus_list_free_link (d->service_link);
961 _dbus_list_free_link (d->owner_link);
963 _dbus_hash_table_free_preallocated_entry (d->service->registry->service_hash,
966 dbus_connection_unref (d->owner->conn);
967 bus_owner_unref (d->owner);
968 bus_service_unref (d->service);
974 add_restore_ownership_to_transaction (BusTransaction *transaction,
978 OwnershipRestoreData *d;
981 d = dbus_new (OwnershipRestoreData, 1);
985 d->service = service;
987 d->service_link = _dbus_list_alloc_link (service);
988 d->owner_link = _dbus_list_alloc_link (owner);
989 d->hash_entry = _dbus_hash_table_preallocate_entry (service->registry->service_hash);
991 bus_service_ref (d->service);
992 bus_owner_ref (d->owner);
993 dbus_connection_ref (d->owner->conn);
995 d->before_owner = NULL;
996 link = _dbus_list_get_first_link (&service->owners);
999 if (link->data == owner)
1001 link = _dbus_list_get_next_link (&service->owners, link);
1004 d->before_owner = link->data;
1009 link = _dbus_list_get_next_link (&service->owners, link);
1012 if (d->service_link == NULL ||
1013 d->owner_link == NULL ||
1014 d->hash_entry == NULL ||
1015 !bus_transaction_add_cancel_hook (transaction, restore_ownership, d,
1016 free_ownership_restore_data))
1018 free_ownership_restore_data (d);
1026 bus_service_swap_owner (BusService *service,
1027 DBusConnection *connection,
1028 BusTransaction *transaction,
1031 DBusList *swap_link;
1032 BusOwner *primary_owner;
1034 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1036 /* We send out notifications before we do any work we
1037 * might have to undo if the notification-sending failed
1040 /* Send service lost message */
1041 primary_owner = bus_service_get_primary_owner (service);
1042 if (primary_owner == NULL || primary_owner->conn != connection)
1043 _dbus_assert_not_reached ("Tried to swap a non primary owner");
1046 if (!bus_driver_send_service_lost (connection, service->name,
1047 transaction, error))
1050 if (service->owners == NULL)
1052 _dbus_assert_not_reached ("Tried to swap owner of a service that has no owners");
1054 else if (_dbus_list_length_is_one (&service->owners))
1056 _dbus_assert_not_reached ("Tried to swap owner of a service that has no other owners in the queue");
1061 BusOwner *new_owner;
1062 DBusConnection *new_owner_conn;
1063 link = _dbus_list_get_first_link (&service->owners);
1064 _dbus_assert (link != NULL);
1065 link = _dbus_list_get_next_link (&service->owners, link);
1066 _dbus_assert (link != NULL);
1068 new_owner = (BusOwner *)link->data;
1069 new_owner_conn = new_owner->conn;
1071 if (!bus_driver_send_service_owner_changed (service->name,
1072 bus_connection_get_name (connection),
1073 bus_connection_get_name (new_owner_conn),
1074 transaction, error))
1077 /* This will be our new owner */
1078 if (!bus_driver_send_service_acquired (new_owner_conn,
1085 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1087 BUS_SET_OOM (error);
1091 /* unlink the primary and make it the second link */
1092 swap_link = _dbus_list_get_first_link (&service->owners);
1093 _dbus_list_unlink (&service->owners, swap_link);
1095 _dbus_list_insert_after_link (&service->owners,
1096 _dbus_list_get_first_link (&service->owners),
1102 /* this function is self-cancelling if you cancel the transaction */
1104 bus_service_remove_owner (BusService *service,
1105 DBusConnection *connection,
1106 BusTransaction *transaction,
1109 BusOwner *primary_owner;
1111 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1113 /* We send out notifications before we do any work we
1114 * might have to undo if the notification-sending failed
1117 /* Send service lost message */
1118 primary_owner = bus_service_get_primary_owner (service);
1119 if (primary_owner != NULL && primary_owner->conn == connection)
1121 if (!bus_driver_send_service_lost (connection, service->name,
1122 transaction, error))
1127 /* if we are not the primary owner then just remove us from the queue */
1129 BusOwner *temp_owner;
1131 link = _bus_service_find_owner_link (service, connection);
1132 _dbus_list_unlink (&service->owners, link);
1133 temp_owner = (BusOwner *)link->data;
1134 bus_owner_unref (temp_owner);
1135 _dbus_list_free_link (link);
1140 if (service->owners == NULL)
1142 _dbus_assert_not_reached ("Tried to remove owner of a service that has no owners");
1144 else if (_dbus_list_length_is_one (&service->owners))
1146 if (!bus_driver_send_service_owner_changed (service->name,
1147 bus_connection_get_name (connection),
1149 transaction, error))
1155 BusOwner *new_owner;
1156 DBusConnection *new_owner_conn;
1157 link = _dbus_list_get_first_link (&service->owners);
1158 _dbus_assert (link != NULL);
1159 link = _dbus_list_get_next_link (&service->owners, link);
1160 _dbus_assert (link != NULL);
1162 new_owner = (BusOwner *)link->data;
1163 new_owner_conn = new_owner->conn;
1165 if (!bus_driver_send_service_owner_changed (service->name,
1166 bus_connection_get_name (connection),
1167 bus_connection_get_name (new_owner_conn),
1168 transaction, error))
1171 /* This will be our new owner */
1172 if (!bus_driver_send_service_acquired (new_owner_conn,
1179 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1181 BUS_SET_OOM (error);
1185 bus_service_unlink_owner (service, primary_owner);
1187 if (service->owners == NULL)
1188 bus_service_unlink (service);
1194 bus_service_ref (BusService *service)
1196 _dbus_assert (service->refcount > 0);
1198 service->refcount += 1;
1204 bus_service_unref (BusService *service)
1206 _dbus_assert (service->refcount > 0);
1208 service->refcount -= 1;
1210 if (service->refcount == 0)
1212 _dbus_assert (service->owners == NULL);
1214 dbus_free (service->name);
1215 _dbus_mem_pool_dealloc (service->registry->service_pool, service);
1220 bus_service_get_primary_owners_connection (BusService *service)
1224 owner = bus_service_get_primary_owner (service);
1233 bus_service_get_primary_owner (BusService *service)
1235 return _dbus_list_get_first (&service->owners);
1239 bus_service_get_name (BusService *service)
1241 return service->name;
1245 bus_service_get_allow_replacement (BusService *service)
1250 _dbus_assert (service->owners != NULL);
1252 link = _dbus_list_get_first_link (&service->owners);
1253 owner = (BusOwner *) link->data;
1255 return owner->allow_replacement;
1259 bus_service_has_owner (BusService *service,
1260 DBusConnection *connection)
1264 link = _bus_service_find_owner_link (service, connection);
1273 bus_service_list_queued_owners (BusService *service,
1274 DBusList **return_list,
1279 _dbus_assert (*return_list == NULL);
1281 link = _dbus_list_get_first_link (&service->owners);
1282 _dbus_assert (link != NULL);
1284 while (link != NULL)
1289 owner = (BusOwner *) link->data;
1290 uname = bus_connection_get_name (owner->conn);
1292 if (!_dbus_list_append (return_list, (char *)uname))
1295 link = _dbus_list_get_next_link (&service->owners, link);
1301 _dbus_list_clear (return_list);
1302 BUS_SET_OOM (error);