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 policy = bus_connection_get_policy (connection);
421 _dbus_assert (policy != NULL);
423 /* Note that if sid is #NULL then the bus's own context gets used
424 * in bus_connection_selinux_allows_acquire_service()
426 sid = bus_selinux_id_table_lookup (registry->service_sid_table,
429 if (!bus_selinux_allows_acquire_service (connection, sid,
430 _dbus_string_get_const_data (service_name), error))
433 if (dbus_error_is_set (error) &&
434 dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
439 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
440 "Connection \"%s\" is not allowed to own the service \"%s\" due "
442 bus_connection_is_active (connection) ?
443 bus_connection_get_name (connection) :
445 _dbus_string_get_const_data (service_name));
449 if (!bus_client_policy_check_can_own (policy, connection,
452 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
453 "Connection \"%s\" is not allowed to own the service \"%s\" due "
454 "to security policies in the configuration file",
455 bus_connection_is_active (connection) ?
456 bus_connection_get_name (connection) :
458 _dbus_string_get_const_data (service_name));
462 if (bus_connection_get_n_services_owned (connection) >=
463 bus_context_get_max_services_per_connection (registry->context))
465 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
466 "Connection \"%s\" is not allowed to own more services "
467 "(increase limits in configuration file if required)",
468 bus_connection_is_active (connection) ?
469 bus_connection_get_name (connection) :
474 service = bus_registry_lookup (registry, service_name);
478 primary_owner = bus_service_get_primary_owner (service);
479 if (primary_owner != NULL)
480 old_owner_conn = primary_owner->conn;
482 old_owner_conn = NULL;
485 old_owner_conn = NULL;
489 service = bus_registry_ensure (registry,
490 service_name, connection, flags,
496 primary_owner = bus_service_get_primary_owner (service);
497 if (primary_owner == NULL)
500 current_owner_conn = primary_owner->conn;
502 if (old_owner_conn == NULL)
504 _dbus_assert (current_owner_conn == connection);
506 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
508 else if (old_owner_conn == connection)
510 bus_owner_set_flags (primary_owner, flags);
511 *result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
513 else if (((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
514 !(bus_service_get_allow_replacement (service))) ||
515 ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
516 !(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)))
519 BusOwner *temp_owner;
520 /* Since we can't be queued if we are already in the queue
523 link = _bus_service_find_owner_link (service, connection);
526 _dbus_list_unlink (&service->owners, link);
527 temp_owner = (BusOwner *)link->data;
528 bus_owner_unref (temp_owner);
529 _dbus_list_free_link (link);
532 *result = DBUS_REQUEST_NAME_REPLY_EXISTS;
534 else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
535 (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
536 !(bus_service_get_allow_replacement (service))))
538 /* Queue the connection */
539 if (!bus_service_add_owner (service, connection,
544 *result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
548 /* Replace the current owner */
550 /* We enqueue the new owner and remove the first one because
551 * that will cause NameAcquired and NameLost messages to
555 if (!bus_service_add_owner (service, connection,
560 if (primary_owner->do_not_queue)
562 if (!bus_service_remove_owner (service, old_owner_conn,
568 if (!bus_service_swap_owner (service, old_owner_conn,
574 _dbus_assert (connection == bus_service_get_primary_owner (service)->conn);
575 *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
578 activation = bus_context_get_activation (registry->context);
579 retval = bus_activation_send_pending_auto_activation_messages (activation,
589 bus_registry_release_service (BusRegistry *registry,
590 DBusConnection *connection,
591 const DBusString *service_name,
592 dbus_uint32_t *result,
593 BusTransaction *transaction,
601 if (!_dbus_validate_bus_name (service_name, 0,
602 _dbus_string_get_length (service_name)))
604 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
605 "Given bus name \"%s\" is not valid",
606 _dbus_string_get_const_data (service_name));
608 _dbus_verbose ("Attempt to release invalid service name\n");
613 if (_dbus_string_get_byte (service_name, 0) == ':')
615 /* Not allowed; the base service name cannot be created or released */
616 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
617 "Cannot release a service starting with ':' such as \"%s\"",
618 _dbus_string_get_const_data (service_name));
620 _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
621 _dbus_string_get_const_data (service_name));
626 service = bus_registry_lookup (registry, service_name);
630 *result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
632 else if (!bus_service_has_owner (service, connection))
634 *result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
638 if (!bus_service_remove_owner (service, connection,
642 _dbus_assert (!bus_service_has_owner (service, connection));
643 *result = DBUS_RELEASE_NAME_REPLY_RELEASED;
653 bus_registry_set_service_context_table (BusRegistry *registry,
654 DBusHashTable *table)
656 DBusHashTable *new_table;
659 new_table = bus_selinux_id_table_new ();
663 _dbus_hash_iter_init (table, &iter);
664 while (_dbus_hash_iter_next (&iter))
666 const char *service = _dbus_hash_iter_get_string_key (&iter);
667 const char *context = _dbus_hash_iter_get_value (&iter);
669 if (!bus_selinux_id_table_insert (new_table,
675 if (registry->service_sid_table)
676 _dbus_hash_table_unref (registry->service_sid_table);
677 registry->service_sid_table = new_table;
682 bus_service_unlink_owner (BusService *service,
685 _dbus_list_remove_last (&service->owners, owner);
686 bus_owner_unref (owner);
690 bus_service_unlink (BusService *service)
692 _dbus_assert (service->owners == NULL);
694 /* the service may not be in the hash, if
695 * the failure causing transaction cancel
696 * was in the right place, but that's OK
698 _dbus_hash_table_remove_string (service->registry->service_hash,
701 bus_service_unref (service);
705 bus_service_relink (BusService *service,
706 DBusPreallocatedHash *preallocated)
708 _dbus_assert (service->owners == NULL);
709 _dbus_assert (preallocated != NULL);
711 _dbus_hash_table_insert_string_preallocated (service->registry->service_hash,
716 bus_service_ref (service);
720 * Data used to represent an ownership cancellation in
725 BusOwner *owner; /**< the owner */
726 BusService *service; /**< service to cancel ownership of */
727 } OwnershipCancelData;
730 cancel_ownership (void *data)
732 OwnershipCancelData *d = data;
734 /* We don't need to send messages notifying of these
735 * changes, since we're reverting something that was
736 * cancelled (effectively never really happened)
738 bus_service_unlink_owner (d->service, d->owner);
740 if (d->service->owners == NULL)
741 bus_service_unlink (d->service);
745 free_ownership_cancel_data (void *data)
747 OwnershipCancelData *d = data;
749 dbus_connection_unref (d->owner->conn);
750 bus_owner_unref (d->owner);
751 bus_service_unref (d->service);
757 add_cancel_ownership_to_transaction (BusTransaction *transaction,
761 OwnershipCancelData *d;
763 d = dbus_new (OwnershipCancelData, 1);
767 d->service = service;
770 if (!bus_transaction_add_cancel_hook (transaction, cancel_ownership, d,
771 free_ownership_cancel_data))
777 bus_service_ref (d->service);
778 bus_owner_ref (owner);
779 dbus_connection_ref (d->owner->conn);
784 /* this function is self-cancelling if you cancel the transaction */
786 bus_service_add_owner (BusService *service,
787 DBusConnection *connection,
789 BusTransaction *transaction,
793 DBusList *bus_owner_link;
795 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
797 /* Send service acquired message first, OOM will result
798 * in cancelling the transaction
800 if (service->owners == NULL)
802 if (!bus_driver_send_service_acquired (connection, service->name, transaction, error))
806 bus_owner_link = _bus_service_find_owner_link (service, connection);
808 if (bus_owner_link == NULL)
810 bus_owner = bus_owner_new (service, connection, flags);
811 if (bus_owner == NULL)
817 bus_owner_set_flags (bus_owner, flags);
818 if (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || service->owners == NULL)
820 if (!_dbus_list_append (&service->owners,
823 bus_owner_unref (bus_owner);
830 if (!_dbus_list_insert_after (&service->owners,
831 _dbus_list_get_first_link (&service->owners),
834 bus_owner_unref (bus_owner);
842 /* Update the link since we are already in the queue
843 * No need for operations that can produce OOM
846 bus_owner = (BusOwner *) bus_owner_link->data;
847 if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
850 _dbus_list_unlink (&service->owners, bus_owner_link);
851 link = _dbus_list_get_first_link (&service->owners);
852 _dbus_assert (link != NULL);
854 _dbus_list_insert_after_link (&service->owners, link, bus_owner_link);
857 bus_owner_set_flags (bus_owner, flags);
861 if (!add_cancel_ownership_to_transaction (transaction,
865 bus_service_unlink_owner (service, bus_owner);
877 BusOwner *before_owner; /* restore to position before this connection in owners list */
878 DBusList *owner_link;
879 DBusList *service_link;
880 DBusPreallocatedHash *hash_entry;
881 } OwnershipRestoreData;
884 restore_ownership (void *data)
886 OwnershipRestoreData *d = data;
889 _dbus_assert (d->service_link != NULL);
890 _dbus_assert (d->owner_link != NULL);
892 if (d->service->owners == NULL)
894 _dbus_assert (d->hash_entry != NULL);
895 bus_service_relink (d->service, d->hash_entry);
899 _dbus_assert (d->hash_entry == NULL);
902 /* We don't need to send messages notifying of these
903 * changes, since we're reverting something that was
904 * cancelled (effectively never really happened)
906 link = _dbus_list_get_first_link (&d->service->owners);
909 if (link->data == d->before_owner)
912 link = _dbus_list_get_next_link (&d->service->owners, link);
915 _dbus_list_insert_before_link (&d->service->owners, link, d->owner_link);
917 /* Note that removing then restoring this changes the order in which
918 * ServiceDeleted messages are sent on destruction of the
919 * connection. This should be OK as the only guarantee there is
920 * that the base service is destroyed last, and we never even
921 * tentatively remove the base service.
923 bus_connection_add_owned_service_link (d->owner->conn, d->service_link);
925 d->hash_entry = NULL;
926 d->service_link = NULL;
927 d->owner_link = NULL;
931 free_ownership_restore_data (void *data)
933 OwnershipRestoreData *d = data;
936 _dbus_list_free_link (d->service_link);
938 _dbus_list_free_link (d->owner_link);
940 _dbus_hash_table_free_preallocated_entry (d->service->registry->service_hash,
943 dbus_connection_unref (d->owner->conn);
944 bus_owner_unref (d->owner);
945 bus_service_unref (d->service);
951 add_restore_ownership_to_transaction (BusTransaction *transaction,
955 OwnershipRestoreData *d;
958 d = dbus_new (OwnershipRestoreData, 1);
962 d->service = service;
964 d->service_link = _dbus_list_alloc_link (service);
965 d->owner_link = _dbus_list_alloc_link (owner);
966 d->hash_entry = _dbus_hash_table_preallocate_entry (service->registry->service_hash);
968 bus_service_ref (d->service);
969 bus_owner_ref (d->owner);
970 dbus_connection_ref (d->owner->conn);
972 d->before_owner = NULL;
973 link = _dbus_list_get_first_link (&service->owners);
976 if (link->data == owner)
978 link = _dbus_list_get_next_link (&service->owners, link);
981 d->before_owner = link->data;
986 link = _dbus_list_get_next_link (&service->owners, link);
989 if (d->service_link == NULL ||
990 d->owner_link == NULL ||
991 d->hash_entry == NULL ||
992 !bus_transaction_add_cancel_hook (transaction, restore_ownership, d,
993 free_ownership_restore_data))
995 free_ownership_restore_data (d);
1003 bus_service_swap_owner (BusService *service,
1004 DBusConnection *connection,
1005 BusTransaction *transaction,
1008 DBusList *swap_link;
1009 BusOwner *primary_owner;
1011 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1013 /* We send out notifications before we do any work we
1014 * might have to undo if the notification-sending failed
1017 /* Send service lost message */
1018 primary_owner = bus_service_get_primary_owner (service);
1019 if (primary_owner == NULL || primary_owner->conn != connection)
1020 _dbus_assert_not_reached ("Tried to swap a non primary owner");
1023 if (!bus_driver_send_service_lost (connection, service->name,
1024 transaction, error))
1027 if (service->owners == NULL)
1029 _dbus_assert_not_reached ("Tried to swap owner of a service that has no owners");
1031 else if (_dbus_list_length_is_one (&service->owners))
1033 _dbus_assert_not_reached ("Tried to swap owner of a service that has no other owners in the queue");
1038 BusOwner *new_owner;
1039 DBusConnection *new_owner_conn;
1040 link = _dbus_list_get_first_link (&service->owners);
1041 _dbus_assert (link != NULL);
1042 link = _dbus_list_get_next_link (&service->owners, link);
1043 _dbus_assert (link != NULL);
1045 new_owner = (BusOwner *)link->data;
1046 new_owner_conn = new_owner->conn;
1048 if (!bus_driver_send_service_owner_changed (service->name,
1049 bus_connection_get_name (connection),
1050 bus_connection_get_name (new_owner_conn),
1051 transaction, error))
1054 /* This will be our new owner */
1055 if (!bus_driver_send_service_acquired (new_owner_conn,
1062 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1064 BUS_SET_OOM (error);
1068 /* unlink the primary and make it the second link */
1069 swap_link = _dbus_list_get_first_link (&service->owners);
1070 _dbus_list_unlink (&service->owners, swap_link);
1072 _dbus_list_insert_after_link (&service->owners,
1073 _dbus_list_get_first_link (&service->owners),
1079 /* this function is self-cancelling if you cancel the transaction */
1081 bus_service_remove_owner (BusService *service,
1082 DBusConnection *connection,
1083 BusTransaction *transaction,
1086 BusOwner *primary_owner;
1088 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1090 /* We send out notifications before we do any work we
1091 * might have to undo if the notification-sending failed
1094 /* Send service lost message */
1095 primary_owner = bus_service_get_primary_owner (service);
1096 if (primary_owner != NULL && primary_owner->conn == connection)
1098 if (!bus_driver_send_service_lost (connection, service->name,
1099 transaction, error))
1104 /* if we are not the primary owner then just remove us from the queue */
1106 BusOwner *temp_owner;
1108 link = _bus_service_find_owner_link (service, connection);
1109 _dbus_list_unlink (&service->owners, link);
1110 temp_owner = (BusOwner *)link->data;
1111 bus_owner_unref (temp_owner);
1112 _dbus_list_free_link (link);
1117 if (service->owners == NULL)
1119 _dbus_assert_not_reached ("Tried to remove owner of a service that has no owners");
1121 else if (_dbus_list_length_is_one (&service->owners))
1123 if (!bus_driver_send_service_owner_changed (service->name,
1124 bus_connection_get_name (connection),
1126 transaction, error))
1132 BusOwner *new_owner;
1133 DBusConnection *new_owner_conn;
1134 link = _dbus_list_get_first_link (&service->owners);
1135 _dbus_assert (link != NULL);
1136 link = _dbus_list_get_next_link (&service->owners, link);
1137 _dbus_assert (link != NULL);
1139 new_owner = (BusOwner *)link->data;
1140 new_owner_conn = new_owner->conn;
1142 if (!bus_driver_send_service_owner_changed (service->name,
1143 bus_connection_get_name (connection),
1144 bus_connection_get_name (new_owner_conn),
1145 transaction, error))
1148 /* This will be our new owner */
1149 if (!bus_driver_send_service_acquired (new_owner_conn,
1156 if (!add_restore_ownership_to_transaction (transaction, service, primary_owner))
1158 BUS_SET_OOM (error);
1162 bus_service_unlink_owner (service, primary_owner);
1164 if (service->owners == NULL)
1165 bus_service_unlink (service);
1171 bus_service_ref (BusService *service)
1173 _dbus_assert (service->refcount > 0);
1175 service->refcount += 1;
1181 bus_service_unref (BusService *service)
1183 _dbus_assert (service->refcount > 0);
1185 service->refcount -= 1;
1187 if (service->refcount == 0)
1189 _dbus_assert (service->owners == NULL);
1191 dbus_free (service->name);
1192 _dbus_mem_pool_dealloc (service->registry->service_pool, service);
1197 bus_service_get_primary_owners_connection (BusService *service)
1201 owner = bus_service_get_primary_owner (service);
1210 bus_service_get_primary_owner (BusService *service)
1212 return _dbus_list_get_first (&service->owners);
1216 bus_service_get_name (BusService *service)
1218 return service->name;
1222 bus_service_get_allow_replacement (BusService *service)
1227 _dbus_assert (service->owners != NULL);
1229 link = _dbus_list_get_first_link (&service->owners);
1230 owner = (BusOwner *) link->data;
1232 return owner->allow_replacement;
1236 bus_service_has_owner (BusService *service,
1237 DBusConnection *connection)
1241 link = _bus_service_find_owner_link (service, connection);
1250 bus_service_list_queued_owners (BusService *service,
1251 DBusList **return_list,
1256 _dbus_assert (*return_list == NULL);
1258 link = _dbus_list_get_first_link (&service->owners);
1259 _dbus_assert (link != NULL);
1261 while (link != NULL)
1266 owner = (BusOwner *) link->data;
1267 uname = bus_connection_get_name (owner->conn);
1269 if (!_dbus_list_append (return_list, uname))
1272 link = _dbus_list_get_next_link (&service->owners, link);
1278 _dbus_list_clear (return_list);
1279 BUS_SET_OOM (error);