[lib-fix] moved dbus_connection_get_unix_user from daemon to library
[platform/upstream/dbus.git] / dbus / dbus-connection.c
index cb1da8c..2c62436 100644 (file)
@@ -2,6 +2,7 @@
 /* dbus-connection.c DBusConnection object
  *
  * Copyright (C) 2002-2006  Red Hat Inc.
+ * Copyright (C) 2013  Samsung Electronics
  *
  * Licensed under the Academic Free License version 2.1
  * 
 #include "dbus-threads-internal.h"
 #include "dbus-bus.h"
 #include "dbus-marshal-basic.h"
+#ifdef ENABLE_KDBUS_TRANSPORT
+#include "dbus-transport-kdbus.h"
+#include "kdbus-common.h"
+#include <stdlib.h>
+#endif
 
 #ifdef DBUS_DISABLE_CHECKS
 #define TOOK_LOCK_CHECK(connection)
 
 #define CONNECTION_LOCK(connection)   do {                                      \
     if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); }   \
-    _dbus_mutex_lock ((connection)->mutex);                                      \
+    _dbus_rmutex_lock ((connection)->mutex);                                    \
     TOOK_LOCK_CHECK (connection);                                               \
   } while (0)
 
 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
 
 #define SLOTS_LOCK(connection) do {                     \
-    _dbus_mutex_lock ((connection)->slot_mutex);        \
+    _dbus_rmutex_lock ((connection)->slot_mutex);       \
   } while (0)
 
 #define SLOTS_UNLOCK(connection) do {                   \
-    _dbus_mutex_unlock ((connection)->slot_mutex);      \
+    _dbus_rmutex_unlock ((connection)->slot_mutex);     \
   } while (0)
 
 #define DISPATCH_STATUS_NAME(s)                                            \
  * @{
  */
 
+static void
+_dbus_connection_trace_ref (DBusConnection *connection,
+    int old_refcount,
+    int new_refcount,
+    const char *why)
+{
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+  static int enabled = -1;
+
+  _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
+      why, "DBUS_CONNECTION_TRACE", &enabled);
+#endif
+}
+
 /**
  * Internal struct representing a message filter function 
  */
@@ -243,11 +263,11 @@ struct DBusConnection
 {
   DBusAtomic refcount; /**< Reference count. */
 
-  DBusMutex *mutex; /**< Lock on the entire DBusConnection */
+  DBusRMutex *mutex; /**< Lock on the entire DBusConnection */
 
-  DBusMutex *dispatch_mutex;     /**< Protects dispatch_acquired */
+  DBusCMutex *dispatch_mutex;     /**< Protects dispatch_acquired */
   DBusCondVar *dispatch_cond;    /**< Notify when dispatch_acquired is available */
-  DBusMutex *io_path_mutex;      /**< Protects io_path_acquired */
+  DBusCMutex *io_path_mutex;      /**< Protects io_path_acquired */
   DBusCondVar *io_path_cond;     /**< Notify when io_path_acquired is available */
   
   DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */
@@ -269,7 +289,7 @@ struct DBusConnection
   
   DBusList *filter_list;        /**< List of filters. */
 
-  DBusMutex *slot_mutex;        /**< Lock on slot_list so overall connection lock need not be taken */
+  DBusRMutex *slot_mutex;        /**< Lock on slot_list so overall connection lock need not be taken */
   DBusDataSlotList slot_list;   /**< Data stored by allocated integer ID */
 
   DBusHashTable *pending_replies;  /**< Hash of message serials to #DBusPendingCall. */  
@@ -315,8 +335,8 @@ struct DBusConnection
 #ifndef DBUS_DISABLE_CHECKS
   unsigned int have_connection_lock : 1; /**< Used to check locking */
 #endif
-  
-#ifndef DBUS_DISABLE_CHECKS
+
+#if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
   int generation; /**< _dbus_current_generation that should correspond to this connection */
 #endif 
 };
@@ -398,7 +418,7 @@ _dbus_connection_unlock (DBusConnection *connection)
   connection->expired_messages = NULL;
 
   RELEASING_LOCK_CHECK (connection);
-  _dbus_mutex_unlock (connection->mutex);
+  _dbus_rmutex_unlock (connection->mutex);
 
   for (iter = _dbus_list_pop_first_link (&expired_messages);
       iter != NULL;
@@ -425,33 +445,7 @@ _dbus_connection_wakeup_mainloop (DBusConnection *connection)
     (*connection->wakeup_main_function) (connection->wakeup_main_data);
 }
 
-#ifdef DBUS_BUILD_TESTS
-/* For now this function isn't used */
-/**
- * Adds a message to the incoming message queue, returning #FALSE
- * if there's insufficient memory to queue the message.
- * Does not take over refcount of the message.
- *
- * @param connection the connection.
- * @param message the message to queue.
- * @returns #TRUE on success.
- */
-dbus_bool_t
-_dbus_connection_queue_received_message (DBusConnection *connection,
-                                         DBusMessage    *message)
-{
-  DBusList *link;
-
-  link = _dbus_list_alloc_link (message);
-  if (link == NULL)
-    return FALSE;
-
-  dbus_message_ref (message);
-  _dbus_connection_queue_received_message_link (connection, link);
-
-  return TRUE;
-}
-
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
 /**
  * Gets the locks so we can examine them
  *
@@ -472,9 +466,9 @@ _dbus_connection_test_get_locks (DBusConnection *connection,
                                  DBusCondVar   **dispatch_cond_loc,
                                  DBusCondVar   **io_path_cond_loc)
 {
-  *mutex_loc = connection->mutex;
-  *dispatch_mutex_loc = connection->dispatch_mutex;
-  *io_path_mutex_loc = connection->io_path_mutex; 
+  *mutex_loc = (DBusMutex *) connection->mutex;
+  *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
+  *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
   *dispatch_cond_loc = connection->dispatch_cond;
   *io_path_cond_loc = connection->io_path_cond;
 }
@@ -495,9 +489,9 @@ _dbus_connection_queue_received_message_link (DBusConnection  *connection,
   DBusPendingCall *pending;
   dbus_uint32_t reply_serial;
   DBusMessage *message;
-  
-  _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
-  
+
+  _dbus_assert (_dbus_transport_peek_is_authenticated (connection->transport));
+
   _dbus_list_append_link (&connection->incoming_messages,
                           link);
   message = link->data;
@@ -539,7 +533,11 @@ _dbus_connection_queue_received_message_link (DBusConnection  *connection,
                  dbus_message_get_signature (message),
                  dbus_message_get_reply_serial (message),
                  connection,
-                 connection->n_incoming);}
+                 connection->n_incoming);
+
+  _dbus_message_trace_ref (message, -1, -1,
+      "_dbus_conection_queue_received_message_link");
+}
 
 /**
  * Adds a link + message to the incoming message queue.
@@ -560,7 +558,10 @@ _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
   connection->n_incoming += 1;
 
   _dbus_connection_wakeup_mainloop (connection);
-  
+
+  _dbus_message_trace_ref (link->data, -1, -1,
+      "_dbus_connection_queue_synthesized_message_link");
+
   _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
                  link->data, connection, connection->n_incoming);
 }
@@ -1077,7 +1078,7 @@ _dbus_connection_acquire_io_path (DBusConnection *connection,
   CONNECTION_UNLOCK (connection);
   
   _dbus_verbose ("locking io_path_mutex\n");
-  _dbus_mutex_lock (connection->io_path_mutex);
+  _dbus_cmutex_lock (connection->io_path_mutex);
 
   _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
                  connection->io_path_acquired, timeout_milliseconds);
@@ -1126,7 +1127,7 @@ _dbus_connection_acquire_io_path (DBusConnection *connection,
                  connection->io_path_acquired, we_acquired);
 
   _dbus_verbose ("unlocking io_path_mutex\n");
-  _dbus_mutex_unlock (connection->io_path_mutex);
+  _dbus_cmutex_unlock (connection->io_path_mutex);
 
   CONNECTION_LOCK (connection);
   
@@ -1150,7 +1151,7 @@ _dbus_connection_release_io_path (DBusConnection *connection)
   HAVE_LOCK_CHECK (connection);
   
   _dbus_verbose ("locking io_path_mutex\n");
-  _dbus_mutex_lock (connection->io_path_mutex);
+  _dbus_cmutex_lock (connection->io_path_mutex);
   
   _dbus_assert (connection->io_path_acquired);
 
@@ -1161,7 +1162,7 @@ _dbus_connection_release_io_path (DBusConnection *connection)
   _dbus_condvar_wake_one (connection->io_path_cond);
 
   _dbus_verbose ("unlocking io_path_mutex\n");
-  _dbus_mutex_unlock (connection->io_path_mutex);
+  _dbus_cmutex_unlock (connection->io_path_mutex);
 }
 
 /**
@@ -1249,9 +1250,14 @@ _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
  *
  * @param transport the transport.
  * @returns the new connection, or #NULL on failure.
- */
+*/
+#ifdef ENABLE_KDBUS_TRANSPORT
+static DBusConnection*
+_dbus_connection_new_for_transport_internal (DBusTransport *transport, dbus_bool_t exists)
+#else
 DBusConnection*
 _dbus_connection_new_for_transport (DBusTransport *transport)
