X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-connection.c;h=e01057908a88e203e27dcb22670fba5f66e31845;hb=1962bd7b478b21ae054b836f41e944f2a45f6621;hp=ac0b2c0e7313ab67bbab305c2e77417236673229;hpb=a183a33fb5bceefe53d60d584f352ca0b61667e1;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index ac0b2c0..e010579 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -203,26 +203,19 @@ * @{ */ -#ifdef DBUS_ENABLE_VERBOSE_MODE 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); -} -#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 @@ -318,7 +311,8 @@ struct DBusConnection */ dbus_bool_t dispatch_acquired; /**< Someone has dispatch path (can drain incoming queue) */ dbus_bool_t io_path_acquired; /**< Someone has transport io path (can use the transport to read/write messages) */ - + + unsigned int dispatch_disabled : 1; /**< if true, then dispatching incoming messages is stopped until enabled again */ unsigned int shareable : 1; /**< #TRUE if libdbus owns a reference to the connection and can return it from dbus_connection_open() more than once */ unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */ @@ -336,8 +330,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 }; @@ -446,7 +440,40 @@ _dbus_connection_wakeup_mainloop (DBusConnection *connection) (*connection->wakeup_main_function) (connection->wakeup_main_data); } -#ifdef DBUS_BUILD_TESTS +static void +_dbus_connection_set_dispatch(DBusConnection *connection, + dbus_bool_t disabled) +{ + CONNECTION_LOCK (connection); + if (connection->dispatch_disabled != disabled) + { + DBusDispatchStatus status; + + connection->dispatch_disabled = disabled; + status = _dbus_connection_get_dispatch_status_unlocked (connection); + _dbus_connection_update_dispatch_status_and_unlock (connection, status); + } + else + { + CONNECTION_UNLOCK (connection); + } +} + + +void +_dbus_connection_enable_dispatch (DBusConnection *connection) +{ + _dbus_connection_set_dispatch (connection, FALSE); +} + +void + _dbus_connection_disable_dispatch (DBusConnection *connection) +{ + _dbus_connection_set_dispatch (connection, TRUE); +} + + +#ifdef DBUS_ENABLE_EMBEDDED_TESTS /** * Gets the locks so we can examine them * @@ -490,9 +517,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; @@ -552,8 +579,21 @@ void _dbus_connection_queue_synthesized_message_link (DBusConnection *connection, DBusList *link) { + DBusMessage *msg, *rmsg; + HAVE_LOCK_CHECK (connection); - + + msg = (DBusMessage *)link->data; + + rmsg = msg; + if (_dbus_transport_assure_protocol_version (connection->transport, &rmsg)) + { + /* If the message is converted, then we don't need the old format anymore */ + _dbus_list_free_link(link); + link = _dbus_list_alloc_link (rmsg); + dbus_message_unref (msg); + } + _dbus_list_append_link (&connection->incoming_messages, link); connection->n_incoming += 1; @@ -1354,7 +1394,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 @@ -1531,7 +1571,7 @@ _dbus_connection_handle_watch (DBusWatch *watch, return retval; } -_DBUS_DEFINE_GLOBAL_LOCK (shared_connections); +/* Protected by _DBUS_LOCK (shared_connections) */ static DBusHashTable *shared_connections = NULL; static DBusList *shared_connections_no_guid = NULL; @@ -1555,9 +1595,14 @@ static void shared_connections_shutdown (void *data) { int n_entries; - - _DBUS_LOCK (shared_connections); - + + if (!_DBUS_LOCK (shared_connections)) + { + /* We'd have initialized locks before adding anything, so there + * can't be anything there. */ + return; + } + /* This is a little bit unpleasant... better ideas? */ while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0) { @@ -1571,7 +1616,8 @@ shared_connections_shutdown (void *data) _DBUS_UNLOCK (shared_connections); close_connection_on_shutdown (connection); - _DBUS_LOCK (shared_connections); + if (!_DBUS_LOCK (shared_connections)) + _dbus_assert_not_reached ("global locks were already initialized"); /* The connection should now be dead and not in our hash ... */ _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries); @@ -1590,7 +1636,8 @@ shared_connections_shutdown (void *data) { _DBUS_UNLOCK (shared_connections); close_connection_on_shutdown (connection); - _DBUS_LOCK (shared_connections); + if (!_DBUS_LOCK (shared_connections)) + _dbus_assert_not_reached ("global locks were already initialized"); connection = _dbus_list_pop_first (&shared_connections_no_guid); } } @@ -1607,8 +1654,13 @@ connection_lookup_shared (DBusAddressEntry *entry, _dbus_verbose ("checking for existing connection\n"); *result = NULL; - - _DBUS_LOCK (shared_connections); + + if (!_DBUS_LOCK (shared_connections)) + { + /* If it was shared, we'd have initialized global locks when we put + * it in shared_connections. */ + return FALSE; + } if (shared_connections == NULL) { @@ -1706,7 +1758,8 @@ connection_record_shared_unlocked (DBusConnection *connection, if (guid == NULL) { - _DBUS_LOCK (shared_connections); + if (!_DBUS_LOCK (shared_connections)) + return FALSE; if (!_dbus_list_prepend (&shared_connections_no_guid, connection)) { @@ -1733,8 +1786,14 @@ connection_record_shared_unlocked (DBusConnection *connection, dbus_free (guid_key); return FALSE; } - - _DBUS_LOCK (shared_connections); + + if (!_DBUS_LOCK (shared_connections)) + { + dbus_free (guid_in_connection); + dbus_free (guid_key); + return FALSE; + } + _dbus_assert (shared_connections != NULL); if (!_dbus_hash_table_insert_string (shared_connections, @@ -1765,9 +1824,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", @@ -1981,6 +2045,34 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con { dbus_uint32_t serial; + /* Finish preparing the message */ + if (dbus_message_get_serial (message) == 0) + { + serial = _dbus_connection_get_next_client_serial (connection); + dbus_message_set_serial (message, serial); + if (client_serial) + *client_serial = serial; + } + else + { + if (client_serial) + *client_serial = dbus_message_get_serial (message); + } + + _dbus_verbose ("Message %p serial is %u\n", + message, dbus_message_get_serial (message)); + + dbus_message_lock (message); + + /* This converts message if neccessary */ + if (!_dbus_transport_assure_protocol_version (connection->transport, &message)) + { + /* Only non-converted messages must be refed. + * Converted messages are local anyway. + */ + dbus_message_ref (message); + } + preallocated->queue_link->data = message; _dbus_list_prepend_link (&connection->outgoing_messages, preallocated->queue_link); @@ -1993,8 +2085,6 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con dbus_free (preallocated); preallocated = NULL; - dbus_message_ref (message); - connection->n_outgoing += 1; _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n", @@ -2016,24 +2106,6 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con connection, connection->n_outgoing); - if (dbus_message_get_serial (message) == 0) - { - serial = _dbus_connection_get_next_client_serial (connection); - dbus_message_set_serial (message, serial); - if (client_serial) - *client_serial = serial; - } - else - { - if (client_serial) - *client_serial = dbus_message_get_serial (message); - } - - _dbus_verbose ("Message %p serial is %u\n", - message, dbus_message_get_serial (message)); - - dbus_message_lock (message); - /* Now we need to run an iteration to hopefully just write the messages * out immediately, and otherwise get them queued up */ @@ -2150,7 +2222,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) @@ -2165,52 +2237,6 @@ _dbus_memory_pause_based_on_timeout (int timeout_milliseconds) _dbus_sleep_milliseconds (1000); } -static DBusMessage * -generate_local_error_message (dbus_uint32_t serial, - char *error_name, - char *error_msg) -{ - DBusMessage *message; - message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); - if (!message) - goto out; - - if (!dbus_message_set_error_name (message, error_name)) - { - dbus_message_unref (message); - message = NULL; - goto out; - } - - dbus_message_set_no_reply (message, TRUE); - - if (!dbus_message_set_reply_serial (message, - serial)) - { - dbus_message_unref (message); - message = NULL; - goto out; - } - - if (error_msg != NULL) - { - DBusMessageIter iter; - - dbus_message_iter_init_append (message, &iter); - if (!dbus_message_iter_append_basic (&iter, - DBUS_TYPE_STRING, - &error_msg)) - { - dbus_message_unref (message); - message = NULL; - goto out; - } - } - - out: - return message; -} - /* * Peek the incoming queue to see if we got reply for a specific serial */ @@ -2308,10 +2334,11 @@ complete_pending_call_and_unlock (DBusConnection *connection, { _dbus_pending_call_set_reply_unlocked (pending, message); _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */ + _dbus_pending_call_start_completion_unlocked(pending); _dbus_connection_detach_pending_call_and_unlock (connection, pending); - + /* Must be called unlocked since it invokes app callback */ - _dbus_pending_call_complete (pending); + _dbus_pending_call_finish_completion (pending); dbus_pending_call_unref (pending); } @@ -2388,7 +2415,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) * below */ timeout = _dbus_pending_call_get_timeout_unlocked (pending); - _dbus_get_current_time (&start_tv_sec, &start_tv_usec); + _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec); if (timeout) { timeout_milliseconds = dbus_timeout_get_interval (timeout); @@ -2445,7 +2472,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; @@ -2453,12 +2480,14 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) { DBusMessage *error_msg; - error_msg = generate_local_error_message (client_serial, - DBUS_ERROR_DISCONNECTED, - "Connection was disconnected before a reply was received"); + error_msg = _dbus_generate_local_error_message (client_serial, + DBUS_ERROR_DISCONNECTED, + "Connection was disconnected before a reply was received"); /* on OOM error_msg is set to NULL */ complete_pending_call_and_unlock (connection, pending, error_msg); + if (error_msg != NULL) + dbus_message_unref (error_msg); dbus_pending_call_unref (pending); return; } @@ -2508,7 +2537,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) { /* block again, we don't have the reply buffered yet. */ _dbus_connection_do_iteration_unlocked (connection, - NULL, + pending, DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK, timeout_milliseconds - elapsed_milliseconds); @@ -2532,6 +2561,33 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending) dbus_pending_call_unref (pending); } +/** + * Return how many file descriptors are pending in the loader + * + * @param connection the connection + */ +int +_dbus_connection_get_pending_fds_count (DBusConnection *connection) +{ + return _dbus_transport_get_pending_fds_count (connection->transport); +} + +/** + * Register a function to be called whenever the number of pending file + * descriptors in the loader change. + * + * @param connection the connection + * @param callback the callback + */ +void +_dbus_connection_set_pending_fds_function (DBusConnection *connection, + DBusPendingFdsChangeFunction callback, + void *data) +{ + _dbus_transport_set_pending_fds_function (connection->transport, + callback, data); +} + /** @} */ /** @@ -2683,6 +2739,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; @@ -2713,8 +2770,6 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_hash_table_unref (connection->pending_replies); connection->pending_replies = NULL; - _dbus_list_clear (&connection->filter_list); - _dbus_list_foreach (&connection->outgoing_messages, free_outgoing_message, connection); @@ -2745,7 +2800,7 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_rmutex_free_at_location (&connection->slot_mutex); _dbus_rmutex_free_at_location (&connection->mutex); - + dbus_free (connection); } @@ -2788,8 +2843,8 @@ dbus_connection_unref (DBusConnection *connection) { _dbus_warn_check_failed ("The last reference on a connection was dropped without closing the connection. This is a bug in an application. See dbus_connection_unref() documentation for details.\n%s", connection->shareable ? - "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : - "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n"); + "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection." : + "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection."); return; } #endif @@ -2896,7 +2951,7 @@ dbus_connection_close (DBusConnection *connection) { CONNECTION_UNLOCK (connection); - _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n"); + _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application."); return; } #endif @@ -2952,9 +3007,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; @@ -3014,7 +3069,7 @@ dbus_connection_get_is_anonymous (DBusConnection *connection) * dbus_bus_get_id() instead (which is just a convenience wrapper * around the org.freedesktop.DBus.GetId method invoked on the bus). * - * You can also get a machine ID; see dbus_get_local_machine_id() to + * You can also get a machine ID; see dbus_try_get_local_machine_id() to * get the machine you are on. There isn't a convenience wrapper, but * you can invoke org.freedesktop.DBus.Peer.GetMachineId on any peer * to get the machine ID on the other end. @@ -3391,6 +3446,7 @@ dbus_connection_send_with_reply (DBusConnection *connection, return TRUE; } + _dbus_message_set_timeout_ms(message, timeout_milliseconds); pending = _dbus_pending_call_new_unlocked (connection, timeout_milliseconds, reply_handler_timeout); @@ -3500,6 +3556,22 @@ dbus_connection_send_with_reply_and_block (DBusConnection *connection, _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL); _dbus_return_val_if_error_is_set (error, NULL); + if (_dbus_transport_can_send_sync_call (connection->transport)) + { + dbus_int32_t serial; + + /* set serial */ + serial = dbus_message_get_serial (message); + if (serial == 0) + { + serial = _dbus_connection_get_next_client_serial (connection); + dbus_message_set_serial (message, serial); + } + + reply = _dbus_transport_send_sync_call (connection->transport, message); + goto out; + } + #ifdef HAVE_UNIX_FD_PASSING CONNECTION_LOCK (connection); @@ -3535,9 +3607,11 @@ dbus_connection_send_with_reply_and_block (DBusConnection *connection, /* call_complete_and_unlock() called from pending_call_block() should * always fill this in. */ + +out: _dbus_assert (reply != NULL); - if (dbus_set_error_from_message (error, reply)) + if (dbus_set_error_from_message (error, reply)) { dbus_message_unref (reply); return NULL; @@ -3938,7 +4012,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) ? @@ -3951,6 +4025,7 @@ _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, @@ -4022,6 +4097,82 @@ _dbus_connection_putback_message_link_unlocked (DBusConnection *connection, "_dbus_connection_putback_message_link_unlocked"); } +dbus_bool_t +_dbus_connection_putback_message (DBusConnection *connection, + DBusMessage *after_message, + DBusMessage *message, + DBusError *error) +{ + DBusDispatchStatus status; + DBusList *message_link = _dbus_list_alloc_link (message); + DBusList *after_link; + if (message_link == NULL) + { + _DBUS_SET_OOM (error); + return FALSE; + } + dbus_message_ref (message); + + CONNECTION_LOCK (connection); + _dbus_connection_acquire_dispatch (connection); + HAVE_LOCK_CHECK (connection); + + after_link = _dbus_list_find_first(&connection->incoming_messages, after_message); + _dbus_list_insert_after_link (&connection->incoming_messages, after_link, message_link); + connection->n_incoming += 1; + + _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n", + message_link->data, + dbus_message_type_to_string (dbus_message_get_type (message_link->data)), + dbus_message_get_interface (message_link->data) ? + dbus_message_get_interface (message_link->data) : + "no interface", + dbus_message_get_member (message_link->data) ? + dbus_message_get_member (message_link->data) : + "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"); + + _dbus_connection_release_dispatch (connection); + + status = _dbus_connection_get_dispatch_status_unlocked (connection); + _dbus_connection_update_dispatch_status_and_unlock (connection, status); + + return TRUE; +} + +dbus_bool_t +_dbus_connection_remove_message (DBusConnection *connection, + DBusMessage *message) +{ + DBusDispatchStatus status; + dbus_bool_t removed; + + CONNECTION_LOCK (connection); + _dbus_connection_acquire_dispatch (connection); + HAVE_LOCK_CHECK (connection); + + removed = _dbus_list_remove(&connection->incoming_messages, message); + + if (removed) + { + connection->n_incoming -= 1; + dbus_message_unref(message); + _dbus_verbose ("Message %p removed from incoming queue\n", message); + } + else + _dbus_verbose ("Message %p not found in the incoming queue\n", message); + + _dbus_connection_release_dispatch (connection); + + status = _dbus_connection_get_dispatch_status_unlocked (connection); + _dbus_connection_update_dispatch_status_and_unlock (connection, status); + return removed; +} + /** * Returns the first-received message from the incoming message queue, * removing it from the queue. The caller owns a reference to the @@ -4205,8 +4356,9 @@ static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection) { HAVE_LOCK_CHECK (connection); - - if (connection->n_incoming > 0) + if (connection->dispatch_disabled) + return DBUS_DISPATCH_COMPLETE; + else if (connection->n_incoming > 0) return DBUS_DISPATCH_DATA_REMAINS; else if (!_dbus_transport_queue_messages (connection->transport)) return DBUS_DISPATCH_NEED_MEMORY; @@ -4390,15 +4542,24 @@ _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, "GetMachineId")) { DBusString uuid; - - ret = dbus_message_new_method_return (message); - if (ret == NULL) + DBusError error = DBUS_ERROR_INIT; + + if (!_dbus_string_init (&uuid)) goto out; - _dbus_string_init (&uuid); - if (_dbus_get_local_machine_uuid_encoded (&uuid)) + if (_dbus_get_local_machine_uuid_encoded (&uuid, &error)) { - const char *v_STRING = _dbus_string_get_const_data (&uuid); + const char *v_STRING; + + ret = dbus_message_new_method_return (message); + + if (ret == NULL) + { + _dbus_string_free (&uuid); + goto out; + } + + v_STRING = _dbus_string_get_const_data (&uuid); if (dbus_message_append_args (ret, DBUS_TYPE_STRING, &v_STRING, DBUS_TYPE_INVALID)) @@ -4406,6 +4567,25 @@ _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); } } + else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) + { + dbus_error_free (&error); + _dbus_string_free (&uuid); + goto out; + } + else + { + ret = dbus_message_new_error (message, error.name, error.message); + dbus_error_free (&error); + _dbus_string_free (&uuid); + + if (ret == NULL) + goto out; + + sent = _dbus_connection_send_unlocked_no_update (connection, ret, + NULL); + } + _dbus_string_free (&uuid); } else @@ -4643,6 +4823,8 @@ dbus_connection_dispatch (DBusConnection *connection) CONNECTION_LOCK (connection); + if (result == DBUS_HANDLER_RESULT_LATER) + goto out; if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) { _dbus_verbose ("No memory\n"); @@ -4765,9 +4947,11 @@ dbus_connection_dispatch (DBusConnection *connection) connection); out: - if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) + if (result == DBUS_HANDLER_RESULT_LATER || + result == DBUS_HANDLER_RESULT_NEED_MEMORY) { - _dbus_verbose ("out of memory\n"); + if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) + _dbus_verbose ("out of memory\n"); /* Put message back, and we'll start over. * Yes this means handlers must be idempotent if they @@ -5103,20 +5287,41 @@ dbus_connection_get_socket(DBusConnection *connection, int *fd) { dbus_bool_t retval; + DBusSocket s = DBUS_SOCKET_INIT; _dbus_return_val_if_fail (connection != NULL, FALSE); _dbus_return_val_if_fail (connection->transport != NULL, FALSE); CONNECTION_LOCK (connection); - retval = _dbus_transport_get_socket_fd (connection->transport, - fd); + retval = _dbus_transport_get_socket_fd (connection->transport, &s); + + if (retval) + { + *fd = _dbus_socket_get_int (s); + } CONNECTION_UNLOCK (connection); return retval; } +/** + * + * Getter for number of messages in incoming queue. + * Useful for sending reply to self (see kdbus_do_iteration) + */ +int +_dbus_connection_get_n_incoming (DBusConnection *connection) +{ + return connection->n_incoming; +} + +dbus_bool_t +_dbus_connection_is_overflowed (DBusConnection *connection) +{ + return _dbus_transport_get_overflowed (connection->transport); +} /** * Gets the UNIX user ID of the connection if known. Returns #TRUE if @@ -5148,10 +5353,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, @@ -5184,10 +5389,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, @@ -5205,7 +5410,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 @@ -5218,10 +5424,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, @@ -5275,6 +5481,32 @@ dbus_connection_set_unix_user_function (DBusConnection *connection, (* old_free_function) (old_data); } +/* Same calling convention as dbus_connection_get_windows_user */ +dbus_bool_t +_dbus_connection_get_linux_security_label (DBusConnection *connection, + char **label_p) +{ + dbus_bool_t result; + + _dbus_assert (connection != NULL); + _dbus_assert (label_p != NULL); + + CONNECTION_LOCK (connection); + + if (!_dbus_transport_try_to_authenticate (connection->transport)) + result = FALSE; + else + result = _dbus_transport_get_linux_security_label (connection->transport, + label_p); +#ifndef __linux__ + _dbus_assert (!result); +#endif + + CONNECTION_UNLOCK (connection); + + return result; +} + /** * Gets the Windows user SID of the connection if known. Returns * #TRUE if the ID is filled in. Always returns #FALSE on non-Windows @@ -5314,10 +5546,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, @@ -5435,7 +5667,7 @@ dbus_connection_set_route_peer_messages (DBusConnection *connection, _dbus_return_if_fail (connection != NULL); CONNECTION_LOCK (connection); - connection->route_peer_messages = TRUE; + connection->route_peer_messages = value; CONNECTION_UNLOCK (connection); } @@ -5550,7 +5782,7 @@ dbus_connection_remove_filter (DBusConnection *connection, #ifndef DBUS_DISABLE_CHECKS if (filter == NULL) { - _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n", + _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added", function, user_data); return; } @@ -5669,7 +5901,7 @@ dbus_connection_register_object_path (DBusConnection *connection, if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE)) { - _dbus_warn ("%s\n", error.message); + _dbus_warn ("%s", error.message); dbus_error_free (&error); return FALSE; } @@ -5741,7 +5973,7 @@ dbus_connection_register_fallback (DBusConnection *connection, if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE)) { - _dbus_warn ("%s\n", error.message); + _dbus_warn ("%s", error.message); dbus_error_free (&error); return FALSE; } @@ -5852,8 +6084,8 @@ dbus_connection_list_registered (DBusConnection *connection, return retval; } -static DBusDataSlotAllocator slot_allocator; -_DBUS_DEFINE_GLOBAL_LOCK (connection_slots); +static DBusDataSlotAllocator slot_allocator = + _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots)); /** * Allocates an integer ID to be used for storing application-specific @@ -5873,7 +6105,6 @@ dbus_bool_t dbus_connection_allocate_data_slot (dbus_int32_t *slot_p) { return _dbus_data_slot_allocator_alloc (&slot_allocator, - &_DBUS_LOCK_NAME (connection_slots), slot_p); } @@ -5974,7 +6205,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, @@ -6043,7 +6275,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, @@ -6141,7 +6373,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, @@ -6258,7 +6490,7 @@ dbus_connection_get_outgoing_unix_fds (DBusConnection *connection) return res; } -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS /** * Returns the address of the transport object of this connection *