dbus/dbus dbus-auth-script.c, 1.16, 1.17 dbus-auth.c, 1.41, 1.42 dbus-auth.h, 1.11, 1.12 dbus-connection.c, 1.100, 1.101 dbus-connection.h, 1.34, 1.35 dbus-internals.h, 1.54, 1.55 dbus-server-debug-pipe.c, 1.17, 1.18 dbus-server-protected.h, 1.18, 1.19 dbus-server-unix.c, 1.27, 1.28 dbus-server.c, 1.40, 1.41 dbus-threads.c, 1.22, 1.23 dbus-transport-protected.h, 1.15, 1.16 dbus-transport-unix.c, 1.45, 1.46 dbus-transport-unix.h, 1.9, 1.10 dbus-transport.c, 1.44, 1.45 dbus-transport.h, 1.19, 1.20

Havoc Pennington hp at freedesktop.org
Fri Feb 25 22:37:48 PST 2005


Update of /cvs/dbus/dbus/dbus
In directory gabe:/tmp/cvs-serv8168/dbus

Modified Files:
	dbus-auth-script.c dbus-auth.c dbus-auth.h dbus-connection.c 
	dbus-connection.h dbus-internals.h dbus-server-debug-pipe.c 
	dbus-server-protected.h dbus-server-unix.c dbus-server.c 
	dbus-threads.c dbus-transport-protected.h 
	dbus-transport-unix.c dbus-transport-unix.h dbus-transport.c 
	dbus-transport.h 
Log Message:
2005-02-26  Havoc Pennington  <hp at redhat.com>

	* doc/TODO: remove the "guid" item

	* test/glib/test-profile.c (no_bus_thread_func): use open_private
	(with_bus_thread_func): use open_private

	* dbus/dbus-connection.c (dbus_connection_open_private): new
	function that works like the old dbus_connection_open()
	(dbus_connection_open): now returns an existing connection if
	possible

	* dbus/dbus-server-unix.c (handle_new_client_fd_and_unlock): pass
	through the GUID to the transport

	* dbus/dbus-server.c (_dbus_server_init_base): keep around the
	GUID in hex-encoded form.

	* dbus/dbus-server-debug-pipe.c (_dbus_transport_debug_pipe_new):
	pass GUID argument in to the transport

	* dbus/dbus-transport-unix.c (_dbus_transport_new_for_fd): add
	guid argument

	* dbus/dbus-transport.c (_dbus_transport_init_base): add guid argument

	* dbus/dbus-auth.c (_dbus_auth_server_new): add guid argument



Index: dbus-auth-script.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-auth-script.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- dbus-auth-script.c	15 Jan 2005 07:15:38 -0000	1.16
+++ dbus-auth-script.c	26 Feb 2005 06:37:46 -0000	1.17
@@ -231,10 +231,12 @@
   DBusString from_auth;
   DBusAuthState state;
   DBusString context;
+  DBusString guid;
   
   retval = FALSE;
   auth = NULL;
 
+  _dbus_string_init_const (&guid, "5fa01f4202cd837709a3274ca0df9d00");
   _dbus_string_init_const (&context, "org_freedesktop_test");
   
   if (!_dbus_string_init (&file))
@@ -334,7 +336,7 @@
               goto out;
             }
 
-          auth = _dbus_auth_server_new ();
+          auth = _dbus_auth_server_new (&guid);
           if (auth == NULL)
             {
               _dbus_warn ("no memory to create DBusAuth\n");

Index: dbus-auth.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-auth.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- dbus-auth.c	7 Feb 2005 05:44:57 -0000	1.41
+++ dbus-auth.c	26 Feb 2005 06:37:46 -0000	1.42
@@ -211,6 +211,8 @@
 
   int failures;     /**< Number of times client has been rejected */
   int max_failures; /**< Number of times we reject before disconnect */
+
+  DBusString guid;  /**< Our globally unique ID in hex encoding */
   
 } DBusAuthServer;
 
@@ -1923,20 +1925,35 @@
  * @returns the new object or #NULL if no memory
  */
 DBusAuth*
