X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-connection.c;h=2c624367074e97e55290aea11a69a9970ff6d8a2;hb=c1a77d2c58c78abc606f1cb7918704596ebf2bfe;hp=1417b733723ffbcccff20e9291e571aa48f093e8;hpb=0d7318ccc72b0b984a3a27e71eb5e9a3919ff3bb;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 1417b73..2c62436 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -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 * @@ -44,6 +45,11 @@ #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 +#endif #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(connection) @@ -66,22 +72,18 @@ #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) do { \ - if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n"); } \ - RELEASING_LOCK_CHECK (connection); \ - _dbus_mutex_unlock ((connection)->mutex); \ - } 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) \ @@ -207,6 +209,20 @@ * @{ */ +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 */ @@ -247,15 +263,16 @@ 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. */ DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */ + DBusList *expired_messages; /**< Messages that will be released when we next unlock. */ DBusMessage *message_borrowed; /**< Filled in if the first incoming message has been borrowed; * dispatch_acquired will be set by the borrower @@ -272,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. */ @@ -290,9 +307,6 @@ struct DBusConnection DBusDispatchStatus last_dispatch_status; /**< The last dispatch status we reported to the application. */ - DBusList *link_cache; /**< A cache of linked list links to prevent contention - * 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 */ @@ -321,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 }; @@ -390,7 +404,31 @@ _dbus_connection_lock (DBusConnection *connection) void _dbus_connection_unlock (DBusConnection *connection) { - CONNECTION_UNLOCK (connection); + DBusList *expired_messages; + DBusList *iter; + + if (TRACE_LOCKS) + { + _dbus_verbose ("UNLOCK\n"); + } + + /* If we had messages that expired (fell off the incoming or outgoing + * queues) while we were locked, actually release them now */ + expired_messages = connection->expired_messages; + connection->expired_messages = NULL; + + RELEASING_LOCK_CHECK (connection); + _dbus_rmutex_unlock (connection->mutex); + + for (iter = _dbus_list_pop_first_link (&expired_messages); + iter != NULL; + iter = _dbus_list_pop_first_link (&expired_messages)) + { + DBusMessage *message = iter->data; + + dbus_message_unref (message); + _dbus_list_free_link (iter); + } } /** @@ -407,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 * @@ -454,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; } @@ -477,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; @@ -521,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. @@ -542,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); } @@ -609,8 +628,8 @@ _dbus_connection_get_message_to_send (DBusConnection *connection) * @param message the message that was sent. */ void -_dbus_connection_message_sent (DBusConnection *connection, - DBusMessage *message) +_dbus_connection_message_sent_unlocked (DBusConnection *connection, + DBusMessage *message) { DBusList *link; @@ -625,11 +644,10 @@ _dbus_connection_message_sent (DBusConnection *connection, _dbus_assert (link != NULL); _dbus_assert (link->data == message); - /* Save this link in the link cache */ _dbus_list_unlink (&connection->outgoing_messages, link); - _dbus_list_prepend_link (&connection->link_cache, link); - + _dbus_list_prepend_link (&connection->expired_messages, link); + connection->n_outgoing -= 1; _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n", @@ -647,12 +665,11 @@ _dbus_connection_message_sent (DBusConnection *connection, dbus_message_get_signature (message), connection, connection->n_outgoing); - /* Save this link in the link cache also */ - _dbus_message_remove_counter (message, connection->outgoing_counter, - &link); - _dbus_list_prepend_link (&connection->link_cache, link); - - dbus_message_unref (message); + /* It's OK that in principle we call the notify function, because for the + * outgoing limit, there isn't one */ + _dbus_message_remove_counter (message, connection->outgoing_counter); + + /* The message will actually be unreffed when we unlock */ } /** Function to be called in protected_change_watch() with refcount held */ @@ -1061,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); @@ -1110,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); @@ -1134,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); @@ -1145,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); } /** @@ -1233,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; @@ -1265,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; @@ -1274,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; @@ -1294,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; @@ -1335,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 @@ -1346,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: @@ -1372,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) @@ -1396,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. @@ -1405,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; } @@ -1425,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); - if (last_unref) + _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, + "unref_unlocked"); + + if (old_refcount == 1) _dbus_connection_last_unref (connection); } @@ -1505,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; @@ -1529,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) { @@ -1545,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); @@ -1564,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); } } @@ -1581,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) { @@ -1680,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)) { @@ -1707,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, @@ -1739,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", @@ -1793,6 +1875,7 @@ connection_try_from_address_entry (DBusAddressEntry *entry, #ifndef DBUS_DISABLE_CHECKS _dbus_assert (!connection->have_connection_lock); #endif + return connection; } @@ -1924,31 +2007,13 @@ _dbus_connection_preallocate_send_unlocked (DBusConnection *connection) if (preallocated == NULL) return NULL; - if (connection->link_cache != NULL) - { - preallocated->queue_link = - _dbus_list_pop_first_link (&connection->link_cache); - preallocated->queue_link->data = NULL; - } - else - { - preallocated->queue_link = _dbus_list_alloc_link (NULL); - if (preallocated->queue_link == NULL) - goto failed_0; - } - - if (connection->link_cache != NULL) - { - preallocated->counter_link = - _dbus_list_pop_first_link (&connection->link_cache); - preallocated->counter_link->data = connection->outgoing_counter; - } - else - { - preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter); - if (preallocated->counter_link == NULL) - goto failed_1; - } + preallocated->queue_link = _dbus_list_alloc_link (NULL); + if (preallocated->queue_link == NULL) + goto failed_0; + + preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter); + if (preallocated->counter_link == NULL) + goto failed_1; _dbus_counter_ref (preallocated->counter_link->data); @@ -1977,6 +2042,8 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con _dbus_list_prepend_link (&connection->outgoing_messages, preallocated->queue_link); + /* It's OK that we'll never call the notify function, because for the + * outgoing limit, there isn't one */ _dbus_message_add_counter_link (message, preallocated->counter_link); @@ -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; } @@ -2641,18 +2711,17 @@ free_outgoing_message (void *element, DBusMessage *message = element; DBusConnection *connection = data; - _dbus_message_remove_counter (message, - connection->outgoing_counter, - NULL); + _dbus_message_remove_counter (message, connection->outgoing_counter); 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; @@ -2663,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... */ @@ -2672,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; @@ -2706,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) { @@ -2725,21 +2801,31 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_list_free_link (connection->disconnect_message_link); } - _dbus_list_clear (&connection->link_cache); - _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. @@ -2762,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)) @@ -2785,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 @@ -2940,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 @@ -3825,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; @@ -3859,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"); } /** @@ -3888,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", @@ -3900,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 @@ -3919,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) ? @@ -3932,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; @@ -3995,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"); } /** @@ -4063,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) { @@ -4077,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); @@ -4096,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); @@ -4104,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 @@ -4143,7 +4284,7 @@ notify_disconnected_unlocked (DBusConnection *connection) while ((link = _dbus_list_get_last_link (&connection->outgoing_messages))) { - _dbus_connection_message_sent (connection, link->data); + _dbus_connection_message_sent_unlocked (connection, link->data); } } } @@ -4180,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)) @@ -4189,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); @@ -4328,44 +4469,48 @@ static DBusHandlerResult _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, DBusMessage *message) { + dbus_bool_t sent = FALSE; + DBusMessage *ret = NULL; + DBusList *expire_link; + if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL) { /* This means we're letting the bus route this message */ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - else if (dbus_message_is_method_call (message, - DBUS_INTERFACE_PEER, - "Ping")) + + if (!dbus_message_has_interface (message, DBUS_INTERFACE_PEER)) + { + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + /* Preallocate a linked-list link, so that if we need to dispose of a + * message, we can attach it to the expired list */ + expire_link = _dbus_list_alloc_link (NULL); + + if (!expire_link) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (dbus_message_is_method_call (message, + DBUS_INTERFACE_PEER, + "Ping")) { - DBusMessage *ret; - dbus_bool_t sent; - ret = dbus_message_new_method_return (message); if (ret == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); - - dbus_message_unref (ret); + goto out; - if (!sent) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return DBUS_HANDLER_RESULT_HANDLED; + sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); } else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PEER, "GetMachineId")) { - DBusMessage *ret; - dbus_bool_t sent; DBusString uuid; ret = dbus_message_new_method_return (message); if (ret == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + goto out; - sent = FALSE; _dbus_string_init (&uuid); if (_dbus_get_local_machine_uuid_encoded (&uuid)) { @@ -4378,43 +4523,38 @@ _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, } } _dbus_string_free (&uuid); - - dbus_message_unref (ret); - - if (!sent) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return DBUS_HANDLER_RESULT_HANDLED; } - else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER)) + else { /* We need to bounce anything else with this interface, otherwise apps * could start extending the interface and when we added extensions * here to DBusConnection we'd break those apps. */ - - DBusMessage *ret; - dbus_bool_t sent; - ret = dbus_message_new_error (message, DBUS_ERROR_UNKNOWN_METHOD, "Unknown method invoked on org.freedesktop.DBus.Peer interface"); if (ret == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - + goto out; + sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); - - dbus_message_unref (ret); - - if (!sent) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return DBUS_HANDLER_RESULT_HANDLED; + } + +out: + if (ret == NULL) + { + _dbus_list_free_link (expire_link); } else { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + /* It'll be safe to unref the reply when we unlock */ + expire_link->data = ret; + _dbus_list_prepend_link (&connection->expired_messages, expire_link); } + + if (!sent) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return DBUS_HANDLER_RESULT_HANDLED; } /** @@ -4662,10 +4802,11 @@ dbus_connection_dispatch (DBusConnection *connection) DBusMessage *reply; DBusString str; DBusPreallocatedSend *preallocated; + DBusList *expire_link; _dbus_verbose (" sending error %s\n", DBUS_ERROR_UNKNOWN_METHOD); - + if (!_dbus_string_init (&str)) { result = DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -4696,11 +4837,24 @@ dbus_connection_dispatch (DBusConnection *connection) _dbus_verbose ("no memory for error reply in dispatch\n"); goto out; } - + + expire_link = _dbus_list_alloc_link (reply); + + if (expire_link == NULL) + { + dbus_message_unref (reply); + result = DBUS_HANDLER_RESULT_NEED_MEMORY; + _dbus_verbose ("no memory for error send in dispatch\n"); + goto out; + } + preallocated = _dbus_connection_preallocate_send_unlocked (connection); if (preallocated == NULL) { + _dbus_list_free_link (expire_link); + /* It's OK that this is finalized, because it hasn't been seen by + * anything that could attach user callbacks */ dbus_message_unref (reply); result = DBUS_HANDLER_RESULT_NEED_MEMORY; _dbus_verbose ("no memory for error send in dispatch\n"); @@ -4709,9 +4863,9 @@ dbus_connection_dispatch (DBusConnection *connection) _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated, reply, NULL); + /* reply will be freed when we release the lock */ + _dbus_list_prepend_link (&connection->expired_messages, expire_link); - dbus_message_unref (reply); - result = DBUS_HANDLER_RESULT_HANDLED; } @@ -4737,20 +4891,35 @@ dbus_connection_dispatch (DBusConnection *connection) */ _dbus_connection_putback_message_link_unlocked (connection, message_link); + /* now we don't want to free them */ + message_link = NULL; + message = NULL; } else { _dbus_verbose (" ... done dispatching\n"); - - _dbus_list_free_link (message_link); - dbus_message_unref (message); /* don't want the message to count in max message limits - * in computing dispatch status below - */ } - + _dbus_connection_release_dispatch (connection); HAVE_LOCK_CHECK (connection); + if (message != NULL) + { + /* We don't want this message to count in maximum message limits when + * computing the dispatch status, below. We have to drop the lock + * temporarily, because finalizing a message can trigger callbacks. + * + * We have a reference to the connection, and we don't use any cached + * pointers to the connection's internals below this point, so it should + * be safe to drop the lock and take it back. */ + CONNECTION_UNLOCK (connection); + dbus_message_unref (message); + CONNECTION_LOCK (connection); + } + + if (message_link != NULL) + _dbus_list_free_link (message_link); + _dbus_verbose ("before final status update\n"); status = _dbus_connection_get_dispatch_status_unlocked (connection); @@ -5064,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 @@ -5095,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; @@ -5131,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); @@ -5152,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 @@ -5165,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, @@ -5261,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, @@ -5799,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 @@ -5820,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); } @@ -5921,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, @@ -5990,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, @@ -6088,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, @@ -6156,8 +6345,7 @@ _dbus_connection_get_stats (DBusConnection *connection, dbus_uint32_t *out_bytes, dbus_uint32_t *out_fds, dbus_uint32_t *out_peak_bytes, - dbus_uint32_t *out_peak_fds, - dbus_uint32_t *link_cache_size) + dbus_uint32_t *out_peak_fds) { CONNECTION_LOCK (connection); @@ -6182,11 +6370,6 @@ _dbus_connection_get_stats (DBusConnection *connection, if (out_peak_fds != NULL) *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter); - if (link_cache_size != NULL) - { - *link_cache_size = _dbus_list_get_length (&connection->link_cache) * sizeof (DBusList); - } - CONNECTION_UNLOCK (connection); } #endif /* DBUS_ENABLE_STATS */ @@ -6211,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 + /** @} */