X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-connection.c;h=a6caaea6298f3bad4650d66f7cf2fa8ca138bce2;hb=bb9e5f65e7acecda1a812e58875d8a65f5a065d3;hp=94bbc57e7d463ba8f5d664ac7181464768d72a59;hpb=30f116fd2d20cbeb13ed20f1f780d8aa92e67983;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 94bbc57..a6caaea 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -66,22 +66,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 +203,27 @@ * @{ */ +#ifdef DBUS_ENABLE_VERBOSE_MODE +static void +_dbus_connection_trace_ref (DBusConnection *connection, + int old_refcount, + int new_refcount, + const char *why) +{ + static int enabled = -1; + + _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount, + why, "DBUS_CONNECTION_TRACE", &enabled); +} +#else +#define _dbus_connection_trace_ref(c,o,n,w) \ + do \ + {\ + (void) (o); \ + (void) (n); \ + } while (0) +#endif + /** * Internal struct representing a message filter function */ @@ -247,15 +264,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 +290,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 +308,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 +336,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 }; @@ -342,8 +357,14 @@ static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DB static DBusMessageFilter * _dbus_message_filter_ref (DBusMessageFilter *filter) { - _dbus_assert (filter->refcount.value > 0); +#ifdef DBUS_DISABLE_ASSERT _dbus_atomic_inc (&filter->refcount); +#else + dbus_int32_t old_value; + + old_value = _dbus_atomic_inc (&filter->refcount); + _dbus_assert (old_value > 0); +#endif return filter; } @@ -351,9 +372,12 @@ _dbus_message_filter_ref (DBusMessageFilter *filter) static void _dbus_message_filter_unref (DBusMessageFilter *filter) { - _dbus_assert (filter->refcount.value > 0); + dbus_int32_t old_value; - if (_dbus_atomic_dec (&filter->refcount) == 1) + old_value = _dbus_atomic_dec (&filter->refcount); + _dbus_assert (old_value > 0); + + if (old_value == 1) { if (filter->free_user_data_function) (* filter->free_user_data_function) (filter->user_data); @@ -381,7 +405,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); + } } /** @@ -398,33 +446,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 * @@ -445,9 +467,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; } @@ -468,9 +490,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; @@ -512,7 +534,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. @@ -533,7 +559,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); } @@ -600,8 +629,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; @@ -616,11 +645,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", @@ -638,12 +666,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 */ @@ -1052,7 +1079,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); @@ -1101,7 +1128,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); @@ -1125,7 +1152,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); @@ -1136,7 +1163,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); } /** @@ -1265,15 +1292,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; @@ -1285,7 +1312,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; @@ -1310,8 +1337,9 @@ _dbus_connection_new_for_transport (DBusTransport *transport) if (_dbus_modify_sigpipe) _dbus_disable_sigpipe (); - - connection->refcount.value = 1; + + /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */ + _dbus_atomic_inc (&connection->refcount); connection->transport = transport; connection->watches = watch_list; connection->timeouts = timeout_list; @@ -1326,7 +1354,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport) 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 @@ -1348,7 +1376,8 @@ _dbus_connection_new_for_transport (DBusTransport *transport) _dbus_transport_ref (transport); CONNECTION_UNLOCK (connection); - + + _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport"); return connection; error: @@ -1362,10 +1391,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) @@ -1395,13 +1424,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; } @@ -1415,15 +1448,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); } @@ -1495,7 +1531,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; @@ -1519,9 +1555,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) { @@ -1535,7 +1576,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); @@ -1554,7 +1596,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); } } @@ -1571,8 +1614,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) { @@ -1670,7 +1718,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)) { @@ -1697,8 +1746,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, @@ -1729,9 +1784,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", @@ -1914,31 +1974,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); @@ -1967,6 +2009,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); @@ -2108,23 +2152,15 @@ _dbus_connection_send_and_unlock (DBusConnection *connection, void _dbus_connection_close_if_only_one_ref (DBusConnection *connection) { - dbus_int32_t tmp_refcount; + dbus_int32_t refcount; CONNECTION_LOCK (connection); - /* We increment and then decrement the refcount, because there is no - * _dbus_atomic_get (mirroring the fact that there's no InterlockedGet - * on Windows). */ - _dbus_atomic_inc (&connection->refcount); - tmp_refcount = _dbus_atomic_dec (&connection->refcount); - - /* The caller should have one ref, and this function temporarily took - * one more, which is reflected in this count even though we already - * released it (relying on the caller's ref) due to _dbus_atomic_dec - * semantics */ - _dbus_assert (tmp_refcount >= 2); + refcount = _dbus_atomic_get (&connection->refcount); + /* The caller should have at least one ref */ + _dbus_assert (refcount >= 1); - if (tmp_refcount == 2) + if (refcount == 1) _dbus_connection_close_possibly_shared_and_unlock (connection); else CONNECTION_UNLOCK (connection); @@ -2138,7 +2174,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) @@ -2376,7 +2412,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); @@ -2433,7 +2469,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; @@ -2624,10 +2660,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; } @@ -2639,9 +2678,7 @@ 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); } @@ -2655,9 +2692,9 @@ _dbus_connection_last_unref (DBusConnection *connection) DBusList *link; _dbus_verbose ("Finalizing connection %p\n", connection); - - _dbus_assert (connection->refcount.value == 0); - + + _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0); + /* You have to disconnect the connection before unref:ing it. Otherwise * you won't get the disconnected message. */ @@ -2670,6 +2707,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; @@ -2723,17 +2761,15 @@ _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); } @@ -2760,14 +2796,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)) @@ -2938,9 +2977,9 @@ 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; @@ -3823,6 +3862,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; @@ -3857,6 +3898,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"); } /** @@ -3886,7 +3929,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", @@ -3898,6 +3942,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 @@ -3917,7 +3963,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) ? @@ -3930,8 +3976,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; @@ -3993,6 +4043,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"); } /** @@ -4061,7 +4114,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) { @@ -4075,7 +4128,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); @@ -4094,7 +4147,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); @@ -4102,7 +4155,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 @@ -4141,7 +4194,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); } } } @@ -4326,44 +4379,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)) { @@ -4376,43 +4433,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; } /** @@ -4660,10 +4712,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; @@ -4694,11 +4747,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"); @@ -4707,9 +4773,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; } @@ -4735,20 +4801,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); @@ -5093,10 +5174,10 @@ 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)) + if (!_dbus_transport_try_to_authenticate (connection->transport)) result = FALSE; else result = _dbus_transport_get_unix_user (connection->transport, @@ -5129,10 +5210,10 @@ 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)) + if (!_dbus_transport_try_to_authenticate (connection->transport)) result = FALSE; else result = _dbus_transport_get_unix_process_id (connection->transport, @@ -5150,7 +5231,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 @@ -5163,10 +5245,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, @@ -5259,10 +5341,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, @@ -5420,8 +5502,8 @@ dbus_connection_add_filter (DBusConnection *connection, if (filter == NULL) return FALSE; - filter->refcount.value = 1; - + _dbus_atomic_inc (&filter->refcount); + CONNECTION_LOCK (connection); if (!_dbus_list_append (&connection->filter_list, @@ -5512,31 +5594,30 @@ dbus_connection_remove_filter (DBusConnection *connection, } /** - * Registers a handler for a given path in the object hierarchy. - * The given vtable handles messages sent to exactly the given path. + * Registers a handler for a given path or subsection in the object + * hierarchy. The given vtable handles messages sent to exactly the + * given path or also for paths bellow that, depending on fallback + * parameter. * * @param connection the connection + * @param fallback whether to handle messages also for "subdirectory" * @param path a '/' delimited string of path elements * @param vtable the virtual table * @param user_data data to pass to functions in the vtable * @param error address where an error can be returned * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or - * #DBUS_ERROR_ADDRESS_IN_USE) is reported + * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported */ -dbus_bool_t -dbus_connection_try_register_object_path (DBusConnection *connection, - const char *path, - const DBusObjectPathVTable *vtable, - void *user_data, - DBusError *error) +static dbus_bool_t +_dbus_connection_register_object_path (DBusConnection *connection, + dbus_bool_t fallback, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error) { char **decomposed_path; dbus_bool_t retval; - - _dbus_return_val_if_fail (connection != NULL, FALSE); - _dbus_return_val_if_fail (path != NULL, FALSE); - _dbus_return_val_if_fail (path[0] == '/', FALSE); - _dbus_return_val_if_fail (vtable != NULL, FALSE); if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) return FALSE; @@ -5544,7 +5625,7 @@ dbus_connection_try_register_object_path (DBusConnection *connectio CONNECTION_LOCK (connection); retval = _dbus_object_tree_register (connection->objects, - FALSE, + fallback, (const char **) decomposed_path, vtable, user_data, error); @@ -5559,6 +5640,33 @@ dbus_connection_try_register_object_path (DBusConnection *connectio * Registers a handler for a given path in the object hierarchy. * The given vtable handles messages sent to exactly the given path. * + * @param connection the connection + * @param path a '/' delimited string of path elements + * @param vtable the virtual table + * @param user_data data to pass to functions in the vtable + * @param error address where an error can be returned + * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or + * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported + */ +dbus_bool_t +dbus_connection_try_register_object_path (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error) +{ + _dbus_return_val_if_fail (connection != NULL, FALSE); + _dbus_return_val_if_fail (path != NULL, FALSE); + _dbus_return_val_if_fail (path[0] == '/', FALSE); + _dbus_return_val_if_fail (vtable != NULL, FALSE); + + return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error); +} + +/** + * Registers a handler for a given path in the object hierarchy. + * The given vtable handles messages sent to exactly the given path. + * * It is a bug to call this function for object paths which already * have a handler. Use dbus_connection_try_register_object_path() if this * might be the case. @@ -5567,7 +5675,8 @@ dbus_connection_try_register_object_path (DBusConnection *connectio * @param path a '/' delimited string of path elements * @param vtable the virtual table * @param user_data data to pass to functions in the vtable - * @returns #FALSE if not enough memory + * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or + * #DBUS_ERROR_OBJECT_PATH_IN_USE) ocurred */ dbus_bool_t dbus_connection_register_object_path (DBusConnection *connection, @@ -5575,7 +5684,6 @@ dbus_connection_register_object_path (DBusConnection *connection, const DBusObjectPathVTable *vtable, void *user_data) { - char **decomposed_path; dbus_bool_t retval; DBusError error = DBUS_ERROR_INIT; @@ -5584,21 +5692,9 @@ dbus_connection_register_object_path (DBusConnection *connection, _dbus_return_val_if_fail (path[0] == '/', FALSE); _dbus_return_val_if_fail (vtable != NULL, FALSE); - if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) - return FALSE; - - CONNECTION_LOCK (connection); - - retval = _dbus_object_tree_register (connection->objects, - FALSE, - (const char **) decomposed_path, vtable, - user_data, &error); - - CONNECTION_UNLOCK (connection); + retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error); - dbus_free_string_array (decomposed_path); - - if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE)) + if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE)) { _dbus_warn ("%s\n", error.message); dbus_error_free (&error); @@ -5620,7 +5716,7 @@ dbus_connection_register_object_path (DBusConnection *connection, * @param user_data data to pass to functions in the vtable * @param error address where an error can be returned * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or - * #DBUS_ERROR_ADDRESS_IN_USE) is reported + * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported */ dbus_bool_t dbus_connection_try_register_fallback (DBusConnection *connection, @@ -5629,29 +5725,12 @@ dbus_connection_try_register_fallback (DBusConnection *connection, void *user_data, DBusError *error) { - char **decomposed_path; - dbus_bool_t retval; - _dbus_return_val_if_fail (connection != NULL, FALSE); _dbus_return_val_if_fail (path != NULL, FALSE); _dbus_return_val_if_fail (path[0] == '/', FALSE); _dbus_return_val_if_fail (vtable != NULL, FALSE); - if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) - return FALSE; - - CONNECTION_LOCK (connection); - - retval = _dbus_object_tree_register (connection->objects, - TRUE, - (const char **) decomposed_path, vtable, - user_data, error); - - CONNECTION_UNLOCK (connection); - - dbus_free_string_array (decomposed_path); - - return retval; + return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error); } /** @@ -5668,7 +5747,8 @@ dbus_connection_try_register_fallback (DBusConnection *connection, * @param path a '/' delimited string of path elements * @param vtable the virtual table * @param user_data data to pass to functions in the vtable - * @returns #FALSE if not enough memory + * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or + * #DBUS_ERROR_OBJECT_PATH_IN_USE) occured */ dbus_bool_t dbus_connection_register_fallback (DBusConnection *connection, @@ -5676,7 +5756,6 @@ dbus_connection_register_fallback (DBusConnection *connection, const DBusObjectPathVTable *vtable, void *user_data) { - char **decomposed_path; dbus_bool_t retval; DBusError error = DBUS_ERROR_INIT; @@ -5685,21 +5764,9 @@ dbus_connection_register_fallback (DBusConnection *connection, _dbus_return_val_if_fail (path[0] == '/', FALSE); _dbus_return_val_if_fail (vtable != NULL, FALSE); - if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) - return FALSE; - - CONNECTION_LOCK (connection); - - retval = _dbus_object_tree_register (connection->objects, - TRUE, - (const char **) decomposed_path, vtable, - user_data, &error); + retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error); - CONNECTION_UNLOCK (connection); - - dbus_free_string_array (decomposed_path); - - if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE)) + if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE)) { _dbus_warn ("%s\n", error.message); dbus_error_free (&error); @@ -5812,8 +5879,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 @@ -5833,7 +5900,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); } @@ -5934,7 +6000,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, @@ -6003,7 +6070,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, @@ -6101,7 +6168,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, @@ -6169,8 +6236,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); @@ -6195,11 +6261,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 */ @@ -6224,4 +6285,18 @@ dbus_connection_get_outgoing_unix_fds (DBusConnection *connection) return res; } +#ifdef DBUS_ENABLE_EMBEDDED_TESTS +/** + * 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); +} +#endif + /** @} */