+#endif
 {
   DBusConnection *connection;
   DBusWatchList *watch_list;
@@ -1281,7 +1287,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
 
   pending_replies =
     _dbus_hash_table_new (DBUS_HASH_INT,
-                         NULL,
+              NULL,
                           (DBusFreeFunction)free_pending_call_on_hash_removal);
   if (pending_replies == NULL)
     goto error;
@@ -1290,15 +1296,15 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
   if (connection == NULL)
     goto error;
 
-  _dbus_mutex_new_at_location (&connection->mutex);
+  _dbus_rmutex_new_at_location (&connection->mutex);
   if (connection->mutex == NULL)
     goto error;
 
-  _dbus_mutex_new_at_location (&connection->io_path_mutex);
+  _dbus_cmutex_new_at_location (&connection->io_path_mutex);
   if (connection->io_path_mutex == NULL)
     goto error;
 
-  _dbus_mutex_new_at_location (&connection->dispatch_mutex);
+  _dbus_cmutex_new_at_location (&connection->dispatch_mutex);
   if (connection->dispatch_mutex == NULL)
     goto error;
   
@@ -1310,7 +1316,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
   if (connection->io_path_cond == NULL)
     goto error;
 
-  _dbus_mutex_new_at_location (&connection->slot_mutex);
+  _dbus_rmutex_new_at_location (&connection->slot_mutex);
   if (connection->slot_mutex == NULL)
     goto error;
 
@@ -1351,8 +1357,8 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
   connection->route_peer_messages = FALSE;
   connection->disconnected_message_arrived = FALSE;
   connection->disconnected_message_processed = FALSE;
-  
-#ifndef DBUS_DISABLE_CHECKS
+
+#if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
   connection->generation = _dbus_current_generation;
 #endif
   
@@ -1362,19 +1368,25 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
 
   connection->disconnect_message_link = disconnect_link;
 
-  CONNECTION_LOCK (connection);
-  
-  if (!_dbus_transport_set_connection (transport, connection))
-    {
-      CONNECTION_UNLOCK (connection);
+#ifdef ENABLE_KDBUS_TRANSPORT
+  if(!exists)
+#endif
+  {
+      CONNECTION_LOCK (connection);
 
-      goto error;
-    }
+      if (!_dbus_transport_set_connection (transport, connection))
+        {
+          CONNECTION_UNLOCK (connection);
 
-  _dbus_transport_ref (transport);
+          goto error;
+        }
 
-  CONNECTION_UNLOCK (connection);
-  
+      _dbus_transport_ref (transport);
+
+      CONNECTION_UNLOCK (connection);
+  }
+
+  _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
   return connection;
   
  error:
@@ -1388,10 +1400,10 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
     {
       _dbus_condvar_free_at_location (&connection->io_path_cond);
       _dbus_condvar_free_at_location (&connection->dispatch_cond);
-      _dbus_mutex_free_at_location (&connection->mutex);
-      _dbus_mutex_free_at_location (&connection->io_path_mutex);
-      _dbus_mutex_free_at_location (&connection->dispatch_mutex);
-      _dbus_mutex_free_at_location (&connection->slot_mutex);
+      _dbus_rmutex_free_at_location (&connection->mutex);
+      _dbus_cmutex_free_at_location (&connection->io_path_mutex);
+      _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
+      _dbus_rmutex_free_at_location (&connection->slot_mutex);
       dbus_free (connection);
     }
   if (pending_replies)
@@ -1412,6 +1424,29 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
   return NULL;
 }
 
+#ifdef ENABLE_KDBUS_TRANSPORT
+/**
+ * Creates a new connection for the given transport.  A transport
+ * represents a message stream that uses some concrete mechanism, such
+ * as UNIX domain sockets. May return #NULL if insufficient
+ * memory exists to create the connection.
+ *
+ * @param transport the transport.
+ * @returns the new connection, or #NULL on failure.
+ */
+DBusConnection*
+_dbus_connection_new_for_transport (DBusTransport *transport)
+{
+    return _dbus_connection_new_for_transport_internal(transport, FALSE);
+}
+
+DBusConnection*
+_dbus_connection_new_for_used_transport (DBusTransport *transport)
+{
+    return _dbus_connection_new_for_transport_internal(transport, TRUE);
+}
+#endif
+
 /**
  * Increments the reference count of a DBusConnection.
  * Requires that the caller already holds the connection lock.
@@ -1421,13 +1456,17 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
  */
 DBusConnection *
 _dbus_connection_ref_unlocked (DBusConnection *connection)
-{  
+{
+  dbus_int32_t old_refcount;
+
   _dbus_assert (connection != NULL);
   _dbus_assert (connection->generation == _dbus_current_generation);
 
   HAVE_LOCK_CHECK (connection);
 
-  _dbus_atomic_inc (&connection->refcount);
+  old_refcount = _dbus_atomic_inc (&connection->refcount);
+  _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
+      "ref_unlocked");
 
   return connection;
 }
@@ -1441,15 +1480,18 @@ _dbus_connection_ref_unlocked (DBusConnection *connection)
 void
 _dbus_connection_unref_unlocked (DBusConnection *connection)
 {
-  dbus_bool_t last_unref;
+  dbus_int32_t old_refcount;
 
   HAVE_LOCK_CHECK (connection);
-  
+
   _dbus_assert (connection != NULL);
 
-  last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
+  old_refcount = _dbus_atomic_dec (&connection->refcount);
+
+  _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
+      "unref_unlocked");
 
-  if (last_unref)
+  if (old_refcount == 1)
     _dbus_connection_last_unref (connection);
 }
 
@@ -1521,7 +1563,7 @@ _dbus_connection_handle_watch (DBusWatch                   *watch,
   return retval;
 }
 
-_DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
+/* Protected by _DBUS_LOCK (shared_connections) */
 static DBusHashTable *shared_connections = NULL;
 static DBusList *shared_connections_no_guid = NULL;
 
@@ -1545,9 +1587,14 @@ static void
 shared_connections_shutdown (void *data)
 {
   int n_entries;
-  
-  _DBUS_LOCK (shared_connections);
-  
+
+  if (!_DBUS_LOCK (shared_connections))
+    {
+      /* We'd have initialized locks before adding anything, so there
+       * can't be anything there. */
+      return;
+    }
+
   /* This is a little bit unpleasant... better ideas? */
   while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
     {
@@ -1561,7 +1608,8 @@ shared_connections_shutdown (void *data)
 
       _DBUS_UNLOCK (shared_connections);
       close_connection_on_shutdown (connection);
-      _DBUS_LOCK (shared_connections);
+      if (!_DBUS_LOCK (shared_connections))
+        _dbus_assert_not_reached ("global locks were already initialized");
 
       /* The connection should now be dead and not in our hash ... */
       _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
@@ -1580,7 +1628,8 @@ shared_connections_shutdown (void *data)
         {
           _DBUS_UNLOCK (shared_connections);
           close_connection_on_shutdown (connection);
-          _DBUS_LOCK (shared_connections);
+          if (!_DBUS_LOCK (shared_connections))
+            _dbus_assert_not_reached ("global locks were already initialized");
           connection = _dbus_list_pop_first (&shared_connections_no_guid);
         }
     }
@@ -1597,8 +1646,13 @@ connection_lookup_shared (DBusAddressEntry  *entry,
   _dbus_verbose ("checking for existing connection\n");
   
   *result = NULL;
-  
-  _DBUS_LOCK (shared_connections);
+
+  if (!_DBUS_LOCK (shared_connections))
+    {
+      /* If it was shared, we'd have initialized global locks when we put
+       * it in shared_connections. */
+      return FALSE;
+    }
 
   if (shared_connections == NULL)
     {
@@ -1696,7 +1750,8 @@ connection_record_shared_unlocked (DBusConnection *connection,
 
   if (guid == NULL)
     {
-      _DBUS_LOCK (shared_connections);
+      if (!_DBUS_LOCK (shared_connections))
+        return FALSE;
 
       if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
         {
@@ -1723,8 +1778,14 @@ connection_record_shared_unlocked (DBusConnection *connection,
       dbus_free (guid_key);
       return FALSE;
     }
-  
-  _DBUS_LOCK (shared_connections);
+
+  if (!_DBUS_LOCK (shared_connections))
+    {
+      dbus_free (guid_in_connection);
+      dbus_free (guid_key);
+      return FALSE;
+    }
+
   _dbus_assert (shared_connections != NULL);
   
   if (!_dbus_hash_table_insert_string (shared_connections,
@@ -1755,9 +1816,14 @@ connection_forget_shared_unlocked (DBusConnection *connection)
 
   if (!connection->shareable)
     return;
-  
-  _DBUS_LOCK (shared_connections);
-      
+
+  if (!_DBUS_LOCK (shared_connections))
+    {
+      /* If it was shared, we'd have initialized global locks when we put
+       * it in the table; so it can't be there. */
+      return;
+    }
+
   if (connection->server_guid != NULL)
     {
       _dbus_verbose ("dropping connection to %s out of the shared table\n",
@@ -1809,6 +1875,7 @@ connection_try_from_address_entry (DBusAddressEntry *entry,
 #ifndef DBUS_DISABLE_CHECKS
   _dbus_assert (!connection->have_connection_lock);
 #endif
+
   return connection;
 }
 
@@ -2140,7 +2207,7 @@ _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
  * relatively long time for memory, if they were only willing to block
  * briefly then we retry for memory at a rapid rate.
  *
- * @timeout_milliseconds the timeout requested for blocking
+ * @param timeout_milliseconds the timeout requested for blocking
  */
 static void
 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
@@ -2155,7 +2222,7 @@ _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
     _dbus_sleep_milliseconds (1000);
 }
 
-static DBusMessage *
+DBusMessage *
 generate_local_error_message (dbus_uint32_t serial, 
                               char *error_name, 
                               char *error_msg)
@@ -2378,7 +2445,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
    * below
    */
   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
-  _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
+  _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
   if (timeout)
     {
       timeout_milliseconds = dbus_timeout_get_interval (timeout);
@@ -2435,7 +2502,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
         return;
     }
   
-  _dbus_get_current_time (&tv_sec, &tv_usec);
+  _dbus_get_monotonic_time (&tv_sec, &tv_usec);
   elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
          (tv_usec - start_tv_usec) / 1000;
   
@@ -2626,10 +2693,13 @@ dbus_connection_open_private (const char     *address,
 DBusConnection *
 dbus_connection_ref (DBusConnection *connection)
 {
+  dbus_int32_t old_refcount;
+
   _dbus_return_val_if_fail (connection != NULL, NULL);
   _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
-
-  _dbus_atomic_inc (&connection->refcount);
+  old_refcount = _dbus_atomic_inc (&connection->refcount);
+  _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
+      "ref");
 
   return connection;
 }
@@ -2645,12 +2715,13 @@ free_outgoing_message (void *element,
   dbus_message_unref (message);
 }
 
-/* This is run without the mutex held, but after the last reference
- * to the connection has been dropped we should have no thread-related
- * problems
- */
+#ifdef ENABLE_KDBUS_TRANSPORT
+static void
+_dbus_connection_last_unref_internal (DBusConnection *connection, dbus_bool_t unref_transport)
+#else
 static void
 _dbus_connection_last_unref (DBusConnection *connection)
+#endif
 {
   DBusList *link;
 
@@ -2661,7 +2732,10 @@ _dbus_connection_last_unref (DBusConnection *connection)
   /* You have to disconnect the connection before unref:ing it. Otherwise
    * you won't get the disconnected message.
    */
-  _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
+#ifdef ENABLE_KDBUS_TRANSPORT
+  if(unref_transport)
+#endif
+      _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... */
@@ -2670,6 +2744,7 @@ _dbus_connection_last_unref (DBusConnection *connection)
   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
   dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
   dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
+  dbus_connection_set_windows_user_function (connection, NULL, NULL, NULL);
   
   _dbus_watch_list_free (connection->watches);
   connection->watches = NULL;
@@ -2704,17 +2779,20 @@ _dbus_connection_last_unref (DBusConnection *connection)
   
   _dbus_list_foreach (&connection->outgoing_messages,
                       free_outgoing_message,
-                     connection);
+              connection);
   _dbus_list_clear (&connection->outgoing_messages);
   
   _dbus_list_foreach (&connection->incoming_messages,
-                     (DBusForeachFunction) dbus_message_unref,
-                     NULL);
+              (DBusForeachFunction) dbus_message_unref,
+              NULL);
   _dbus_list_clear (&connection->incoming_messages);
 
   _dbus_counter_unref (connection->outgoing_counter);
 
-  _dbus_transport_unref (connection->transport);
+#ifdef ENABLE_KDBUS_TRANSPORT
+  if(unref_transport)
+#endif
+      _dbus_transport_unref (connection->transport);
 
   if (connection->disconnect_message_link)
     {
@@ -2726,16 +2804,28 @@ _dbus_connection_last_unref (DBusConnection *connection)
   _dbus_condvar_free_at_location (&connection->dispatch_cond);
   _dbus_condvar_free_at_location (&connection->io_path_cond);
 
-  _dbus_mutex_free_at_location (&connection->io_path_mutex);
-  _dbus_mutex_free_at_location (&connection->dispatch_mutex);
+  _dbus_cmutex_free_at_location (&connection->io_path_mutex);
+  _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
 
-  _dbus_mutex_free_at_location (&connection->slot_mutex);
+  _dbus_rmutex_free_at_location (&connection->slot_mutex);
 
-  _dbus_mutex_free_at_location (&connection->mutex);
+  _dbus_rmutex_free_at_location (&connection->mutex);
   
   dbus_free (connection);
 }
 
+#ifdef ENABLE_KDBUS_TRANSPORT
+/* This is run without the mutex held, but after the last reference
+ * to the connection has been dropped we should have no thread-related
+ * problems
+ */
+static void
+_dbus_connection_last_unref (DBusConnection *connection)
+{
+    _dbus_connection_last_unref_internal(connection, TRUE);
+}
+#endif
+
 /**
  * Decrements the reference count of a DBusConnection, and finalizes
  * it if the count reaches zero.
@@ -2758,14 +2848,17 @@ _dbus_connection_last_unref (DBusConnection *connection)
 void
 dbus_connection_unref (DBusConnection *connection)
 {
-  dbus_bool_t last_unref;
+  dbus_int32_t old_refcount;
 
   _dbus_return_if_fail (connection != NULL);
   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
 
-  last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
+  old_refcount = _dbus_atomic_dec (&connection->refcount);
+
+  _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
+      "unref");
 
-  if (last_unref)
+  if (old_refcount == 1)
     {
 #ifndef DBUS_DISABLE_CHECKS
       if (_dbus_transport_get_is_connected (connection->transport))
@@ -2781,6 +2874,24 @@ dbus_connection_unref (DBusConnection *connection)
     }
 }
 
+#ifdef ENABLE_KDBUS_TRANSPORT
+void
+dbus_connection_unref_phantom (DBusConnection *connection)
+{
+  dbus_int32_t old_refcount;
+
+  _dbus_return_if_fail (connection != NULL);
+  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
+
+  old_refcount = _dbus_atomic_dec (&connection->refcount);
+
+  _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, "unref");
+
+  if (old_refcount == 1)
+      _dbus_connection_last_unref_internal(connection, FALSE);
+}
+#endif
+
 /*
  * Note that the transport can disconnect itself (other end drops us)
  * and in that case this function never runs. So this function must
@@ -2936,14 +3047,34 @@ dbus_connection_get_is_authenticated (DBusConnection *connection)
   dbus_bool_t res;
 
   _dbus_return_val_if_fail (connection != NULL, FALSE);
-  
+
   CONNECTION_LOCK (connection);
-  res = _dbus_transport_get_is_authenticated (connection->transport);
+  res = _dbus_transport_try_to_authenticate (connection->transport);
   CONNECTION_UNLOCK (connection);
   
   return res;
 }
 
+#ifdef ENABLE_KDBUS_TRANSPORT
+/**
+ * Sets authenticated status for connection. Needed for kdbus, where authentication is
+ * made in different manner.
+ * LOCK commented out because called with lock already set
+ * @param connection the connection
+ */
+dbus_bool_t
+dbus_connection_set_is_authenticated (DBusConnection *connection)
+{
+  _dbus_return_val_if_fail (connection != NULL, FALSE);
+
+//  CONNECTION_LOCK (connection);
+  connection->transport->authenticated = TRUE;
+//  CONNECTION_UNLOCK (connection);
+
+  return TRUE;
+}
+#endif
+
 /**
  * Gets whether the connection is not authenticated as a specific
  * user.  If the connection is not authenticated, this function
@@ -3821,6 +3952,8 @@ dbus_connection_borrow_message (DBusConnection *connection)
 
   CONNECTION_UNLOCK (connection);
 
+  _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message");
+
   /* We don't update dispatch status until it's returned or stolen */
   
   return message;
@@ -3855,6 +3988,8 @@ dbus_connection_return_message (DBusConnection *connection,
 
   status = _dbus_connection_get_dispatch_status_unlocked (connection);
   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
+
+  _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message");
 }
 
 /**
@@ -3884,7 +4019,8 @@ dbus_connection_steal_borrowed_message (DBusConnection *connection,
 
   pop_message = _dbus_list_pop_first (&connection->incoming_messages);
   _dbus_assert (message == pop_message);
-  
+  (void) pop_message; /* unused unless asserting */
+
   connection->n_incoming -= 1;
  
   _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
@@ -3896,6 +4032,8 @@ dbus_connection_steal_borrowed_message (DBusConnection *connection,
 
   status = _dbus_connection_get_dispatch_status_unlocked (connection);
   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
+  _dbus_message_trace_ref (message, -1, -1,
+      "dbus_connection_steal_borrowed_message");
 }
 
 /* See dbus_connection_pop_message, but requires the caller to own
@@ -3915,7 +4053,7 @@ _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
       link = _dbus_list_pop_first_link (&connection->incoming_messages);
       connection->n_incoming -= 1;
 
-      _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
+      _dbus_verbose ("Message %p (%s %s %s %s sig:'%s' serial:%u) removed from incoming queue %p, %d incoming\n",
                      link->data,
                      dbus_message_type_to_string (dbus_message_get_type (link->data)),
                      dbus_message_get_path (link->data) ?
@@ -3928,8 +4066,12 @@ _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
                      dbus_message_get_member (link->data) :
                      "no member",
                      dbus_message_get_signature (link->data),
+                     dbus_message_get_serial (link->data),
                      connection, connection->n_incoming);
 
+      _dbus_message_trace_ref (link->data, -1, -1,
+          "_dbus_connection_pop_message_link_unlocked");
+
       check_disconnected_message_arrived_unlocked (connection, link->data);
       
       return link;
@@ -3991,6 +4133,9 @@ _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
                  "no member",
                  dbus_message_get_signature (message_link->data),
                  connection, connection->n_incoming);
+
+  _dbus_message_trace_ref (message_link->data, -1, -1,
+      "_dbus_connection_putback_message_link_unlocked");
 }
 
 /**
@@ -4059,7 +4204,7 @@ _dbus_connection_acquire_dispatch (DBusConnection *connection)
   CONNECTION_UNLOCK (connection);
   
   _dbus_verbose ("locking dispatch_mutex\n");
-  _dbus_mutex_lock (connection->dispatch_mutex);
+  _dbus_cmutex_lock (connection->dispatch_mutex);
 
   while (connection->dispatch_acquired)
     {
@@ -4073,7 +4218,7 @@ _dbus_connection_acquire_dispatch (DBusConnection *connection)
   connection->dispatch_acquired = TRUE;
 
   _dbus_verbose ("unlocking dispatch_mutex\n");
-  _dbus_mutex_unlock (connection->dispatch_mutex);
+  _dbus_cmutex_unlock (connection->dispatch_mutex);
   
   CONNECTION_LOCK (connection);
   _dbus_connection_unref_unlocked (connection);
@@ -4092,7 +4237,7 @@ _dbus_connection_release_dispatch (DBusConnection *connection)
   HAVE_LOCK_CHECK (connection);
   
   _dbus_verbose ("locking dispatch_mutex\n");
-  _dbus_mutex_lock (connection->dispatch_mutex);
+  _dbus_cmutex_lock (connection->dispatch_mutex);
   
   _dbus_assert (connection->dispatch_acquired);
 
@@ -4100,7 +4245,7 @@ _dbus_connection_release_dispatch (DBusConnection *connection)
   _dbus_condvar_wake_one (connection->dispatch_cond);
 
   _dbus_verbose ("unlocking dispatch_mutex\n");
-  _dbus_mutex_unlock (connection->dispatch_mutex);
+  _dbus_cmutex_unlock (connection->dispatch_mutex);
 }
 
 static void
@@ -4176,7 +4321,7 @@ static DBusDispatchStatus
 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
 {
   HAVE_LOCK_CHECK (connection);
-  
+
   if (connection->n_incoming > 0)
     return DBUS_DISPATCH_DATA_REMAINS;
   else if (!_dbus_transport_queue_messages (connection->transport))
@@ -4185,7 +4330,7 @@ _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
     {
       DBusDispatchStatus status;
       dbus_bool_t is_connected;
-      
+
       status = _dbus_transport_get_dispatch_status (connection->transport);
       is_connected = _dbus_transport_get_is_connected (connection->transport);
 
@@ -5088,7 +5233,6 @@ dbus_connection_get_socket(DBusConnection              *connection,
   return retval;
 }
 
-
 /**
  * Gets the UNIX user ID of the connection if known.  Returns #TRUE if
  * the uid is filled in.  Always returns #FALSE on non-UNIX platforms
@@ -5119,19 +5263,29 @@ dbus_connection_get_unix_user (DBusConnection *connection,
 
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (uid != NULL, FALSE);
-  
+
   CONNECTION_LOCK (connection);
 
-  if (!_dbus_transport_get_is_authenticated (connection->transport))
-    result = FALSE;
+#ifdef ENABLE_KDBUS_TRANSPORT
+  if (_dbus_connection_get_address (connection) != NULL)
+    {
+      if (!strncmp (_dbus_connection_get_address (connection), "kdbus:", strlen("kdbus:")))
+        result = kdbus_connection_get_unix_user (connection, dbus_bus_get_unique_name (connection), uid, NULL);
+    }
   else
-    result = _dbus_transport_get_unix_user (connection->transport,
-                                            uid);
+#endif
+    {
+      if (!_dbus_transport_try_to_authenticate (connection->transport))
+        result = FALSE;
+      else
+        result = _dbus_transport_get_unix_user (connection->transport,
+                                                uid);
+    }
 
 #ifdef DBUS_WIN
   _dbus_assert (!result);
 #endif
-  
+
   CONNECTION_UNLOCK (connection);
 
   return result;
@@ -5155,14 +5309,24 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
 
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (pid != NULL, FALSE);
-  
+
   CONNECTION_LOCK (connection);
 
-  if (!_dbus_transport_get_is_authenticated (connection->transport))
-    result = FALSE;
+#ifdef ENABLE_KDBUS_TRANSPORT
+  if (_dbus_connection_get_address (connection) != NULL)
+    {
+      if (!strncmp (_dbus_connection_get_address (connection), "kdbus:", strlen("kdbus:")))
+        result = kdbus_connection_get_unix_process_id (connection, dbus_bus_get_unique_name (connection), pid, NULL);
+    }
   else
-    result = _dbus_transport_get_unix_process_id (connection->transport,
-                                                 pid);
+#endif
+    {
+      if (!_dbus_transport_try_to_authenticate (connection->transport))
+        result = FALSE;
+      else
+        result = _dbus_transport_get_unix_process_id (connection->transport,
+                                                      pid);
+    }
 
   CONNECTION_UNLOCK (connection);
 
@@ -5176,7 +5340,8 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
  * connection.
  *
  * @param connection the connection
- * @param data return location for audit data 
+ * @param data return location for audit data
+ * @param data_size return location for length of audit data
  * @returns #TRUE if audit data is filled in with a valid ucred pointer
  */
 dbus_bool_t
@@ -5189,10 +5354,10 @@ dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (data != NULL, FALSE);
   _dbus_return_val_if_fail (data_size != NULL, FALSE);
-  
+
   CONNECTION_LOCK (connection);
 
-  if (!_dbus_transport_get_is_authenticated (connection->transport))
+  if (!_dbus_transport_try_to_authenticate (connection->transport))
     result = FALSE;
   else
     result = _dbus_transport_get_adt_audit_session_data (connection->transport,
@@ -5285,10 +5450,10 @@ dbus_connection_get_windows_user (DBusConnection             *connection,
 
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
-  
+
   CONNECTION_LOCK (connection);
 
-  if (!_dbus_transport_get_is_authenticated (connection->transport))
+  if (!_dbus_transport_try_to_authenticate (connection->transport))
     result = FALSE;
   else
     result = _dbus_transport_get_windows_user (connection->transport,
@@ -5823,8 +5988,8 @@ dbus_connection_list_registered (DBusConnection              *connection,
   return retval;
 }
 
-static DBusDataSlotAllocator slot_allocator;
-_DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
+static DBusDataSlotAllocator slot_allocator =
+  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
 
 /**
  * Allocates an integer ID to be used for storing application-specific
@@ -5844,7 +6009,6 @@ dbus_bool_t
 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
 {
   return _dbus_data_slot_allocator_alloc (&slot_allocator,
-                                          &_DBUS_LOCK_NAME (connection_slots),
                                           slot_p);
 }
 
@@ -5945,7 +6109,8 @@ dbus_connection_get_data (DBusConnection   *connection,
   void *res;
 
   _dbus_return_val_if_fail (connection != NULL, NULL);
-  
+  _dbus_return_val_if_fail (slot >= 0, NULL);
+
   SLOTS_LOCK (connection);
 
   res = _dbus_data_slot_list_get (&slot_allocator,
@@ -6014,7 +6179,7 @@ dbus_connection_get_max_message_size (DBusConnection *connection)
  * result in disconnecting the connection.
  *
  * @param connection a #DBusConnection
- * @param size maximum message unix fds the connection can receive
+ * @param n maximum message unix fds the connection can receive
  */
 void
 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
@@ -6112,7 +6277,7 @@ dbus_connection_get_max_received_size (DBusConnection *connection)
  * The semantics are analogous to those of dbus_connection_set_max_received_size().
  *
  * @param connection the connection
- * @param size the maximum size in bytes of all outstanding messages
+ * @param n the maximum size in bytes of all outstanding messages
  */
 void
 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
@@ -6229,4 +6394,26 @@ dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
   return res;
 }
 
+/**
+ * Returns the address of the transport object of this connection
+ *
+ * @param connection the connection
+ * @returns the address string
+ */
+const char*
+_dbus_connection_get_address (DBusConnection *connection)
+{
+  return _dbus_transport_get_address (connection->transport);
+}
+
+#ifdef ENABLE_KDBUS_TRANSPORT
+DBusTransport*
+dbus_connection_get_transport(DBusConnection *connection)
+{
+       _dbus_return_val_if_fail (connection != NULL, NULL);
+
+       return connection->transport;
+}
+#endif
+
 /** @} */