-_dbus_auth_server_new (void)
+_dbus_auth_server_new (const DBusString *guid)
 {
   DBusAuth *auth;
   DBusAuthServer *server_auth;
+  DBusString guid_copy;
 
-  auth = _dbus_auth_new (sizeof (DBusAuthServer));
-  if (auth == NULL)
+  if (!_dbus_string_init (&guid_copy))
     return NULL;
 
+  if (!_dbus_string_copy (guid, 0, &guid_copy, 0))
+    {
+      _dbus_string_free (&guid_copy);
+      return NULL;
+    }
+
+  auth = _dbus_auth_new (sizeof (DBusAuthServer));
+  if (auth == NULL)
+    {
+      _dbus_string_free (&guid_copy);
+      return NULL;
+    }
+  
   auth->side = auth_side_server;
   auth->state = &server_state_waiting_for_auth;
 
   server_auth = DBUS_AUTH_SERVER (auth);
 
+  server_auth->guid = guid_copy;
+  
   /* perhaps this should be per-mechanism with a lower
    * max
    */
@@ -2012,6 +2029,12 @@
         {
           _dbus_list_clear (& DBUS_AUTH_CLIENT (auth)->mechs_to_try);
         }
+      else
+        {
+          _dbus_assert (DBUS_AUTH_IS_SERVER (auth));
+
+          _dbus_string_free (& DBUS_AUTH_SERVER (auth)->guid);
+        }
 
       if (auth->keyring)
         _dbus_keyring_unref (auth->keyring);

Index: dbus-auth.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-auth.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- dbus-auth.h	9 Sep 2004 10:20:17 -0000	1.11
+++ dbus-auth.h	26 Feb 2005 06:37:46 -0000	1.12
@@ -41,7 +41,7 @@
   DBUS_AUTH_STATE_AUTHENTICATED
 } DBusAuthState;
 
-DBusAuth*     _dbus_auth_server_new          (void);
+DBusAuth*     _dbus_auth_server_new          (const DBusString       *guid);
 DBusAuth*     _dbus_auth_client_new          (void);
 DBusAuth*     _dbus_auth_ref                 (DBusAuth               *auth);
 void          _dbus_auth_unref               (DBusAuth               *auth);

Index: dbus-connection.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.c,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -d -r1.100 -r1.101
--- dbus-connection.c	24 Feb 2005 18:37:16 -0000	1.100
+++ dbus-connection.c	26 Feb 2005 06:37:46 -0000	1.101
@@ -233,6 +233,10 @@
                          *   for the global linked list mempool lock
                          */
   DBusObjectTree *objects; /**< Object path handlers registered with this connection */
+
+  char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */
+
+  unsigned int shareable : 1; /**< #TRUE if connection can go in shared_connections once we know the GUID */
   
   unsigned int dispatch_acquired : 1; /**< Someone has dispatch path (can drain incoming queue) */
   unsigned int io_path_acquired : 1;  /**< Someone has transport io path (can use the transport to read/write messages) */
@@ -1175,6 +1179,7 @@
   connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
   connection->objects = objects;
   connection->exit_on_disconnect = FALSE;
+  connection->shareable = FALSE;
 #ifndef DBUS_DISABLE_CHECKS
   connection->generation = _dbus_current_generation;
 #endif
@@ -1363,6 +1368,301 @@
   return retval;
 }
 
+_DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
+static DBusHashTable *shared_connections = NULL;
+
+static void
+shared_connections_shutdown (void *data)
+{
+  _DBUS_LOCK (shared_connections);
+
+  _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
+  _dbus_hash_table_unref (shared_connections);
+  shared_connections = NULL;
+  
+  _DBUS_UNLOCK (shared_connections);
+}
+
+static dbus_bool_t
+connection_lookup_shared (DBusAddressEntry  *entry,
+                          DBusConnection   **result)
+{
+  _dbus_verbose ("checking for existing connection\n");
+  
+  *result = NULL;
+  
+  _DBUS_LOCK (shared_connections);
+
+  if (shared_connections == NULL)
+    {
+      _dbus_verbose ("creating shared_connections hash table\n");
+      
+      shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
+                                                 dbus_free,
+                                                 NULL);
+      if (shared_connections == NULL)
+        {
+          _DBUS_UNLOCK (shared_connections);
+          return FALSE;
+        }
+
+      if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
+        {
+          _dbus_hash_table_unref (shared_connections);
+          shared_connections = NULL;
+          _DBUS_UNLOCK (shared_connections);
+          return FALSE;
+        }
+
+      _dbus_verbose ("  successfully created shared_connections\n");
+      
+      _DBUS_UNLOCK (shared_connections);
+      return TRUE; /* no point looking up in the hash we just made */
+    }
+  else
+    {
+      const char *guid;
+
+      guid = dbus_address_entry_get_value (entry, "guid");
+      
+      if (guid != NULL)
+        {
+          *result = _dbus_hash_table_lookup_string (shared_connections,
+                                                    guid);
+
+          if (*result)
+            {
+              /* The DBusConnection can't have been disconnected
+               * between the lookup and this code, because the
+               * disconnection will take the shared_connections lock to
+               * remove the connection. It can't have been finalized
+               * since you have to disconnect prior to finalize.
+               *
+               * Thus it's safe to ref the connection.
+               */
+              dbus_connection_ref (*result);
+
+              _dbus_verbose ("looked up existing connection to server guid %s\n",
+                             guid);
+            }
+        }
+      
+      _DBUS_UNLOCK (shared_connections);
+      return TRUE;
+    }
+}
+
+static dbus_bool_t
+connection_record_shared_unlocked (DBusConnection *connection,
+                                   const char     *guid)
+{
+  char *guid_key;
+  char *guid_in_connection;
+
+  /* A separate copy of the key is required in the hash table, because
+   * we don't have a lock on the connection when we are doing a hash
+   * lookup.
+   */
+  
+  _dbus_assert (connection->server_guid == NULL);
+  _dbus_assert (connection->shareable);
+  
+  guid_key = _dbus_strdup (guid);
+  if (guid_key == NULL)
+    return FALSE;
+
+  guid_in_connection = _dbus_strdup (guid);
+  if (guid_in_connection == NULL)
+    {
+      dbus_free (guid_key);
+      return FALSE;
+    }
+  
+  _DBUS_LOCK (shared_connections);
+  _dbus_assert (shared_connections != NULL);
+  
+  if (!_dbus_hash_table_insert_string (shared_connections,
+                                       guid_key, connection))
+    {
+      dbus_free (guid_key);
+      dbus_free (guid_in_connection);
+      _DBUS_UNLOCK (shared_connections);
+      return FALSE;
+    }
+
+  connection->server_guid = guid_in_connection;
+
+  _dbus_verbose ("stored connection to %s to be shared\n",
+                 connection->server_guid);
+  
+  _DBUS_UNLOCK (shared_connections);
+
+  _dbus_assert (connection->server_guid != NULL);
+  
+  return TRUE;
+}
+
+static void
+connection_forget_shared_unlocked (DBusConnection *connection)
+{
+  HAVE_LOCK_CHECK (connection);
+  
+  if (connection->server_guid == NULL)
+    return;
+
+  _dbus_verbose ("dropping connection to %s out of the shared table\n",
+                 connection->server_guid);
+  
+  _DBUS_LOCK (shared_connections);
+
+  if (!_dbus_hash_table_remove_string (shared_connections,
+                                       connection->server_guid))
+    _dbus_assert_not_reached ("connection was not in the shared table");
+  
+  dbus_free (connection->server_guid);
+  connection->server_guid = NULL;
+
+  _DBUS_UNLOCK (shared_connections);
+}
+
+static DBusConnection*
+connection_try_from_address_entry (DBusAddressEntry *entry,
+                                   DBusError        *error)
+{
+  DBusTransport *transport;
+  DBusConnection *connection;
+
+  transport = _dbus_transport_open (entry, error);
+
+  if (transport == NULL)
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      return NULL;
+    }
+
+  connection = _dbus_connection_new_for_transport (transport);
+
+  _dbus_transport_unref (transport);
+  
+  if (connection == NULL)
+    {
+      _DBUS_SET_OOM (error);
+      return NULL;
+    }
+
+#ifndef DBUS_DISABLE_CHECKS
+  _dbus_assert (!connection->have_connection_lock);
+#endif
+  return connection;
+}
+
+/*
+ * If the shared parameter is true, then any existing connection will
+ * be used (and if a new connection is created, it will be available
+ * for use by others). If the shared parameter is false, a new
+ * connection will always be created, and the new connection will
+ * never be returned to other callers.
+ *
+ * @param address the address
+ * @param shared whether the connection is shared or private
+ * @param error error return
+ * @returns the connection or #NULL on error
+ */
+static DBusConnection*
+_dbus_connection_open_internal (const char     *address,
+                                dbus_bool_t     shared,
+                                DBusError      *error)
+{
+  DBusConnection *connection;
+  DBusAddressEntry **entries;
+  DBusError tmp_error;
+  DBusError first_error;
+  int len, i;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  _dbus_verbose ("opening %s connection to: %s\n",
+                 shared ? "shared" : "private", address);
+  
+  if (!dbus_parse_address (address, &entries, &len, error))
+    return NULL;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  
+  connection = NULL;
+
+  dbus_error_init (&tmp_error);
+  dbus_error_init (&first_error);
+  for (i = 0; i < len; i++)
+    {
+      if (shared)
+        {
+          if (!connection_lookup_shared (entries[i], &connection))
+            _DBUS_SET_OOM (&tmp_error);
+        }
+
+      if (connection == NULL)
+        {
+          connection = connection_try_from_address_entry (entries[i],
+                                                          &tmp_error);
+          
+          if (connection != NULL && shared)
+            {
+              const char *guid;
+
+              connection->shareable = TRUE;
+              
+              guid = dbus_address_entry_get_value (entries[i], "guid");
+
+              /* we don't have a connection lock but we know nobody
+               * else has a handle to the connection
+               */
+              
+              if (guid &&
+                  !connection_record_shared_unlocked (connection, guid))
+                {
+                  _DBUS_SET_OOM (&tmp_error);
+                  dbus_connection_disconnect (connection);
+                  dbus_connection_unref (connection);
+                  connection = NULL;
+                }
+
+              /* but as of now the connection is possibly shared
+               * since another thread could have pulled it from the table
+               */
+            }
+        }
+      
+      if (connection)
+	break;
+
+      _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
+      
+      if (i == 0)
+        dbus_move_error (&tmp_error, &first_error);
+      else
+        dbus_error_free (&tmp_error);
+    }
+
+  /* NOTE we don't have a lock on a possibly-shared connection object */
+  
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
+  
+  if (connection == NULL)
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (&first_error);
+      dbus_move_error (&first_error, error);
+    }
+  else
+    {
+      dbus_error_free (&first_error);
+    }
+  
+  dbus_address_entries_free (entries);
+  return connection;
+}
+
 /** @} */
 
 /**
@@ -1372,16 +1672,19 @@
  */
 
 /**
- * Opens a new connection to a remote address.
+ * Gets a connection to a remote address. If a connection to the given
+ * address already exists, returns the existing connection with its
+ * reference count incremented.  Otherwise, returns a new connection
+ * and saves the new connection for possible re-use if a future call
+ * to dbus_connection_open() asks to connect to the same server.
  *
- * @todo specify what the address parameter is. Right now
- * it's just the name of a UNIX domain socket. It should be
- * something more complex that encodes which transport to use.
+ * Use dbus_connection_open_private() to get a dedicated connection
+ * not shared with other callers of dbus_connection_open().
  *
- * If the open fails, the function returns #NULL, and provides
- * a reason for the failure in the result parameter. Pass
- * #NULL for the result parameter if you aren't interested
- * in the reason for failure.
+ * If the open fails, the function returns #NULL, and provides a
+ * reason for the failure in the error parameter. Pass #NULL for the
+ * error parameter if you aren't interested in the reason for
+ * failure.
  * 
  * @param address the address.
  * @param error address where an error can be returned.
@@ -1392,31 +1695,44 @@
                       DBusError      *error)
 {
   DBusConnection *connection;
-  DBusTransport *transport;
 
   _dbus_return_val_if_fail (address != NULL, NULL);
   _dbus_return_val_if_error_is_set (error, NULL);
-  
-  transport = _dbus_transport_open (address, error);
-  if (transport == NULL)
-    {
-      _DBUS_ASSERT_ERROR_IS_SET (error);
-      return NULL;
-    }
-  
-  connection = _dbus_connection_new_for_transport (transport);
 
-  _dbus_transport_unref (transport);
-  
-  if (connection == NULL)
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      return NULL;
-    }
+  connection = _dbus_connection_open_internal (address,
+                                               TRUE,
+                                               error);
+
+  return connection;
+}
+
+/**
+ * Opens a new, dedicated connection to a remote address. Unlike
+ * dbus_connection_open(), always creates a new connection.
+ * This connection will not be saved or recycled by libdbus.
+ *
+ * If the open fails, the function returns #NULL, and provides a
+ * reason for the failure in the error parameter. Pass #NULL for the
+ * error parameter if you aren't interested in the reason for
+ * failure.
+ * 
+ * @param address the address.
+ * @param error address where an error can be returned.
+ * @returns new connection, or #NULL on failure.
+ */
+DBusConnection*
+dbus_connection_open_private (const char     *address,
+                              DBusError      *error)
+{
+  DBusConnection *connection;
+
+  _dbus_return_val_if_fail (address != NULL, NULL);
+  _dbus_return_val_if_error_is_set (error, NULL);
+
+  connection = _dbus_connection_open_internal (address,
+                                               FALSE,
+                                               error);
 
-#ifndef DBUS_DISABLE_CHECKS
-  _dbus_assert (!connection->have_connection_lock);
-#endif
   return connection;
 }
 
@@ -1479,7 +1795,8 @@
    * you won't get the disconnected message.
    */
   _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
-
+  _dbus_assert (connection->server_guid == NULL);
+  
   /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
   _dbus_object_tree_free_all_unlocked (connection->objects);
   
@@ -1529,7 +1846,7 @@
   _dbus_list_clear (&connection->incoming_messages);
 
   _dbus_counter_unref (connection->outgoing_counter);
-  
+
   _dbus_transport_unref (connection->transport);
 
   if (connection->disconnect_message_link)
@@ -1620,6 +1937,7 @@
   _dbus_verbose ("Disconnecting %p\n", connection);
   
   CONNECTION_LOCK (connection);
+  
   _dbus_transport_disconnect (connection->transport);
 
   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
@@ -2838,7 +3156,9 @@
             {
               _dbus_verbose ("Sending disconnect message from %s\n",
                              _DBUS_FUNCTION_NAME);
-                             
+
+              connection_forget_shared_unlocked (connection);
+              
               /* We haven't sent the disconnect message already,
                * and all real messages have been queued up.
                */

Index: dbus-connection.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- dbus-connection.h	26 Nov 2004 01:53:13 -0000	1.34
+++ dbus-connection.h	26 Feb 2005 06:37:46 -0000	1.35
@@ -89,6 +89,8 @@
 
 DBusConnection*    dbus_connection_open                         (const char                 *address,
                                                                  DBusError                  *error);
+DBusConnection*    dbus_connection_open_private                 (const char                 *address,
+                                                                 DBusError                  *error);
 DBusConnection*    dbus_connection_ref                          (DBusConnection             *connection);
 void               dbus_connection_unref                        (DBusConnection             *connection);
 void               dbus_connection_disconnect                   (DBusConnection             *connection);

Index: dbus-internals.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.h,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- dbus-internals.h	25 Feb 2005 22:03:30 -0000	1.54
+++ dbus-internals.h	26 Feb 2005 06:37:46 -0000	1.55
@@ -280,7 +280,8 @@
 _DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs);
 _DBUS_DECLARE_GLOBAL_LOCK (system_users);
 _DBUS_DECLARE_GLOBAL_LOCK (message_cache);
-#define _DBUS_N_GLOBAL_LOCKS (10)
+_DBUS_DECLARE_GLOBAL_LOCK (shared_connections);
+#define _DBUS_N_GLOBAL_LOCKS (11)
 
 dbus_bool_t _dbus_threads_init_debug (void);
 

Index: dbus-server-debug-pipe.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-debug-pipe.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- dbus-server-debug-pipe.c	11 Feb 2005 03:37:03 -0000	1.17
+++ dbus-server-debug-pipe.c	26 Feb 2005 06:37:46 -0000	1.18
@@ -270,9 +270,9 @@
   _dbus_string_free (&address);
   
   client_fd = -1;
-  
+
   server_transport = _dbus_transport_new_for_fd (server_fd,
-                                                 TRUE, NULL);
+                                                 &server->guid_hex, NULL);
   if (server_transport == NULL)
     {
       _dbus_transport_unref (client_transport);

Index: dbus-server-protected.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-protected.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- dbus-server-protected.h	25 Feb 2005 22:03:30 -0000	1.18
+++ dbus-server-protected.h	26 Feb 2005 06:37:46 -0000	1.19
@@ -31,6 +31,7 @@
 #include <dbus/dbus-watch.h>
 #include <dbus/dbus-resources.h>
 #include <dbus/dbus-dataslot.h>
+#include <dbus/dbus-string.h>
 
 DBUS_BEGIN_DECLS
 
@@ -67,7 +68,9 @@
   const DBusServerVTable *vtable;             /**< Virtual methods for this instance. */
   DBusMutex *mutex;                           /**< Lock on the server object */
 
-  DBusGUID guid;                              /**< Globally unique ID of server */ 
+  DBusGUID guid;                              /**< Globally unique ID of server */
+
+  DBusString guid_hex;                        /**< Hex-encoded version of GUID */
   
   DBusWatchList *watches;                     /**< Our watches */
   DBusTimeoutList *timeouts;                  /**< Our timeouts */  

Index: dbus-server-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-unix.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- dbus-server-unix.c	24 Feb 2005 18:37:16 -0000	1.27
+++ dbus-server-unix.c	26 Feb 2005 06:37:46 -0000	1.28
@@ -99,7 +99,7 @@
       return TRUE;
     }
   
