summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--bus/Makefile.am2
-rw-r--r--bus/activation.c101
-rw-r--r--bus/activation.h15
-rw-r--r--bus/bus.c202
-rw-r--r--bus/bus.h48
-rw-r--r--bus/connection.c199
-rw-r--r--bus/connection.h24
-rw-r--r--bus/dispatch.c21
-rw-r--r--bus/driver.c39
-rw-r--r--bus/main.c105
-rw-r--r--bus/services.c237
-rw-r--r--bus/services.h40
-rw-r--r--test/Makefile.am17
14 files changed, 738 insertions, 323 deletions
diff --git a/ChangeLog b/ChangeLog
index c7bc4362..9591317c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2003-03-12 Havoc Pennington <hp@pobox.com>
+
+ Throughout: purge global variables, introduce BusActivation,
+ BusConnections, BusRegistry, etc. objects instead.
+
+ * bus/bus.h, bus/bus.c: introduce BusContext as a global
+ message bus object
+
+ * test/Makefile.am (TEST_BINARIES): disable bus-test for now,
+ going to redo this a bit differently I think
+
2003-03-12 Havoc Pennington <hp@redhat.com>
Mega-patch that gets the message bus daemon initially handling
diff --git a/bus/Makefile.am b/bus/Makefile.am
index d84e99d7..f9f4dbfc 100644
--- a/bus/Makefile.am
+++ b/bus/Makefile.am
@@ -11,6 +11,8 @@ noinst_LTLIBRARIES=libdbus-daemon.la
libdbus_daemon_la_SOURCES= \
activation.c \
activation.h \
+ bus.c \
+ bus.h \
connection.c \
connection.h \
desktop-file.c \
diff --git a/bus/activation.c b/bus/activation.c
index 4e428bde..ba130edd 100644
--- a/bus/activation.c
+++ b/bus/activation.c
@@ -33,8 +33,12 @@
#define DBUS_SERVICE_NAME "Name"
#define DBUS_SERVICE_EXEC "Exec"
-static DBusHashTable *activation_entries = NULL;
-static char *server_address = NULL;
+struct BusActivation
+{
+ int refcount;
+ DBusHashTable *entries;
+ char *server_address;
+};
typedef struct
{
@@ -42,12 +46,6 @@ typedef struct
char *exec;
} BusActivationEntry;
-static DBusHashTable *pending_activations = NULL;
-typedef struct
-{
- char *service;
-} BusPendingActivation;
-
static void
bus_activation_entry_free (BusActivationEntry *entry)
{
@@ -59,7 +57,8 @@ bus_activation_entry_free (BusActivationEntry *entry)
}
static dbus_bool_t
-add_desktop_file_entry (BusDesktopFile *desktop_file,
+add_desktop_file_entry (BusActivation *activation,
+ BusDesktopFile *desktop_file,
DBusError *error)
{
char *name, *exec;
@@ -92,7 +91,7 @@ add_desktop_file_entry (BusDesktopFile *desktop_file,
/* FIXME we need a better-defined algorithm for which service file to
* pick than "whichever one is first in the directory listing"
*/
- if (_dbus_hash_table_lookup_string (activation_entries, name))
+ if (_dbus_hash_table_lookup_string (activation->entries, name))
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Service %s already exists in activation entry list\n", name);
@@ -109,7 +108,7 @@ add_desktop_file_entry (BusDesktopFile *desktop_file,
entry->name = name;
entry->exec = exec;
- if (!_dbus_hash_table_insert_string (activation_entries, entry->name, entry))
+ if (!_dbus_hash_table_insert_string (activation->entries, entry->name, entry))
{
BUS_SET_OOM (error);
goto failed;
@@ -131,8 +130,9 @@ add_desktop_file_entry (BusDesktopFile *desktop_file,
* hash entries it already added.
*/
static dbus_bool_t
-load_directory (const char *directory,
- DBusError *error)
+load_directory (BusActivation *activation,
+ const char *directory,
+ DBusError *error)
{
DBusDirIter *iter;
DBusString dir, filename;
@@ -213,7 +213,7 @@ load_directory (const char *directory,
continue;
}
- if (!add_desktop_file_entry (desktop_file, &tmp_error))
+ if (!add_desktop_file_entry (activation, desktop_file, &tmp_error))
{
const char *full_path_c;
@@ -263,27 +263,34 @@ load_directory (const char *directory,
return FALSE;
}
-dbus_bool_t
-bus_activation_init (const char *address,
- const char **directories,
- DBusError *error)
+BusActivation*
+bus_activation_new (const char *address,
+ const char **directories,
+ DBusError *error)
{
int i;
+ BusActivation *activation;
- _dbus_assert (server_address == NULL);
- _dbus_assert (activation_entries == NULL);
+ activation = dbus_new0 (BusActivation, 1);
+ if (activation == NULL)
+ {
+ BUS_SET_OOM (error);
+ return NULL;
+ }
+
+ activation->refcount = 1;
/* FIXME: We should split up the server addresses. */
- server_address = _dbus_strdup (address);
- if (server_address == NULL)
+ activation->server_address = _dbus_strdup (address);
+ if (activation->server_address == NULL)
{
BUS_SET_OOM (error);
goto failed;
}
- activation_entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
+ activation->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
(DBusFreeFunction)bus_activation_entry_free);
- if (activation_entries == NULL)
+ if (activation->entries == NULL)
{
BUS_SET_OOM (error);
goto failed;
@@ -293,39 +300,63 @@ bus_activation_init (const char *address,
i = 0;
while (directories[i] != NULL)
{
- if (!load_directory (directories[i], error))
+ if (!load_directory (activation, directories[i], error))
goto failed;
++i;
}
- return TRUE;
+ return activation;
failed:
- dbus_free (server_address);
- if (activation_entries)
- _dbus_hash_table_unref (activation_entries);
+ bus_activation_unref (activation);
+ return NULL;
+}
+
+void
+bus_activation_ref (BusActivation *activation)
+{
+ _dbus_assert (activation->refcount > 0);
- return FALSE;
+ activation->refcount += 1;
+}
+
+void
+bus_activation_unref (BusActivation *activation)
+{
+ _dbus_assert (activation->refcount > 0);
+
+ activation->refcount -= 1;
+
+ if (activation->refcount == 0)
+ {
+ dbus_free (activation->server_address);
+ if (activation->entries)
+ _dbus_hash_table_unref (activation->entries);
+ dbus_free (activation);
+ }
}
static void
child_setup (void *data)
{
+ BusActivation *activation = data;
+
/* If no memory, we simply have the child exit, so it won't try
* to connect to the wrong thing.
*/
- if (!_dbus_setenv ("DBUS_ADDRESS", server_address))
+ if (!_dbus_setenv ("DBUS_ADDRESS", activation->server_address))
_dbus_exit (1);
}
dbus_bool_t
-bus_activation_activate_service (const char *service_name,
- DBusError *error)
+bus_activation_activate_service (BusActivation *activation,
+ const char *service_name,
+ DBusError *error)
{
BusActivationEntry *entry;
char *argv[2];
- entry = _dbus_hash_table_lookup_string (activation_entries, service_name);
+ entry = _dbus_hash_table_lookup_string (activation->entries, service_name);
if (!entry)
{
@@ -344,7 +375,7 @@ bus_activation_activate_service (const char *service_name,
argv[1] = NULL;
if (!_dbus_spawn_async (argv,
- child_setup, NULL,
+ child_setup, activation,
error))
return FALSE;
diff --git a/bus/activation.h b/bus/activation.h
index e7a9cdfc..4e363c92 100644
--- a/bus/activation.h
+++ b/bus/activation.h
@@ -25,12 +25,17 @@
#define BUS_ACTIVATION_H
#include <dbus/dbus.h>
+#include "bus.h"
+
+BusActivation* bus_activation_new (const char *address,
+ const char **paths,
+ DBusError *error);
+void bus_activation_ref (BusActivation *activation);
+void bus_activation_unref (BusActivation *activation);
+dbus_bool_t bus_activation_activate_service (BusActivation *activation,
+ const char *service_name,
+ DBusError *error);
-dbus_bool_t bus_activation_init (const char *address,
- const char **paths,
- DBusError *error);
-dbus_bool_t bus_activation_activate_service (const char *service_name,
- DBusError *error);
#endif /* BUS_ACTIVATION_H */
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;
+}
diff --git a/bus/bus.h b/bus/bus.h
new file mode 100644
index 00000000..4d922f0c
--- /dev/null
+++ b/bus/bus.h
@@ -0,0 +1,48 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* bus.h 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
+ *
+ */
+
+#ifndef BUS_BUS_H
+#define BUS_BUS_H
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-string.h>
+
+typedef struct BusActivation BusActivation;
+typedef struct BusConnections BusConnections;
+typedef struct BusContext BusContext;
+typedef struct BusRegistry BusRegistry;
+typedef struct BusService BusService;
+typedef struct BusTransaction BusTransaction;
+
+BusContext* bus_context_new (const char *address,
+ const char **service_dirs,
+ DBusError *error);
+void bus_context_shutdown (BusContext *context);
+void bus_context_ref (BusContext *context);
+void bus_context_unref (BusContext *context);
+BusRegistry* bus_context_get_registry (BusContext *context);
+BusConnections* bus_context_get_connections (BusContext *context);
+BusActivation* bus_context_get_activation (BusContext *context);
+
+
+#endif /* BUS_BUS_H */
diff --git a/bus/connection.c b/bus/connection.c
index ff671c58..cdc8be79 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -29,11 +29,18 @@
static void bus_connection_remove_transactions (DBusConnection *connection);
-static int connection_data_slot;
-static DBusList *connections = NULL;
+struct BusConnections
+{
+ int refcount;
+ DBusList *list; /**< List of all the connections */
+ BusContext *context;
+};
+
+static int connection_data_slot = -1;
typedef struct
{
+ BusConnections *connections;
DBusConnection *connection;
DBusList *services_owned;
char *name;
@@ -74,7 +81,7 @@ bus_connection_disconnected (DBusConnection *connection)
transaction = NULL;
while (transaction == NULL)
{
- transaction = bus_transaction_new ();
+ transaction = bus_transaction_new (d->connections->context);
bus_wait_for_memory ();
}
@@ -107,12 +114,14 @@ bus_connection_disconnected (DBusConnection *connection)
NULL);
bus_connection_remove_transactions (connection);
-
+
+ _dbus_list_remove (&d->connections->list, connection);
+
+ /* frees "d" as side effect */
dbus_connection_set_data (connection,
connection_data_slot,
NULL, NULL);
-
- _dbus_list_remove (&connections, connection);
+
dbus_connection_unref (connection);
}
@@ -166,19 +175,55 @@ free_connection_data (void *data)
dbus_free (d);
}
-dbus_bool_t
-bus_connection_init (void)
+BusConnections*
+bus_connections_new (BusContext *context)
{
- connection_data_slot = dbus_connection_allocate_data_slot ();
+ BusConnections *connections;
if (connection_data_slot < 0)
- return FALSE;
+ {
+ connection_data_slot = dbus_connection_allocate_data_slot ();
+
+ if (connection_data_slot < 0)
+ return NULL;
+ }
- return TRUE;
+ connections = dbus_new0 (BusConnections, 1);
+ if (connections == NULL)
+ return NULL;
+
+ connections->refcount = 1;
+ connections->context = context;
+
+ return connections;
+}
+
+void
+bus_connections_ref (BusConnections *connections)
+{
+ _dbus_assert (connections->refcount > 0);
+ connections->refcount += 1;
+}
+
+void
+bus_connections_unref (BusConnections *connections)
+{
+ _dbus_assert (connections->refcount > 0);
+ connections->refcount -= 1;
+ if (connections->refcount == 0)
+ {
+ /* FIXME free each connection... */
+ _dbus_assert_not_reached ("shutting down connections not implemented");
+
+ _dbus_list_clear (&connections->list);
+
+ dbus_free (connections);
+ }
}
dbus_bool_t
-bus_connection_setup (DBusConnection *connection)
+bus_connections_setup_connection (BusConnections *connections,
+ DBusConnection *connection)
{
BusConnectionData *d;
@@ -187,6 +232,7 @@ bus_connection_setup (DBusConnection *connection)
if (d == NULL)
return FALSE;
+ d->connections = connections;
d->connection = connection;
if (!dbus_connection_set_data (connection,
@@ -197,7 +243,7 @@ bus_connection_setup (DBusConnection *connection)
return FALSE;
}
- if (!_dbus_list_append (&connections, connection))
+ if (!_dbus_list_append (&connections->list, connection))
{
/* this will free our data when connection gets finalized */
dbus_connection_disconnect (connection);
@@ -219,6 +265,89 @@ bus_connection_setup (DBusConnection *connection)
return TRUE;
}
+
+/**
+ * Calls function on each connection; if the function returns
+ * #FALSE, stops iterating.
+ *
+ * @param connections the connections object
+ * @param function the function
+ * @param data data to pass to it as a second arg
+ */
+void
+bus_connections_foreach (BusConnections *connections,
+ BusConnectionForeachFunction function,
+ void *data)
+{
+ DBusList *link;
+
+ link = _dbus_list_get_first_link (&connections->list);
+ while (link != NULL)
+ {
+ DBusConnection *connection = link->data;
+ DBusList *next = _dbus_list_get_next_link (&connections->list, link);
+
+ if (!(* function) (connection, data))
+ break;
+
+ link = next;
+ }
+}
+
+BusContext*
+bus_connections_get_context (BusConnections *connections)
+{
+ return connections->context;
+}
+
+BusContext*
+bus_connection_get_context (DBusConnection *connection)
+{
+ BusConnectionData *d;
+
+ d = BUS_CONNECTION_DATA (connection);
+
+ _dbus_assert (d != NULL);
+
+ return d->connections->context;
+}
+
+BusConnections*
+bus_connection_get_connections (DBusConnection *connection)
+{
+ BusConnectionData *d;
+
+ d = BUS_CONNECTION_DATA (connection);
+
+ _dbus_assert (d != NULL);
+
+ return d->connections;
+}
+
+BusRegistry*
+bus_connection_get_registry (DBusConnection *connection)
+{
+ BusConnectionData *d;
+
+ d = BUS_CONNECTION_DATA (connection);
+
+ _dbus_assert (d != NULL);
+
+ return bus_context_get_registry (d->connections->context);
+}
+
+BusActivation*
+bus_connection_get_activation (DBusConnection *connection)
+{
+ BusConnectionData *d;
+
+ d = BUS_CONNECTION_DATA (connection);
+
+ _dbus_assert (d != NULL);
+
+ return bus_context_get_activation (d->connections->context);
+}
+
/**
* Checks whether the connection is registered with the message bus.
*
@@ -361,32 +490,6 @@ bus_connection_get_name (DBusConnection *connection)
return d->name;
}
-/**
- * Calls function on each connection; if the function returns
- * #FALSE, stops iterating.
- *
- * @param function the function
- * @param data data to pass to it as a second arg
- */
-void
-bus_connection_foreach (BusConnectionForeachFunction function,
- void *data)
-{
- DBusList *link;
-
- link = _dbus_list_get_first_link (&connections);
- while (link != NULL)
- {
- DBusConnection *connection = link->data;
- DBusList *next = _dbus_list_get_next_link (&connections, link);
-
- if (!(* function) (connection, data))
- break;
-
- link = next;
- }
-}
-
typedef struct
{
BusTransaction *transaction;
@@ -397,7 +500,7 @@ typedef struct
struct BusTransaction
{
DBusList *connections;
-
+ BusContext *context;
};
static void
@@ -414,7 +517,7 @@ message_to_send_free (DBusConnection *connection,
}
BusTransaction*
-bus_transaction_new (void)
+bus_transaction_new (BusContext *context)
{
BusTransaction *transaction;
@@ -422,9 +525,23 @@ bus_transaction_new (void)
if (transaction == NULL)
return NULL;
+ transaction->context = context;
+
return transaction;
}
+BusContext*
+bus_transaction_get_context (BusTransaction *transaction)
+{
+ return transaction->context;
+}
+
+BusConnections*
+bus_transaction_get_connections (BusTransaction *transaction)
+{
+ return bus_context_get_connections (transaction->context);
+}
+
dbus_bool_t
bus_transaction_send_message (BusTransaction *transaction,
DBusConnection *connection,
diff --git a/bus/connection.h b/bus/connection.h
index a7a448a1..f78c3ac1 100644
--- a/bus/connection.h
+++ b/bus/connection.h
@@ -25,14 +25,26 @@
#define BUS_CONNECTION_H
#include <dbus/dbus.h>
-#include "services.h"
+#include "bus.h"
typedef dbus_bool_t (* BusConnectionForeachFunction) (DBusConnection *connection,
void *data);
-dbus_bool_t bus_connection_init (void);
-dbus_bool_t bus_connection_setup (DBusConnection *connection);
+BusConnections* bus_connections_new (BusContext *context);
+void bus_connections_ref (BusConnections *connections);
+void bus_connections_unref (BusConnections *connections);
+dbus_bool_t bus_connections_setup_connection (BusConnections *connections,
+ DBusConnection *connection);
+void bus_connections_foreach (BusConnections *connections,
+ BusConnectionForeachFunction function,
+ void *data);
+BusContext* bus_connections_get_context (BusConnections *connections);
+
+BusContext* bus_connection_get_context (DBusConnection *connection);
+BusConnections* bus_connection_get_connections (DBusConnection *connection);
+BusRegistry* bus_connection_get_registry (DBusConnection *connection);
+BusActivation* bus_connection_get_activation (DBusConnection *connection);
dbus_bool_t bus_connection_is_active (DBusConnection *connection);
@@ -50,14 +62,14 @@ void bus_connection_remove_owned_service (DBusConnection *connection,
dbus_bool_t bus_connection_set_name (DBusConnection *connection,
const DBusString *name);
const char *bus_connection_get_name (DBusConnection *connection);
-void bus_connection_foreach (BusConnectionForeachFunction function,
- void *data);
/* called by dispatch.c when the connection is dropped */
void bus_connection_disconnected (DBusConnection *connection);
/* transaction API so we can send or not send a block of messages as a whole */
-BusTransaction* bus_transaction_new (void);
+BusTransaction* bus_transaction_new (BusContext *context);
+BusContext* bus_transaction_get_context (BusTransaction *transaction);
+BusConnections* bus_transaction_get_connections (BusTransaction *transaction);
dbus_bool_t bus_transaction_send_message (BusTransaction *transaction,
DBusConnection *connection,
DBusMessage *message);
diff --git a/bus/dispatch.c b/bus/dispatch.c
index d9fe81ac..1d2ea1c2 100644
--- a/bus/dispatch.c
+++ b/bus/dispatch.c
@@ -24,7 +24,9 @@
#include "dispatch.h"
#include "connection.h"
#include "driver.h"
+#include "services.h"
#include "utils.h"
+#include "bus.h"
#include <dbus/dbus-internals.h>
#include <string.h>
@@ -63,14 +65,18 @@ bus_dispatch_broadcast_message (BusTransaction *transaction,
{
DBusError tmp_error;
SendMessageData d;
+ BusConnections *connections;
_dbus_assert (dbus_message_get_sender (message) != NULL);
+ connections = bus_transaction_get_connections (transaction);
+
dbus_error_init (&tmp_error);
d.message = message;
d.transaction = transaction;
d.error = &tmp_error;
- bus_connection_foreach (send_one_message, &d);
+
+ bus_connections_foreach (connections, send_one_message, &d);
if (dbus_error_is_set (&tmp_error))
{
@@ -145,9 +151,13 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
const char *sender, *service_name, *message_name;
DBusError error;
BusTransaction *transaction;
-
+ BusContext *context;
+
transaction = NULL;
dbus_error_init (&error);
+
+ context = bus_connection_get_context (connection);
+ _dbus_assert (context != NULL);
/* If we can't even allocate an OOM error, we just go to sleep
* until we can.
@@ -181,7 +191,7 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
_dbus_assert (service_name != NULL); /* this message is intended for bus routing */
/* Create our transaction */
- transaction = bus_transaction_new ();
+ transaction = bus_transaction_new (context);
if (transaction == NULL)
{
BUS_SET_OOM (&error);
@@ -224,9 +234,12 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
{
DBusString service_string;
BusService *service;
+ BusRegistry *registry;
+ registry = bus_connection_get_registry (connection);
+
_dbus_string_init_const (&service_string, service_name);
- service = bus_service_lookup (&service_string);
+ service = bus_registry_lookup (registry, &service_string);
if (service == NULL)
{
diff --git a/bus/driver.c b/bus/driver.c
index 46985594..09ec18af 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -199,7 +199,8 @@ bus_driver_send_service_acquired (DBusConnection *connection,
}
static dbus_bool_t
-create_unique_client_name (DBusString *str)
+create_unique_client_name (BusRegistry *registry,
+ DBusString *str)
{
/* We never want to use the same unique client name twice, because
* we want to guarantee that if you send a message to a given unique
@@ -246,7 +247,7 @@ create_unique_client_name (DBusString *str)
next_minor_number += 1;
/* Check if a client with the name exists */
- if (bus_service_lookup (str) == NULL)
+ if (bus_registry_lookup (registry, str) == NULL)
break;
/* drop the number again, try the next one. */
@@ -265,6 +266,7 @@ bus_driver_handle_hello (DBusConnection *connection,
DBusString unique_name;
BusService *service;
dbus_bool_t retval;
+ BusRegistry *registry;
if (!_dbus_string_init (&unique_name, _DBUS_INT_MAX))
{
@@ -273,8 +275,10 @@ bus_driver_handle_hello (DBusConnection *connection,
}
retval = FALSE;
+
+ registry = bus_connection_get_registry (connection);
- if (!create_unique_client_name (&unique_name))
+ if (!create_unique_client_name (registry, &unique_name))
{
BUS_SET_OOM (error);
goto out_0;
@@ -297,7 +301,8 @@ bus_driver_handle_hello (DBusConnection *connection,
goto out_0;
/* Create the service */
- service = bus_service_ensure (&unique_name, connection, transaction, error);
+ service = bus_registry_ensure (registry,
+ &unique_name, connection, transaction, error);
if (service == NULL)
goto out_0;
@@ -367,7 +372,10 @@ bus_driver_handle_list_services (DBusConnection *connection,
DBusMessage *reply;
int len;
char **services;
-
+ BusRegistry *registry;
+
+ registry = bus_connection_get_registry (connection);
+
reply = dbus_message_new_reply (message);
if (reply == NULL)
{
@@ -375,8 +383,7 @@ bus_driver_handle_list_services (DBusConnection *connection,
return FALSE;
}
- services = bus_services_list (&len);
- if (services == NULL)
+ if (!bus_registry_list_services (registry, &services, &len))
{
dbus_message_unref (reply);
BUS_SET_OOM (error);
@@ -423,6 +430,9 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
dbus_bool_t retval;
DBusConnection *old_owner;
DBusConnection *current_owner;
+ BusRegistry *registry;
+
+ registry = bus_connection_get_registry (connection);
if (!dbus_message_get_args (message,
error,
@@ -438,7 +448,7 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
_dbus_string_init_const (&service_name, name);
- service = bus_service_lookup (&service_name);
+ service = bus_registry_lookup (registry, &service_name);
if (service != NULL)
old_owner = bus_service_get_primary_owner (service);
@@ -454,7 +464,8 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
if (service == NULL)
{
- service = bus_service_ensure (&service_name, connection, transaction, error);
+ service = bus_registry_ensure (registry,
+ &service_name, connection, transaction, error);
if (service == NULL)
goto out;
}
@@ -542,6 +553,9 @@ bus_driver_handle_service_exists (DBusConnection *connection,
BusService *service;
char *name;
dbus_bool_t retval;
+ BusRegistry *registry;
+
+ registry = bus_connection_get_registry (connection);
if (!dbus_message_get_args (message, error,
DBUS_TYPE_STRING, &name,
@@ -551,7 +565,7 @@ bus_driver_handle_service_exists (DBusConnection *connection,
retval = FALSE;
_dbus_string_init_const (&service_name, name);
- service = bus_service_lookup (&service_name);
+ service = bus_registry_lookup (registry, &service_name);
reply = dbus_message_new_reply (message);
if (reply == NULL)
@@ -599,6 +613,9 @@ bus_driver_handle_activate_service (DBusConnection *connection,
dbus_uint32_t flags;
char *name;
dbus_bool_t retval;
+ BusActivation *activation;
+
+ activation = bus_connection_get_activation (connection);
if (!dbus_message_get_args (message, error,
DBUS_TYPE_STRING, &name,
@@ -608,7 +625,7 @@ bus_driver_handle_activate_service (DBusConnection *connection,
retval = FALSE;
- if (!bus_activation_activate_service (name, error))
+ if (!bus_activation_activate_service (activation, name, error))
goto out;
retval = TRUE;
diff --git a/bus/main.c b/bus/main.c
index 56345c76..ce03a6a7 100644
--- a/bus/main.c
+++ b/bus/main.c
@@ -20,110 +20,41 @@
* 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 "driver.h"
-#include <dbus/dbus-list.h>
-
-static void
-server_watch_callback (DBusWatch *watch,
- unsigned int condition,
- void *data)
-{
- DBusServer *server = data;
-
- dbus_server_handle_watch (server, watch, condition);
-}
-
-static void
-add_server_watch (DBusWatch *watch,
- DBusServer *server)
-{
- bus_loop_add_watch (watch, server_watch_callback, server,
- NULL);
-}
-
-static void
-remove_server_watch (DBusWatch *watch,
- DBusServer *server)
-{
- bus_loop_remove_watch (watch, server_watch_callback, server);
-}
-
-static void
-setup_server (DBusServer *server)
-{
- dbus_server_set_watch_functions (server,
- (DBusAddWatchFunction) add_server_watch,
- (DBusRemoveWatchFunction) remove_server_watch,
- server,
- NULL);
-}
-
-static void
-new_connection_callback (DBusServer *server,
- DBusConnection *new_connection,
- void *data)
-{
- if (!bus_connection_setup (new_connection))
- ; /* we won't have ref'd the connection so it will die */
-}
+#include <dbus/dbus-internals.h>
int
main (int argc, char **argv)
{
- DBusServer *server;
- DBusResultCode result;
-
- if (argc < 2)
+ BusContext *context;
+ DBusError error;
+ const char *paths[] = { NULL, NULL };
+
+ if (argc < 3)
{
- _dbus_warn ("Give the server address as an argument\n");
+ /* FIXME obviously just for testing */
+ _dbus_warn ("Give the server address as an argument and activation directory as args\n");
return 1;
}
+ paths[0] = argv[2];
- server = dbus_server_listen (argv[1], &result);
- if (server == NULL)
+ dbus_error_init (&error);
+ context = bus_context_new (argv[1], paths, &error);
+ if (context == NULL)
{
- _dbus_warn ("Failed to start server on %s: %s\n",
- argv[1], dbus_result_to_string (result));
+ _dbus_warn ("Failed to start message bus: %s\n",
+ error.message);
+ dbus_error_free (&error);
return 1;
}
- if (argc < 3)
- {
- _dbus_warn ("No service location given, not activating activation\n");
- }
- else
- {
- const char *paths[] = { argv[2], NULL };
- DBusError error;
-
- dbus_error_init (&error);
- if (!bus_activation_init (argv[1], paths,
- &error))
- {
- _dbus_warn ("Could not initialize service activation: %s\n",
- error.message);
- dbus_error_free (&error);
- return 1;
- }
- }
-
- setup_server (server);
-
- bus_connection_init ();
-
- dbus_server_set_new_connection_function (server,
- new_connection_callback,
- NULL, NULL);
-
_dbus_verbose ("We are on D-Bus...\n");
bus_loop_run ();
- dbus_server_disconnect (server);
- dbus_server_unref (server);
+ bus_context_shutdown (context);
+ bus_context_unref (context);
return 0;
}
diff --git a/bus/services.c b/bus/services.c
index 22302af4..9508b2f7 100644
--- a/bus/services.c
+++ b/bus/services.c
@@ -32,65 +32,94 @@
struct BusService
{
+ BusRegistry *registry;
char *name;
DBusList *owners;
unsigned int prohibit_replacement : 1;
};
-static DBusHashTable *service_hash = NULL;
-static DBusMemPool *service_pool = NULL;
+struct BusRegistry
+{
+ int refcount;
+
+ DBusHashTable *service_hash;
+ DBusMemPool *service_pool;
+};
+
+BusRegistry*
+bus_registry_new (void)
+{
+ BusRegistry *registry;
+
+ registry = dbus_new0 (BusRegistry, 1);
+ if (registry == NULL)
+ return NULL;
+
+ registry->refcount = 1;
+
+ registry->service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
+ NULL, NULL);
+ if (registry->service_hash == NULL)
+ goto failed;
+
+ registry->service_pool = _dbus_mem_pool_new (sizeof (BusService),
+ TRUE);
+ if (registry->service_pool == NULL)
+ goto failed;
+
+ return registry;
+
+ failed:
+ bus_registry_unref (registry);
+ return NULL;
+}
+
+void
+bus_registry_ref (BusRegistry *registry)
+{
+ _dbus_assert (registry->refcount > 0);
+ registry->refcount += 1;
+}
-static dbus_bool_t
-init_hash (void)
+void
+bus_registry_unref (BusRegistry *registry)
{
- if (service_hash == NULL)
+ _dbus_assert (registry->refcount > 0);
+ registry->refcount -= 1;
+
+ if (registry->refcount == 0)
{
- service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
- NULL, NULL);
- service_pool = _dbus_mem_pool_new (sizeof (BusService),
- TRUE);
+ if (registry->service_hash)
+ _dbus_hash_table_unref (registry->service_hash);
+ if (registry->service_pool)
+ _dbus_mem_pool_free (registry->service_pool);
- if (service_hash == NULL || service_pool == NULL)
- {
- if (service_hash)
- {
- _dbus_hash_table_unref (service_hash);
- service_hash = NULL;
- }
- if (service_pool)
- {
- _dbus_mem_pool_free (service_pool);
- service_pool = NULL;
- }
- return FALSE;
- }
+ dbus_free (registry);
}
- return TRUE;
}
BusService*
-bus_service_lookup (const DBusString *service_name)
+bus_registry_lookup (BusRegistry *registry,
+ const DBusString *service_name)
{
const char *c_name;
BusService *service;
- if (!init_hash ())
- return NULL;
-
_dbus_string_get_const_data (service_name, &c_name);
- service = _dbus_hash_table_lookup_string (service_hash,
+ service = _dbus_hash_table_lookup_string (registry->service_hash,
c_name);
return service;
}
BusService*
-bus_service_ensure (const DBusString *service_name,
- DBusConnection *owner_if_created,
- BusTransaction *transaction,
- DBusError *error)
+bus_registry_ensure (BusRegistry *registry,
+ const DBusString *service_name,
+ DBusConnection *owner_if_created,
+ BusTransaction *transaction,
+ DBusError *error)
{
const char *c_name;
BusService *service;
@@ -98,27 +127,26 @@ bus_service_ensure (const DBusString *service_name,
_dbus_assert (owner_if_created != NULL);
_dbus_assert (transaction != NULL);
- if (!init_hash ())
- return NULL;
-
_dbus_string_get_const_data (service_name, &c_name);
- service = _dbus_hash_table_lookup_string (service_hash,
+ service = _dbus_hash_table_lookup_string (registry->service_hash,
c_name);
if (service != NULL)
return service;
- service = _dbus_mem_pool_alloc (service_pool);
+ service = _dbus_mem_pool_alloc (registry->service_pool);
if (service == NULL)
{
BUS_SET_OOM (error);
return NULL;
}
+ service->registry = registry;
+
service->name = _dbus_strdup (c_name);
if (service->name == NULL)
{
- _dbus_mem_pool_dealloc (service_pool, service);
+ _dbus_mem_pool_dealloc (registry->service_pool, service);
BUS_SET_OOM (error);
return NULL;
}
@@ -126,7 +154,7 @@ bus_service_ensure (const DBusString *service_name,
if (!bus_driver_send_service_created (service->name, transaction, error))
{
dbus_free (service->name);
- _dbus_mem_pool_dealloc (service_pool, service);
+ _dbus_mem_pool_dealloc (registry->service_pool, service);
return NULL;
}
@@ -134,17 +162,17 @@ bus_service_ensure (const DBusString *service_name,
transaction, error))
{
dbus_free (service->name);
- _dbus_mem_pool_dealloc (service_pool, service);
+ _dbus_mem_pool_dealloc (registry->service_pool, service);
return NULL;
}
- if (!_dbus_hash_table_insert_string (service_hash,
+ if (!_dbus_hash_table_insert_string (registry->service_hash,
service->name,
service))
{
_dbus_list_clear (&service->owners);
dbus_free (service->name);
- _dbus_mem_pool_dealloc (service_pool, service);
+ _dbus_mem_pool_dealloc (registry->service_pool, service);
BUS_SET_OOM (error);
return NULL;
}
@@ -152,6 +180,66 @@ bus_service_ensure (const DBusString *service_name,
return service;
}
+void
+bus_registry_foreach (BusRegistry *registry,
+ BusServiceForeachFunction function,
+ void *data)
+{
+ DBusHashIter iter;
+
+ _dbus_hash_iter_init (registry->service_hash, &iter);
+ while (_dbus_hash_iter_next (&iter))
+ {
+ BusService *service = _dbus_hash_iter_get_value (&iter);
+
+ (* function) (service, data);
+ }
+}
+
+dbus_bool_t
+bus_registry_list_services (BusRegistry *registry,
+ char ***listp,
+ int *array_len)
+{
+ int i, j, len;
+ char **retval;
+ DBusHashIter iter;
+
+ len = _dbus_hash_table_get_n_entries (registry->service_hash);
+ retval = dbus_new (char *, len + 1);
+
+ if (retval == NULL)
+ return FALSE;
+
+ _dbus_hash_iter_init (registry->service_hash, &iter);
+ i = 0;
+ while (_dbus_hash_iter_next (&iter))
+ {
+ BusService *service = _dbus_hash_iter_get_value (&iter);
+
+ retval[i] = _dbus_strdup (service->name);
+ if (retval[i] == NULL)
+ goto error;
+
+ i++;
+ }
+
+ retval[i] = NULL;
+
+ if (array_len)
+ *array_len = len;
+
+ *listp = retval;
+ return TRUE;
+
+ error:
+ for (j = 0; j < i; j++)
+ dbus_free (retval[i]);
+ dbus_free (retval);
+
+ return FALSE;
+}
+
dbus_bool_t
bus_service_add_owner (BusService *service,
DBusConnection *owner,
@@ -232,10 +320,10 @@ bus_service_remove_owner (BusService *service,
if (service->owners == NULL)
{
/* Delete service (already sent message that it was deleted above) */
- _dbus_hash_table_remove_string (service_hash, service->name);
+ _dbus_hash_table_remove_string (service->registry->service_hash, service->name);
dbus_free (service->name);
- _dbus_mem_pool_dealloc (service_pool, service);
+ _dbus_mem_pool_dealloc (service->registry->service_pool, service);
}
return TRUE;
@@ -254,65 +342,6 @@ bus_service_get_name (BusService *service)
}
void
-bus_service_foreach (BusServiceForeachFunction function,
- void *data)
-{
- DBusHashIter iter;
-
- if (service_hash == NULL)
- return;
-
- _dbus_hash_iter_init (service_hash, &iter);
- while (_dbus_hash_iter_next (&iter))
- {
- BusService *service = _dbus_hash_iter_get_value (&iter);
-
- (* function) (service, data);
- }
-}
-
-char **
-bus_services_list (int *array_len)
-{
- int i, j, len;
- char **retval;
- DBusHashIter iter;
-
- len = _dbus_hash_table_get_n_entries (service_hash);
- retval = dbus_new (char *, len + 1);
-
- if (retval == NULL)
- return NULL;
-
- _dbus_hash_iter_init (service_hash, &iter);
- i = 0;
- while (_dbus_hash_iter_next (&iter))
- {
- BusService *service = _dbus_hash_iter_get_value (&iter);
-
- retval[i] = _dbus_strdup (service->name);
- if (retval[i] == NULL)
- goto error;
-
- i++;
- }
-
- retval[i] = NULL;
-
- if (array_len)
- *array_len = len;
-
- return retval;
-
- error:
- for (j = 0; j < i; j++)
- dbus_free (retval[i]);
- dbus_free (retval);
-
- return NULL;
-}
-
-void
bus_service_set_prohibit_replacement (BusService *service,
dbus_bool_t prohibit_replacement)
{
diff --git a/bus/services.h b/bus/services.h
index 97583582..5e9ece18 100644
--- a/bus/services.h
+++ b/bus/services.h
@@ -27,26 +27,29 @@
#include <dbus/dbus.h>
#include <dbus/dbus-string.h>
#include "connection.h"
-
-/* forward decl that probably shouldn't be in this file */
-typedef struct BusTransaction BusTransaction;
-
-/* Each service can have multiple owners; one owner is the "real
- * owner" and the others are queued up. For example, if I have
- * multiple text editors open, one might own the TextEditor service;
- * if I close that one, the next in line will become the owner of it.
- */
-
-typedef struct BusService BusService;
+#include "bus.h"
typedef void (* BusServiceForeachFunction) (BusService *service,
void *data);
-BusService* bus_service_lookup (const DBusString *service_name);
-BusService* bus_service_ensure (const DBusString *service_name,
- DBusConnection *owner_if_created,
- BusTransaction *transaction,
- DBusError *error);
+BusRegistry* bus_registry_new (void);
+void bus_registry_ref (BusRegistry *registry);
+void bus_registry_unref (BusRegistry *registry);
+BusService* bus_registry_lookup (BusRegistry *registry,
+ const DBusString *service_name);
+BusService* bus_registry_ensure (BusRegistry *registry,
+ const DBusString *service_name,
+ DBusConnection *owner_if_created,
+ BusTransaction *transaction,
+ DBusError *error);
+void bus_registry_foreach (BusRegistry *registry,
+ BusServiceForeachFunction function,
+ void *data);
+dbus_bool_t bus_registry_list_services (BusRegistry *registry,
+ char ***listp,
+ int *array_len);
+
+
dbus_bool_t bus_service_add_owner (BusService *service,
DBusConnection *owner,
BusTransaction *transaction,
@@ -62,10 +65,5 @@ void bus_service_set_prohibit_replacement (BusService
dbus_bool_t prohibit_replacement);
dbus_bool_t bus_service_get_prohibit_replacement (BusService *service);
const char* bus_service_get_name (BusService *service);
-void bus_service_foreach (BusServiceForeachFunction function,
- void *data);
-
-
-char **bus_services_list (int *array_len);
#endif /* BUS_SERVICES_H */
diff --git a/test/Makefile.am b/test/Makefile.am
index 47e96689..8c527bef 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -2,7 +2,7 @@
INCLUDES=-I$(top_srcdir) $(DBUS_TEST_CFLAGS)
if DBUS_BUILD_TESTS
-TEST_BINARIES=echo-client echo-server unbase64 bus-test break-loader spawn-test
+TEST_BINARIES=echo-client echo-server unbase64 break-loader spawn-test
else
TEST_BINARIES=
endif
@@ -22,13 +22,12 @@ echo_server_SOURCES= \
unbase64_SOURCES= \
unbase64.c
-
-bus_test_SOURCES = \
- debug-thread.c \
- debug-thread.h \
- bus-test.c \
- bus-test-loop.c \
- bus-test-loop.h
+# bus_test_SOURCES = \
+# debug-thread.c \
+# debug-thread.h \
+# bus-test.c \
+# bus-test-loop.c \
+# bus-test-loop.h
break_loader_SOURCES= \
break-loader.c
@@ -42,7 +41,7 @@ echo_client_LDADD=$(TEST_LIBS)
echo_server_LDADD=$(TEST_LIBS)
unbase64_LDADD=$(TEST_LIBS)
break_loader_LDADD= $(TEST_LIBS)
-bus_test_LDADD=$(TEST_LIBS) $(top_builddir)/bus/libdbus-daemon.la
+#bus_test_LDADD=$(TEST_LIBS) $(top_builddir)/bus/libdbus-daemon.la
spawn_test_LDADD=$(TEST_LIBS)
dist-hook: