Added NameList method handling, small improvemnets and cleanups
[platform/upstream/dbus.git] / dbus / dbus-connection.c
index b8f48ad..d6a547e 100644 (file)
@@ -44,6 +44,8 @@
 #include "dbus-threads-internal.h"
 #include "dbus-bus.h"
 #include "dbus-marshal-basic.h"
+#include "dbus-transport-kdbus.h"
+#include <stdlib.h>
 
 #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)                                            \
@@ -264,11 +266,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. */
@@ -290,7 +292,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. */  
@@ -419,7 +421,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;
@@ -467,9 +469,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;
 }
@@ -1079,7 +1081,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);
@@ -1128,7 +1130,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);
   
@@ -1152,7 +1154,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);
 
@@ -1163,7 +1165,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);
 }
 
 /**
@@ -1292,15 +1294,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;
   
@@ -1312,7 +1314,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;
 
@@ -1391,10 +1393,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)
@@ -1531,7 +1533,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;
 
@@ -1555,9 +1557,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)
     {
@@ -1571,7 +1578,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);
@@ -1590,7 +1598,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);
         }
     }
@@ -1607,8 +1616,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)
     {
@@ -1706,7 +1720,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))
         {
@@ -1733,8 +1748,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,
@@ -1765,9 +1786,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",
@@ -1819,6 +1845,7 @@ connection_try_from_address_entry (DBusAddressEntry *entry,
 #ifndef DBUS_DISABLE_CHECKS
   _dbus_assert (!connection->have_connection_lock);
 #endif
+
   return connection;
 }
 
@@ -2032,6 +2059,23 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *con
   _dbus_verbose ("Message %p serial is %u\n",
                  message, dbus_message_get_serial (message));
   
+  if(dbus_transport_is_kdbus(connection))
+  {
+         const char* name;
+         char* sender;
+
+         name = dbus_bus_get_unique_name(connection);
+         sender = malloc (strlen(name) + 4);
+         if(sender)
+         {
+                 strcpy(sender,":1.");
+                 strcpy(&sender[3], name);
+                 _dbus_verbose ("Message sender: %s\n", sender);
+                 dbus_message_set_sender(message, sender);
+                 free((void*)sender);
+         }
+  }
+
   dbus_message_lock (message);
 
   /* Now we need to run an iteration to hopefully just write the messages
@@ -2165,7 +2209,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)
@@ -2388,7 +2432,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);
@@ -2445,7 +2489,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;
   
@@ -2739,12 +2783,12 @@ _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);
 }
@@ -2961,6 +3005,24 @@ dbus_connection_get_is_authenticated (DBusConnection *connection)
 }
 
 /**
+ * Sets authenticated status for connection. Needed for kdbus, where authentication is
+ * made in different manner.
+ *
+ * @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;
+}
+
+/**
  * Gets whether the connection is not authenticated as a specific
  * user.  If the connection is not authenticated, this function
  * returns #TRUE, and if it is authenticated but as an anonymous user,
@@ -4088,7 +4150,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)
     {
@@ -4102,7 +4164,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);
@@ -4121,7 +4183,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);
 
@@ -4129,7 +4191,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
@@ -4205,7 +4267,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))
@@ -4214,7 +4276,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);
 
@@ -5852,8 +5914,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
@@ -5873,7 +5935,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);
 }
 
@@ -5974,7 +6035,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,
@@ -6258,4 +6320,25 @@ 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);
+}
+
+DBusTransport*
+dbus_connection_get_transport(DBusConnection *connection)
+{
+       _dbus_return_val_if_fail (connection != NULL, NULL);
+
+       return connection->transport;
+}
+
+
 /** @} */