diff options
| -rw-r--r-- | ChangeLog | 11 | ||||
| -rw-r--r-- | bus/Makefile.am | 2 | ||||
| -rw-r--r-- | bus/activation.c | 101 | ||||
| -rw-r--r-- | bus/activation.h | 15 | ||||
| -rw-r--r-- | bus/bus.c | 202 | ||||
| -rw-r--r-- | bus/bus.h | 48 | ||||
| -rw-r--r-- | bus/connection.c | 199 | ||||
| -rw-r--r-- | bus/connection.h | 24 | ||||
| -rw-r--r-- | bus/dispatch.c | 21 | ||||
| -rw-r--r-- | bus/driver.c | 39 | ||||
| -rw-r--r-- | bus/main.c | 105 | ||||
| -rw-r--r-- | bus/services.c | 237 | ||||
| -rw-r--r-- | bus/services.h | 40 | ||||
| -rw-r--r-- | test/Makefile.am | 17 | 
14 files changed, 738 insertions, 323 deletions
@@ -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; @@ -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:  | 