-  transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL);
+  transport = _dbus_transport_new_for_fd (client_fd, &server->guid_hex, NULL);
   if (transport == NULL)
     {
       close (client_fd);

Index: dbus-server.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- dbus-server.c	25 Feb 2005 22:03:30 -0000	1.40
+++ dbus-server.c	26 Feb 2005 06:37:46 -0000	1.41
@@ -75,33 +75,30 @@
  */
 static char*
 copy_address_with_guid_appended (const DBusString *address,
-                                 const DBusGUID   *guid)
+                                 const DBusString *guid_hex)
 {
   DBusString with_guid;
-  DBusString guid_str;
   char *retval;
   
   if (!_dbus_string_init (&with_guid))
     return NULL;
 
-  _dbus_string_init_const_len (&guid_str, guid->as_bytes,
-                               sizeof (guid->as_bytes));
-
-  if (!_dbus_string_copy (address, 0, &with_guid, 0) ||
+  if (!_dbus_string_copy (address, 0, &with_guid,
+                          _dbus_string_get_length (&with_guid)) ||
       !_dbus_string_append (&with_guid, ",guid=") ||
-      !_dbus_string_hex_encode (&guid_str, 0,
-                                &with_guid, _dbus_string_get_length (&with_guid)))
+      !_dbus_string_copy (guid_hex, 0,
+                          &with_guid, _dbus_string_get_length (&with_guid)))
     {
       _dbus_string_free (&with_guid);
       return NULL;
     }
 
   retval = NULL;
-  _dbus_string_copy_data (&with_guid, &retval);
+  _dbus_string_steal_data (&with_guid, &retval);
 
   _dbus_string_free (&with_guid);
       
-  return retval; /* may be NULL if copy failed */
+  return retval; /* may be NULL if steal_data failed */
 }
 
 /**
@@ -117,7 +114,9 @@
 _dbus_server_init_base (DBusServer             *server,
                         const DBusServerVTable *vtable,
                         const DBusString       *address)
-{  
+{
+  DBusString guid_raw;
+  
   server->vtable = vtable;
   server->refcount.value = 1;
 
@@ -125,10 +124,20 @@
   server->watches = NULL;
   server->timeouts = NULL;
 
+  if (!_dbus_string_init (&server->guid_hex))
+    return FALSE;
+
   init_guid (&server->guid);
 
+  _dbus_string_init_const_len (&guid_raw, server->guid.as_bytes,
+                               sizeof (server->guid.as_bytes));
+  if (!_dbus_string_hex_encode (&guid_raw, 0,
+                                &server->guid_hex,
+                                _dbus_string_get_length (&server->guid_hex)))
+    goto failed;
+  
   server->address = copy_address_with_guid_appended (address,
-                                                     &server->guid);
+                                                     &server->guid_hex);
   if (server->address == NULL)
     goto failed;
   
@@ -171,6 +180,7 @@
       dbus_free (server->address);
       server->address = NULL;
     }
+  _dbus_string_free (&server->guid_hex);
   
   return FALSE;
 }
@@ -205,6 +215,8 @@
   dbus_free (server->address);
 
   dbus_free_string_array (server->auth_mechanisms);
+
+  _dbus_string_free (&server->guid_hex);
 }
 
 

Index: dbus-threads.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-threads.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- dbus-threads.c	24 Feb 2005 18:37:16 -0000	1.22
+++ dbus-threads.c	26 Feb 2005 06:37:46 -0000	1.23
@@ -231,7 +231,8 @@
     LOCK_ADDR (bus),
     LOCK_ADDR (shutdown_funcs),
     LOCK_ADDR (system_users),
-    LOCK_ADDR (message_cache)
+    LOCK_ADDR (message_cache),
+    LOCK_ADDR (shared_connections)
 #undef LOCK_ADDR
   };
 

Index: dbus-transport-protected.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-protected.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- dbus-transport-protected.h	26 Nov 2004 01:53:13 -0000	1.15
+++ dbus-transport-protected.h	26 Feb 2005 06:37:46 -0000	1.16
@@ -113,7 +113,7 @@
 
 dbus_bool_t _dbus_transport_init_base     (DBusTransport             *transport,
                                            const DBusTransportVTable *vtable,
-                                           dbus_bool_t                server,
+                                           const DBusString          *server_guid,
                                            const DBusString          *address);
 void        _dbus_transport_finalize_base (DBusTransport             *transport);
 

Index: dbus-transport-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-unix.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- dbus-transport-unix.c	13 Feb 2005 17:16:25 -0000	1.45
+++ dbus-transport-unix.c	26 Feb 2005 06:37:46 -0000	1.46
@@ -1114,13 +1114,13 @@
  * boil down to a full duplex file descriptor.
  *
  * @param fd the file descriptor.
- * @param server #TRUE if this transport is on the server side of a connection
+ * @param server_guid non-#NULL if this transport is on the server side of a connection
  * @param address the transport's address
  * @returns the new transport, or #NULL if no memory.
  */
 DBusTransport*
 _dbus_transport_new_for_fd (int               fd,
-                            dbus_bool_t       server,
+                            const DBusString *server_guid,
                             const DBusString *address)
 {
   DBusTransportUnix *unix_transport;
@@ -1151,7 +1151,7 @@
   
   if (!_dbus_transport_init_base (&unix_transport->base,
                                   &unix_vtable,
-                                  server, address))
+                                  server_guid, address))
     goto failed_4;
   
   unix_transport->fd = fd;

Index: dbus-transport-unix.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-unix.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- dbus-transport-unix.h	9 Sep 2004 10:20:17 -0000	1.9
+++ dbus-transport-unix.h	26 Feb 2005 06:37:46 -0000	1.10
@@ -28,7 +28,7 @@
 DBUS_BEGIN_DECLS
 
 DBusTransport* _dbus_transport_new_for_fd            (int               fd,
-                                                      dbus_bool_t       server,
+                                                      const DBusString *server_guid,
                                                       const DBusString *address);
 DBusTransport* _dbus_transport_new_for_domain_socket (const char       *path,
                                                       dbus_bool_t       abstract,

Index: dbus-transport.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- dbus-transport.c	13 Feb 2005 17:16:25 -0000	1.44
+++ dbus-transport.c	26 Feb 2005 06:37:46 -0000	1.45
@@ -75,19 +75,22 @@
 }
 
 /**
- * Initializes the base class members of DBusTransport.
- * Chained up to by subclasses in their constructor.
+ * Initializes the base class members of DBusTransport.  Chained up to
+ * by subclasses in their constructor.  The server GUID is the
+ * globally unique ID for the server creating this connection
+ * and will be #NULL for the client side of a connection. The GUID
+ * is in hex format.
  *
  * @param transport the transport being created.
  * @param vtable the subclass vtable.
- * @param server #TRUE if this transport is on the server side of a connection
+ * @param server_guid non-#NULL if this transport is on the server side of a connection
  * @param address the address of the transport
  * @returns #TRUE on success.
  */
 dbus_bool_t
 _dbus_transport_init_base (DBusTransport             *transport,
                            const DBusTransportVTable *vtable,
-                           dbus_bool_t                server,
+                           const DBusString          *server_guid,
                            const DBusString          *address)
 {
   DBusMessageLoader *loader;
@@ -99,8 +102,8 @@
   if (loader == NULL)
     return FALSE;
   
-  if (server)
-    auth = _dbus_auth_server_new ();
+  if (server_guid)
+    auth = _dbus_auth_server_new (server_guid);
   else
     auth = _dbus_auth_client_new ();
   if (auth == NULL)
@@ -117,7 +120,7 @@
       return FALSE;
     }  
   
-  if (server)
+  if (server_guid)
     {
       _dbus_assert (address == NULL);
       address_copy = NULL;
@@ -142,9 +145,9 @@
   transport->live_messages_size = counter;
   transport->authenticated = FALSE;
   transport->disconnected = FALSE;
-  transport->send_credentials_pending = !server;
-  transport->receive_credentials_pending = server;
-  transport->is_server = server;
+  transport->is_server = (server_guid != NULL);
+  transport->send_credentials_pending = !transport->is_server;
+  transport->receive_credentials_pending = transport->is_server;
   transport->address = address_copy;
   
   transport->unix_user_function = NULL;
@@ -195,33 +198,22 @@
 }
 
 /**
- * Opens a new transport for the given address.  (This opens a
- * client-side-of-the-connection transport.)
- *
- * @todo error messages on bad address could really be better.
- * DBusResultCode is a bit limiting here.
+ * Try to open a new transport for the given address entry.  (This
+ * opens a client-side-of-the-connection transport.)
  * 
- * @param address the address.
+ * @param entry the address entry
  * @param error location to store reason for failure.
  * @returns new transport of #NULL on failure.
  */
 DBusTransport*
-_dbus_transport_open (const char     *address,
-                      DBusError      *error)
+_dbus_transport_open (DBusAddressEntry *entry,
+                      DBusError        *error)
 {
   DBusTransport *transport;
-  DBusAddressEntry **entries;
-  DBusError tmp_error;
-  DBusError first_error;
-  int len, i;
   const char *address_problem_type;
   const char *address_problem_field;
   const char *address_problem_other;
-
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-  
-  if (!dbus_parse_address (address, &entries, &len, error))
-    return NULL;
+  const char *method;     
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   
@@ -229,125 +221,96 @@
   address_problem_type = NULL;
   address_problem_field = NULL;
   address_problem_other = NULL;
-
-  dbus_error_init (&tmp_error);
-  dbus_error_init (&first_error);
-  for (i = 0; i < len; i++)
-    {
-      const char *method;
-
-      method = dbus_address_entry_get_method (entries[i]);
+  
+  method = dbus_address_entry_get_method (entry);
+  _dbus_assert (method != NULL);
       
-      if (strcmp (method, "unix") == 0)
-	{
-	  const char *path = dbus_address_entry_get_value (entries[i], "path");
-          const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir");
-          const char *abstract = dbus_address_entry_get_value (entries[i], "abstract");
+  if (strcmp (method, "unix") == 0)
+    {
+      const char *path = dbus_address_entry_get_value (entry, "path");
+      const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
+      const char *abstract = dbus_address_entry_get_value (entry, "abstract");
           
-	  if (tmpdir != NULL)
-            {
-              address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on";
-              goto bad_address;
-            }
+      if (tmpdir != NULL)
+        {
+          address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on";
+          goto bad_address;
+        }
           
-	  if (path == NULL && abstract == NULL)
-            {
-              address_problem_type = "unix";
-              address_problem_field = "path or abstract";  
-              goto bad_address;
-            }
+      if (path == NULL && abstract == NULL)
+        {
+          address_problem_type = "unix";
+          address_problem_field = "path or abstract";  
+          goto bad_address;
+        }
 
-	  if (path != NULL && abstract != NULL)
-            {
-              address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address";
-              goto bad_address;
-            }
+      if (path != NULL && abstract != NULL)
+        {
+          address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address";
+          goto bad_address;
+        }
 
-          if (path)
-            transport = _dbus_transport_new_for_domain_socket (path, FALSE,
-                                                               &tmp_error);
-          else
-            transport = _dbus_transport_new_for_domain_socket (abstract, TRUE,
-                                                               &tmp_error);
-	}
-      else if (strcmp (method, "tcp") == 0)
-	{
-	  const char *host = dbus_address_entry_get_value (entries[i], "host");
-          const char *port = dbus_address_entry_get_value (entries[i], "port");
-          DBusString  str;
-          long lport;
-          dbus_bool_t sresult;
+      if (path)
+        transport = _dbus_transport_new_for_domain_socket (path, FALSE,
+                                                           error);
+      else
+        transport = _dbus_transport_new_for_domain_socket (abstract, TRUE,
+                                                           error);
+    }
+  else if (strcmp (method, "tcp") == 0)
+    {
+      const char *host = dbus_address_entry_get_value (entry, "host");
+      const char *port = dbus_address_entry_get_value (entry, "port");
+      DBusString  str;
+      long lport;
+      dbus_bool_t sresult;
           
-          if (port == NULL)
-            {
-              address_problem_type = "tcp";
-              address_problem_field = "port";
-              goto bad_address;
-            }
+      if (port == NULL)
+        {
+          address_problem_type = "tcp";
+          address_problem_field = "port";
+          goto bad_address;
+        }
 
-          _dbus_string_init_const (&str, port);
-          sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
-          _dbus_string_free (&str);
+      _dbus_string_init_const (&str, port);
+      sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
+      _dbus_string_free (&str);
           
-          if (sresult == FALSE || lport <= 0 || lport > 65535)
-            {
-              address_problem_other = "Port is not an integer between 0 and 65535";
-              goto bad_address;
-            }
+      if (sresult == FALSE || lport <= 0 || lport > 65535)
+        {
+          address_problem_other = "Port is not an integer between 0 and 65535";
+          goto bad_address;
+        }
           
-	  transport = _dbus_transport_new_for_tcp_socket (host, lport, &tmp_error);
-	}
+      transport = _dbus_transport_new_for_tcp_socket (host, lport, error);
+    }
 #ifdef DBUS_BUILD_TESTS
-      else if (strcmp (method, "debug-pipe") == 0)
-	{
-	  const char *name = dbus_address_entry_get_value (entries[i], "name");
+  else if (strcmp (method, "debug-pipe") == 0)
+    {
+      const char *name = dbus_address_entry_get_value (entry, "name");
 
-          if (name == NULL)
-            {
-              address_problem_type = "debug-pipe";
-              address_problem_field = "name";
-              goto bad_address;
-            }
-          
-	  transport = _dbus_transport_debug_pipe_new (name, &tmp_error);
-	}
-#endif
-      else
+      if (name == NULL)
         {
-          address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
+          address_problem_type = "debug-pipe";
+          address_problem_field = "name";
           goto bad_address;
         }
-
-      if (transport)
-	break;
-
-      _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
-      
-      if (i == 0)
-        dbus_move_error (&tmp_error, &first_error);
-      else
-        dbus_error_free (&tmp_error);
-    }
-
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
-  
-  if (transport == NULL)
-    {
-      _DBUS_ASSERT_ERROR_IS_SET (&first_error);
-      dbus_move_error (&first_error, error);
+          
+      transport = _dbus_transport_debug_pipe_new (name, error);
     }
+#endif
   else
     {
-      dbus_error_free (&first_error);
+      address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
+      goto bad_address;
     }
+
+  if (transport == NULL)
+    _DBUS_ASSERT_ERROR_IS_SET (error);
   
-  dbus_address_entries_free (entries);
   return transport;
-
+  
  bad_address:
-  dbus_address_entries_free (entries);
-
   if (address_problem_type != NULL)
     dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                     "Address of type %s was missing argument %s",

Index: dbus-transport.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- dbus-transport.h	26 Nov 2004 01:53:13 -0000	1.19
+++ dbus-transport.h	26 Feb 2005 06:37:46 -0000	1.20
@@ -26,12 +26,13 @@
 #include <dbus/dbus-internals.h>
 #include <dbus/dbus-connection.h>
 #include <dbus/dbus-protocol.h>
+#include <dbus/dbus-address.h>
 
 DBUS_BEGIN_DECLS
 
 typedef struct DBusTransport DBusTransport;
 
-DBusTransport*     _dbus_transport_open                   (const char                 *address,
+DBusTransport*     _dbus_transport_open                   (DBusAddressEntry           *entry,
                                                            DBusError                  *error);
 DBusTransport*     _dbus_transport_ref                    (DBusTransport              *transport);
 void               _dbus_transport_unref                  (DBusTransport              *transport);



More information about the dbus-commit mailing list