2003-03-12 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Thu, 13 Mar 2003 03:52:58 +0000 (03:52 +0000)
committerHavoc Pennington <hp@redhat.com>
Thu, 13 Mar 2003 03:52:58 +0000 (03:52 +0000)
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

14 files changed:
ChangeLog
bus/Makefile.am
bus/activation.c
bus/activation.h
bus/bus.c [new file with mode: 0644]
bus/bus.h [new file with mode: 0644]
bus/connection.c
bus/connection.h
bus/dispatch.c
bus/driver.c
bus/main.c
bus/services.c
bus/services.h
test/Makefile.am

index c7bc436..9591317 100644 (file)
--- 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 
index d84e99d..f9f4dbf 100644 (file)
@@ -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                          \
index 4e428bd..ba130ed 100644 (file)
 #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;
 
index e7a9cdf..4e363c9 100644 (file)
 #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 (file)
index 0000000..7ac0bee
--- /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 (file)
index 0000000..4d922f0
--- /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 */
index ff671c5..cdc8be7 100644 (file)
 
 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,
index a7a448a..f78c3ac 100644 (file)
 #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);
index d9fe81a..1d2ea1c 100644 (file)
@@ -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)
         {
index 4698559..09ec18a 100644 (file)
@@ -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;
index 56345c7..ce03a6a 100644 (file)
  * 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;
 }
index 22302af..9508b2f 100644 (file)
 
 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)
 {
index 9758358..5e9ece1 100644 (file)
 #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 */
index 47e9668..8c527be 100644 (file)
@@ -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: