X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-connection.c;h=2c624367074e97e55290aea11a69a9970ff6d8a2;hb=c1a77d2c58c78abc606f1cb7918704596ebf2bfe;hp=03ee066730723d209033f88cc1a066b741b47ed1;hpb=c80c20af46c5f43dcbe672f2c6d8aec0e7f2bbd6;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 03ee066..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) @@ -203,26 +209,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 @@ -336,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 }; @@ -446,7 +445,7 @@ _dbus_connection_wakeup_mainloop (DBusConnection *connection) (*connection->wakeup_main_function) (connection->wakeup_main_data); } -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS /** * Gets the locks so we can examine them * @@ -490,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; @@ -1251,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; @@ -1283,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; @@ -1353,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 @@ -1364,18 +1368,23 @@ _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; @@ -1415,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. @@ -1555,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) { @@ -1571,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); @@ -1590,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); } } @@ -1607,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) { @@ -1706,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)) { @@ -1733,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, @@ -1765,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", @@ -1819,6 +1875,7 @@ connection_try_from_address_entry (DBusAddressEntry *entry, #ifndef DBUS_DISABLE_CHECKS _dbus_assert (!connection->have_connection_lock); #endif + return connection; } @@ -2150,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) @@ -2165,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) @@ -2658,12 +2715,13 @@ free_outgoing_message (void *element, dbus_message_unref (message); } -/* This is run without the mutex held, but after the last reference - * to the connection has been dropped we should have no thread-related - * problems - */ +#ifdef ENABLE_KDBUS_TRANSPORT +static void +_dbus_connection_last_unref_internal (DBusConnection *connection, dbus_bool_t unref_transport) +#else static void _dbus_connection_last_unref (DBusConnection *connection) +#endif { DBusList *link; @@ -2674,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... */ @@ -2683,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; @@ -2717,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) { @@ -2749,6 +2814,18 @@ _dbus_connection_last_unref (DBusConnection *connection) 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. @@ -2797,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 @@ -2952,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 @@ -3938,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) ? @@ -3951,6 +4066,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, @@ -4205,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)) @@ -4214,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); @@ -5117,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 @@ -5148,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; @@ -5184,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); @@ -5205,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 @@ -5218,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, @@ -5314,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, @@ -6043,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, @@ -6141,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, @@ -6258,7 +6394,6 @@ dbus_connection_get_outgoing_unix_fds (DBusConnection *connection) return res; } -#ifdef DBUS_BUILD_TESTS /** * Returns the address of the transport object of this connection * @@ -6270,6 +6405,15 @@ _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 /** @} */