2003-01-05 Havoc Pennington <hp@pobox.com>
[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 dbus_bool_t
102 bus_service_add_owner (BusService     *service,
103                        DBusConnection *owner)
104 {
105   if (!_dbus_list_append (&service->owners,
106                           owner))
107     return FALSE;
108
109   if (!bus_connection_add_owned_service (owner, service))
110     {
111       _dbus_list_remove_last (&service->owners, owner);
112       return FALSE;
113     }
114
115   return TRUE;
116 }
117
118 void
119 bus_service_remove_owner (BusService     *service,
120                           DBusConnection *owner)
121 {
122   _dbus_list_remove_last (&service->owners, owner);
123   bus_connection_remove_owned_service (owner, service);
124 }
125
126 DBusConnection*
127 bus_service_get_primary_owner (BusService *service)
128 {
129   return _dbus_list_get_first (&service->owners);
130 }
131
132 const char*
133 bus_service_get_name (BusService *service)
134 {
135   return service->name;
136 }
137
138 void
139 bus_service_foreach (BusServiceForeachFunction  function,
140                      void                      *data)
141 {
142   DBusHashIter iter;
143   
144   if (service_hash == NULL)
145     return;
146   
147   _dbus_hash_iter_init (service_hash, &iter);
148   while (_dbus_hash_iter_next (&iter))
149     {
150       BusService *service = _dbus_hash_iter_get_value (&iter);
151
152       (* function) (service, data);
153     }
154 }