summaryrefslogtreecommitdiffstats
path: root/bus/bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'bus/bus.c')
-rw-r--r--bus/bus.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/bus/bus.c b/bus/bus.c
new file mode 100644
index 00000000..7ac0beee
--- /dev/null
+++ b/bus/bus.c
@@ -0,0 +1,202 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* bus.c message bus context object
+ *
+ * Copyright (C) 2003 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 "bus.h"
+#include "loop.h"
+#include "activation.h"
+#include "connection.h"
+#include "services.h"
+#include "utils.h"
+#include <dbus/dbus-internals.h>
+
+struct BusContext
+{
+ int refcount;
+ char *address;
+ DBusServer *server;
+ BusConnections *connections;
+ BusActivation *activation;
+ BusRegistry *registry;
+};
+
+static void
+server_watch_callback (DBusWatch *watch,
+ unsigned int condition,
+ void *data)
+{
+ BusContext *context = data;
+
+ dbus_server_handle_watch (context->server, watch, condition);
+}
+
+static void
+add_server_watch (DBusWatch *watch,
+ BusContext *context)
+{
+ bus_loop_add_watch (watch, server_watch_callback, context,
+ NULL);
+}
+
+static void
+remove_server_watch (DBusWatch *watch,
+ BusContext *context)
+{
+ bus_loop_remove_watch (watch, server_watch_callback, context);
+}
+
+static void
+new_connection_callback (DBusServer *server,
+ DBusConnection *new_connection,
+ void *data)
+{
+ BusContext *context = data;
+
+ if (!bus_connections_setup_connection (context->connections, new_connection))
+ _dbus_verbose ("No memory to setup new connection\n");
+
+ /* on OOM, we won't have ref'd the connection so it will die */
+}
+
+BusContext*
+bus_context_new (const char *address,
+ const char **service_dirs,
+ DBusError *error)
+{
+ BusContext *context;
+ DBusResultCode result;
+
+ context = dbus_new0 (BusContext, 1);
+ if (context == NULL)
+ {
+ BUS_SET_OOM (error);
+ return NULL;
+ }
+
+ context->refcount = 1;
+
+ context->address = _dbus_strdup (address);
+ if (context->address == NULL)
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+
+ context->server = dbus_server_listen (address, &result);
+ if (context->server == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Failed to start server on %s: %s\n",
+ address, dbus_result_to_string (result));
+ goto failed;
+ }
+
+ context->activation = bus_activation_new (address, service_dirs,
+ error);
+ if (context->activation == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+
+ context->connections = bus_connections_new (context);
+ if (context->connections == NULL)
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+
+ context->registry = bus_registry_new ();
+ if (context->registry == NULL)
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+
+ dbus_server_set_new_connection_function (context->server,
+ new_connection_callback,
+ context, NULL);
+
+ dbus_server_set_watch_functions (context->server,
+ (DBusAddWatchFunction) add_server_watch,
+ (DBusRemoveWatchFunction) remove_server_watch,
+ context,
+ NULL);
+
+ return context;
+
+ failed:
+ bus_context_unref (context);
+ return NULL;
+}
+
+void
+bus_context_shutdown (BusContext *context)
+{
+ dbus_server_disconnect (context->server);
+}
+
+void
+bus_context_ref (BusContext *context)
+{
+ _dbus_assert (context->refcount > 0);
+ context->refcount += 1;
+}
+
+void
+bus_context_unref (BusContext *context)
+{
+ _dbus_assert (context->refcount > 0);
+ context->refcount -= 1;
+
+ if (context->refcount == 0)
+ {
+ if (context->registry)
+ bus_registry_unref (context->registry);
+ if (context->connections)
+ bus_connections_unref (context->connections);
+ if (context->activation)
+ bus_activation_unref (context->activation);
+ if (context->server)
+ dbus_server_unref (context->server);
+ dbus_free (context->address);
+ dbus_free (context);
+ }
+}
+
+BusRegistry*
+bus_context_get_registry (BusContext *context)
+{
+ return context->registry;
+}
+
+BusConnections*
+bus_context_get_connections (BusContext *context)
+{
+ return context->connections;
+}
+
+BusActivation*
+bus_context_get_activation (BusContext *context)
+{
+ return context->activation;
+}