diff options
Diffstat (limited to 'dbus/dbus-server.c')
-rw-r--r-- | dbus/dbus-server.c | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c new file mode 100644 index 00000000..c4b36bd6 --- /dev/null +++ b/dbus/dbus-server.c @@ -0,0 +1,299 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-server.c DBusServer object + * + * Copyright (C) 2002 Red Hat Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "dbus-server.h" +#include "dbus-server-unix.h" + +/** + * @defgroup DBusServer DBusServer + * @ingroup DBus + * @brief Server that listens for new connections. + * + * Types and functions related to DBusServer. + * A DBusServer represents a server that other applications + * can connect to. Each connection from another application + * is represented by a DBusConnection. + */ + +/** + * @defgroup DBusServerInternals DBusServer implementation details + * @ingroup DBusInternals + * @brief Implementation details of DBusServer + * + * @{ + */ + +/** + * Initializes the members of the DBusServer base class. + * Chained up to by subclass constructors. + * + * @param server the server. + * @param vtable the vtable for the subclass. + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_server_init_base (DBusServer *server, + const DBusServerVTable *vtable) +{ + server->vtable = vtable; + server->refcount = 1; + + server->watches = _dbus_watch_list_new (); + if (server->watches == NULL) + return FALSE; + + return TRUE; +} + +/** + * Finalizes the members of the DBusServer base class. + * Chained up to by subclass finalizers. + * + * @param server the server. + */ +void +_dbus_server_finalize_base (DBusServer *server) +{ + dbus_server_set_new_connection_function (server, NULL, NULL, NULL); + + if (!server->disconnected) + dbus_server_disconnect (server); + + _dbus_watch_list_free (server->watches); +} + +/** + * Adds a watch for this server, chaining out to application-provided + * watch handlers. + * + * @param server the server. + * @param watch the watch to add. + */ +dbus_bool_t +_dbus_server_add_watch (DBusServer *server, + DBusWatch *watch) +{ + return _dbus_watch_list_add_watch (server->watches, watch); +} + +/** + * Removes a watch previously added with _dbus_server_remove_watch(). + * + * @param server the server. + * @param watch the watch to remove. + */ +void +_dbus_server_remove_watch (DBusServer *server, + DBusWatch *watch) +{ + _dbus_watch_list_remove_watch (server->watches, watch); +} + + +/** @} */ + +/** + * @addtogroup DBusServer + * + * @{ + */ + + +/** + * @typedef DBusServer + * + * An opaque object representing a server that listens for + * connections from other applications. Each time a connection + * is made, a new DBusConnection is created and made available + * via an application-provided DBusNewConnectionFunction. + * The DBusNewConnectionFunction is provided with + * dbus_server_set_new_connection_function(). + * + */ + +/** + * Listens for new connections on the given address. + * Returns #NULL if listening fails for any reason. + * Otherwise returns a new #DBusServer. + * dbus_server_set_new_connection_function() and + * dbus_server_set_watch_functions() should be called + * immediately to render the server fully functional. + * + * @param address the address of this server. + * @param result location to store rationale for failure. + * @returns a new DBusServer, or #NULL on failure. + * + */ +DBusServer* +dbus_server_listen (const char *address, + DBusResultCode *result) +{ + DBusServer *server; + + /* For now just pretend the address is a unix domain socket path */ + server = _dbus_server_new_for_domain_socket (address, result); + + return server; +} + +/** + * Increments the reference count of a DBusServer. + * + * @param server the server. + */ +void +dbus_server_ref (DBusServer *server) +{ + server->refcount += 1; +} + +/** + * Decrements the reference count of a DBusServer. Finalizes the + * server if the reference count reaches zero. The server connection + * will be closed as with dbus_server_disconnect() when the server is + * finalized. + * + * @param server the server. + */ +void +dbus_server_unref (DBusServer *server) +{ + _dbus_assert (server != NULL); + _dbus_assert (server->refcount > 0); + + server->refcount -= 1; + if (server->refcount == 0) + { + _dbus_assert (server->vtable->finalize != NULL); + + (* server->vtable->finalize) (server); + } +} + +/** + * Releases the server's address and stops listening for + * new clients. If called more than once, only the first + * call has an effect. Does not modify the server's + * reference count. + * + * @param server the server. + */ +void +dbus_server_disconnect (DBusServer *server) +{ + _dbus_assert (server->vtable->disconnect != NULL); + + if (server->disconnected) + return; + + (* server->vtable->disconnect) (server); + server->disconnected = TRUE; +} + +/** + * Returns #TRUE if the server is still listening for new connections. + * + * @param server the server. + */ +dbus_bool_t +dbus_server_get_is_connected (DBusServer *server) +{ + return !server->disconnected; +} + +/** + * Sets a function to be used for handling new connections. The given + * function is passed each new connection as the connection is + * created. If the new connection function increments the connection's + * reference count, the connection will stay alive. Otherwise, the + * connection will be unreferenced and closed. + * + * @param server the server. + * @param function a function to handle new connections. + * @param data data to pass to the new connection handler. + * @param free_data_function function to free the data. + */ +void +dbus_server_set_new_connection_function (DBusServer *server, + DBusNewConnectionFunction function, + void *data, + DBusFreeFunction free_data_function) +{ + if (server->new_connection_free_data_function != NULL) + (* server->new_connection_free_data_function) (server->new_connection_data); + + server->new_connection_function = function; + server->new_connection_data = data; + server->new_connection_free_data_function = free_data_function; +} + +/** + * Sets the watch functions for the connection. These functions are + * responsible for making the application's main loop aware of file + * descriptors that need to be monitored for events. + * + * This function behaves exactly like dbus_connection_set_watch_functions(); + * see the documentation for that routine. + * + * @param server the server. + * @param add_function function to begin monitoring a new descriptor. + * @param remove_function function to stop monitoring a descriptor. + * @param data data to pass to add_function and remove_function. + * @param free_data_function function to be called to free the data. + */ +void +dbus_server_set_watch_functions (DBusServer *server, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + void *data, + DBusFreeFunction free_data_function) +{ + _dbus_watch_list_set_functions (server->watches, + add_function, + remove_function, + data, + free_data_function); +} + +/** + * Called to notify the server when a previously-added watch + * is ready for reading or writing, or has an exception such + * as a hangup. + * + * @param server the server. + * @param watch the watch. + * @param condition the current condition of the file descriptors being watched. + */ +void +dbus_server_handle_watch (DBusServer *server, + DBusWatch *watch, + unsigned int condition) +{ + _dbus_assert (server->vtable->handle_watch != NULL); + + _dbus_watch_sanitize_condition (watch, &condition); + + (* server->vtable->handle_watch) (server, watch, condition); +} + +/** @} */ + |