2002-11-24 Havoc Pennington <hp@pobox.com>
[platform/upstream/dbus.git] / dbus / dbus-server.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-server.c DBusServer object
3  *
4  * Copyright (C) 2002  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 "dbus-server.h"
24 #include "dbus-server-unix.h"
25
26 /**
27  * @defgroup DBusServer DBusServer
28  * @ingroup  DBus
29  * @brief Server that listens for new connections.
30  *
31  * Types and functions related to DBusServer.
32  * A DBusServer represents a server that other applications
33  * can connect to. Each connection from another application
34  * is represented by a DBusConnection.
35  */
36
37 /**
38  * @defgroup DBusServerInternals DBusServer implementation details
39  * @ingroup  DBusInternals
40  * @brief Implementation details of DBusServer
41  *
42  * @{
43  */
44
45 /**
46  * Initializes the members of the DBusServer base class.
47  * Chained up to by subclass constructors.
48  *
49  * @param server the server.
50  * @param vtable the vtable for the subclass.
51  * @returns #TRUE on success.
52  */
53 dbus_bool_t
54 _dbus_server_init_base (DBusServer             *server,
55                         const DBusServerVTable *vtable)
56 {
57   server->vtable = vtable;
58   server->refcount = 1;
59
60   server->watches = _dbus_watch_list_new ();
61   if (server->watches == NULL)
62     return FALSE;
63
64   return TRUE;
65 }
66
67 /**
68  * Finalizes the members of the DBusServer base class.
69  * Chained up to by subclass finalizers.
70  *
71  * @param server the server.
72  */
73 void
74 _dbus_server_finalize_base (DBusServer *server)
75 {
76   dbus_server_set_new_connection_function (server, NULL, NULL, NULL);
77
78   if (!server->disconnected)
79     dbus_server_disconnect (server);
80
81   _dbus_watch_list_free (server->watches);
82 }
83
84 /**
85  * Adds a watch for this server, chaining out to application-provided
86  * watch handlers.
87  *
88  * @param server the server.
89  * @param watch the watch to add.
90  */
91 dbus_bool_t
92 _dbus_server_add_watch (DBusServer *server,
93                         DBusWatch  *watch)
94 {
95   return _dbus_watch_list_add_watch (server->watches, watch);
96 }
97
98 /**
99  * Removes a watch previously added with _dbus_server_remove_watch().
100  *
101  * @param server the server.
102  * @param watch the watch to remove.
103  */
104 void
105 _dbus_server_remove_watch  (DBusServer *server,
106                             DBusWatch  *watch)
107 {
108   _dbus_watch_list_remove_watch (server->watches, watch);
109 }
110
111
112 /** @} */
113
114 /**
115  * @addtogroup DBusServer
116  *
117  * @{
118  */
119
120
121 /**
122  * @typedef DBusServer
123  *
124  * An opaque object representing a server that listens for
125  * connections from other applications. Each time a connection
126  * is made, a new DBusConnection is created and made available
127  * via an application-provided DBusNewConnectionFunction.
128  * The DBusNewConnectionFunction is provided with
129  * dbus_server_set_new_connection_function().
130  * 
131  */
132
133 /**
134  * Listens for new connections on the given address.
135  * Returns #NULL if listening fails for any reason.
136  * Otherwise returns a new #DBusServer.
137  * dbus_server_set_new_connection_function() and
138  * dbus_server_set_watch_functions() should be called
139  * immediately to render the server fully functional.
140  *
141  * @param address the address of this server.
142  * @param result location to store rationale for failure.
143  * @returns a new DBusServer, or #NULL on failure.
144  * 
145  */
146 DBusServer*
147 dbus_server_listen (const char     *address,
148                     DBusResultCode *result)
149 {
150   DBusServer *server;
151
152   /* For now just pretend the address is a unix domain socket path */
153   server = _dbus_server_new_for_domain_socket (address, result);
154   
155   return server;
156 }
157
158 /**
159  * Increments the reference count of a DBusServer.
160  *
161  * @param server the server.
162  */
163 void
164 dbus_server_ref (DBusServer *server)
165 {
166   server->refcount += 1;
167 }
168
169 /**
170  * Decrements the reference count of a DBusServer.  Finalizes the
171  * server if the reference count reaches zero. The server connection
172  * will be closed as with dbus_server_disconnect() when the server is
173  * finalized.
174  *
175  * @param server the server.
176  */
177 void
178 dbus_server_unref (DBusServer *server)
179 {
180   _dbus_assert (server != NULL);
181   _dbus_assert (server->refcount > 0);
182
183   server->refcount -= 1;
184   if (server->refcount == 0)
185     {
186       _dbus_assert (server->vtable->finalize != NULL);
187       
188       (* server->vtable->finalize) (server);
189     }
190 }
191
192 /**
193  * Releases the server's address and stops listening for
194  * new clients. If called more than once, only the first
195  * call has an effect. Does not modify the server's
196  * reference count.
197  * 
198  * @param server the server.
199  */
200 void
201 dbus_server_disconnect (DBusServer *server)
202 {
203   _dbus_assert (server->vtable->disconnect != NULL);
204
205   if (server->disconnected)
206     return;
207   
208   (* server->vtable->disconnect) (server);
209   server->disconnected = TRUE;
210 }
211
212 /**
213  * Returns #TRUE if the server is still listening for new connections.
214  *
215  * @param server the server.
216  */
217 dbus_bool_t
218 dbus_server_get_is_connected (DBusServer *server)
219 {
220   return !server->disconnected;
221 }
222
223 /**
224  * Sets a function to be used for handling new connections.  The given
225  * function is passed each new connection as the connection is
226  * created. If the new connection function increments the connection's
227  * reference count, the connection will stay alive. Otherwise, the
228  * connection will be unreferenced and closed.
229  *
230  * @param server the server.
231  * @param function a function to handle new connections.
232  * @param data data to pass to the new connection handler.
233  * @param free_data_function function to free the data.
234  */
235 void
236 dbus_server_set_new_connection_function (DBusServer                *server,
237                                          DBusNewConnectionFunction  function,
238                                          void                      *data,
239                                          DBusFreeFunction           free_data_function)
240 {
241   if (server->new_connection_free_data_function != NULL)
242     (* server->new_connection_free_data_function) (server->new_connection_data);
243   
244   server->new_connection_function = function;
245   server->new_connection_data = data;
246   server->new_connection_free_data_function = free_data_function;
247 }
248
249 /**
250  * Sets the watch functions for the connection. These functions are
251  * responsible for making the application's main loop aware of file
252  * descriptors that need to be monitored for events.
253  *
254  * This function behaves exactly like dbus_connection_set_watch_functions();
255  * see the documentation for that routine.
256  *
257  * @param server the server.
258  * @param add_function function to begin monitoring a new descriptor.
259  * @param remove_function function to stop monitoring a descriptor.
260  * @param data data to pass to add_function and remove_function.
261  * @param free_data_function function to be called to free the data.
262  */
263 void
264 dbus_server_set_watch_functions (DBusServer              *server,
265                                  DBusAddWatchFunction     add_function,
266                                  DBusRemoveWatchFunction  remove_function,
267                                  void                    *data,
268                                  DBusFreeFunction         free_data_function)
269 {
270   _dbus_watch_list_set_functions (server->watches,
271                                   add_function,
272                                   remove_function,
273                                   data,
274                                   free_data_function);
275 }
276
277 /**
278  * Called to notify the server when a previously-added watch
279  * is ready for reading or writing, or has an exception such
280  * as a hangup.
281  *
282  * @param server the server.
283  * @param watch the watch.
284  * @param condition the current condition of the file descriptors being watched.
285  */
286 void
287 dbus_server_handle_watch (DBusServer              *server,
288                           DBusWatch               *watch,
289                           unsigned int             condition)
290 {
291   _dbus_assert (server->vtable->handle_watch != NULL);
292
293   _dbus_watch_sanitize_condition (watch, &condition);
294   
295   (* server->vtable->handle_watch) (server, watch, condition);
296 }
297
298 /** @} */
299