c07b20fd132c70bdf19b28d755c8f2818eb5f1e1
[platform/upstream/dbus.git] / bus / services.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* services.c  Service management
3  *
4  * Copyright (C) 2003  Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23 #include "services.h"
24 #include "connection.h"
25 #include <dbus/dbus-hash.h>
26 #include <dbus/dbus-list.h>
27 #include <dbus/dbus-mempool.h>
28
29 struct BusService
30 {
31   char *name;
32   DBusList *owners;
33 };
34
35 static DBusHashTable *service_hash = NULL;
36 static DBusMemPool   *service_pool = NULL;
37
38 BusService*
39 bus_service_lookup (const DBusString *service_name,
40                     dbus_bool_t       create_if_not_found)
41 {
42   const char *c_name;
43   BusService *service;
44   
45   if (service_hash == NULL)
46     {
47       service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
48                                            NULL, NULL);
49       service_pool = _dbus_mem_pool_new (sizeof (BusService),
50                                          TRUE);
51
52       if (service_hash == NULL || service_pool == NULL)
53         {
54           if (service_hash)
55             {
56               _dbus_hash_table_unref (service_hash);
57               service_hash = NULL;
58             }
59           if (service_pool)
60             {
61               _dbus_mem_pool_free (service_pool);
62               service_pool = NULL;
63             }
64           return NULL;
65         }
66     }
67   
68   _dbus_string_get_const_data (service_name, &c_name);
69
70   service = _dbus_hash_table_lookup_string (service_hash,
71                                             c_name);
72   if (service != NULL)
73     return service;
74
75   if (!create_if_not_found)
76     return NULL;
77   
78   service = _dbus_mem_pool_alloc (service_pool);
79   if (service == NULL)
80     return NULL;
81
82   service->name = _dbus_strdup (c_name);
83   if (service->name == NULL)
84     {
85       _dbus_mem_pool_dealloc (service_pool, service);
86       return NULL;
87     }
88
89   if (!_dbus_hash_table_insert_string (service_hash,
90                                        service->name,
91                                        service))
92     {
93       dbus_free (service->name);
94       _dbus_mem_pool_dealloc (service_pool, service);
95       return NULL;
96     }
97
98   return service;
99 }
100
101 void
102 bus_service_free (BusService *service)
103 {
104   _dbus_assert (service->owners == NULL);
105
106   _dbus_hash_table_remove_string (service_hash, service->name);
107   
108   dbus_free (service->name);
109   _dbus_mem_pool_dealloc (service_pool, service);
110 }
111
112 dbus_bool_t
113 bus_service_add_owner (BusService     *service,
114                        DBusConnection *owner)
115 {
116   if (!_dbus_list_append (&service->owners,
117                           owner))
118     return FALSE;
119
120   if (!bus_connection_add_owned_service (owner, service))
121     {
122       _dbus_list_remove_last (&service->owners, owner);
123       return FALSE;
124     }
125
126   return TRUE;
127 }
128
129 void
130 bus_service_remove_owner (BusService     *service,
131                           DBusConnection *owner)
132 {
133   _dbus_list_remove_last (&service->owners, owner);
134   bus_connection_remove_owned_service (owner, service);
135 }
136
137 DBusConnection*
138 bus_service_get_primary_owner (BusService *service)
139 {
140   return _dbus_list_get_first (&service->owners);
141 }
142
143 const char*
144 bus_service_get_name (BusService *service)
145 {
146   return service->name;
147 }
148
149 void
150 bus_service_foreach (BusServiceForeachFunction  function,
151                      void                      *data)
152 {
153   DBusHashIter iter;
154   
155   if (service_hash == NULL)
156     return;
157   
158   _dbus_hash_iter_init (service_hash, &iter);
159   while (_dbus_hash_iter_next (&iter))
160     {
161       BusService *service = _dbus_hash_iter_get_value (&iter);
162
163       (* function) (service, data);
164     }
165 }