From b61b94a14488f22ab7f136dc0a9f6c7787d3f510 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Wed, 9 Mar 2005 23:12:24 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'dbus-0.23.3'. --- dbus/dbus-connection.c | 466 +++++++------------------------------------ dbus/dbus-object-tree.c | 459 +++++++----------------------------------- dbus/dbus-pending-call.c | 18 ++ dbus/dbus-server-protected.h | 22 +- dbus/dbus-server-unix.c | 39 +--- dbus/dbus-server.c | 317 ++++------------------------- dbus/dbus-transport-unix.c | 6 +- dbus/dbus-transport.c | 221 +++++++++++--------- 8 files changed, 341 insertions(+), 1207 deletions(-) (limited to 'dbus') diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index db76ba22..89f789b3 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -38,7 +38,7 @@ #include "dbus-string.h" #include "dbus-pending-call.h" #include "dbus-object-tree.h" -#include "dbus-threads-internal.h" +#include "dbus-marshal.h" #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(connection) @@ -61,14 +61,14 @@ #define CONNECTION_LOCK(connection) do { \ if (TRACE_LOCKS) { _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); } \ - _dbus_mutex_lock ((connection)->mutex); \ + dbus_mutex_lock ((connection)->mutex); \ TOOK_LOCK_CHECK (connection); \ } while (0) #define CONNECTION_UNLOCK(connection) do { \ if (TRACE_LOCKS) { _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); } \ RELEASING_LOCK_CHECK (connection); \ - _dbus_mutex_unlock ((connection)->mutex); \ + dbus_mutex_unlock ((connection)->mutex); \ } while (0) #define DISPATCH_STATUS_NAME(s) \ @@ -125,8 +125,8 @@ * * When a connection is disconnected, you are guaranteed to get a * signal "Disconnected" from the interface - * #DBUS_INTERFACE_LOCAL, path - * #DBUS_PATH_LOCAL. + * #DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, path + * #DBUS_PATH_ORG_FREEDESKTOP_LOCAL. * * You may not drop the last reference to a #DBusConnection * until that connection has been disconnected. @@ -233,10 +233,6 @@ struct DBusConnection * 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 */ - - unsigned int shareable : 1; /**< #TRUE if connection can go in shared_connections once we know the GUID */ unsigned int dispatch_acquired : 1; /**< Someone has dispatch path (can drain incoming queue) */ unsigned int io_path_acquired : 1; /**< Someone has transport io path (can use the transport to read/write messages) */ @@ -927,7 +923,7 @@ _dbus_connection_acquire_io_path (DBusConnection *connection, CONNECTION_UNLOCK (connection); _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_lock (connection->io_path_mutex); + dbus_mutex_lock (connection->io_path_mutex); _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n", _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds); @@ -940,16 +936,16 @@ _dbus_connection_acquire_io_path (DBusConnection *connection, { _dbus_verbose ("%s waiting %d for IO path to be acquirable\n", _DBUS_FUNCTION_NAME, timeout_milliseconds); - _dbus_condvar_wait_timeout (connection->io_path_cond, - connection->io_path_mutex, - timeout_milliseconds); + dbus_condvar_wait_timeout (connection->io_path_cond, + connection->io_path_mutex, + timeout_milliseconds); } else { while (connection->io_path_acquired) { _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME); - _dbus_condvar_wait (connection->io_path_cond, connection->io_path_mutex); + dbus_condvar_wait (connection->io_path_cond, connection->io_path_mutex); } } } @@ -964,7 +960,7 @@ _dbus_connection_acquire_io_path (DBusConnection *connection, _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired); _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_unlock (connection->io_path_mutex); + dbus_mutex_unlock (connection->io_path_mutex); CONNECTION_LOCK (connection); @@ -988,7 +984,7 @@ _dbus_connection_release_io_path (DBusConnection *connection) HAVE_LOCK_CHECK (connection); _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_lock (connection->io_path_mutex); + dbus_mutex_lock (connection->io_path_mutex); _dbus_assert (connection->io_path_acquired); @@ -996,10 +992,10 @@ _dbus_connection_release_io_path (DBusConnection *connection) _DBUS_FUNCTION_NAME, connection->io_path_acquired); connection->io_path_acquired = FALSE; - _dbus_condvar_wake_one (connection->io_path_cond); + dbus_condvar_wake_one (connection->io_path_cond); _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_unlock (connection->io_path_mutex); + dbus_mutex_unlock (connection->io_path_mutex); } /** @@ -1118,32 +1114,32 @@ _dbus_connection_new_for_transport (DBusTransport *transport) if (connection == NULL) goto error; - mutex = _dbus_mutex_new (); + mutex = dbus_mutex_new (); if (mutex == NULL) goto error; - io_path_mutex = _dbus_mutex_new (); + io_path_mutex = dbus_mutex_new (); if (io_path_mutex == NULL) goto error; - dispatch_mutex = _dbus_mutex_new (); + dispatch_mutex = dbus_mutex_new (); if (dispatch_mutex == NULL) goto error; - message_returned_cond = _dbus_condvar_new (); + message_returned_cond = dbus_condvar_new (); if (message_returned_cond == NULL) goto error; - dispatch_cond = _dbus_condvar_new (); + dispatch_cond = dbus_condvar_new (); if (dispatch_cond == NULL) goto error; - io_path_cond = _dbus_condvar_new (); + io_path_cond = dbus_condvar_new (); if (io_path_cond == NULL) goto error; - disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL, - DBUS_INTERFACE_LOCAL, + disconnect_message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_LOCAL, + DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected"); if (disconnect_message == NULL) @@ -1179,7 +1175,6 @@ _dbus_connection_new_for_transport (DBusTransport *transport) connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */ connection->objects = objects; connection->exit_on_disconnect = FALSE; - connection->shareable = FALSE; #ifndef DBUS_DISABLE_CHECKS connection->generation = _dbus_current_generation; #endif @@ -1209,22 +1204,22 @@ _dbus_connection_new_for_transport (DBusTransport *transport) _dbus_list_free_link (disconnect_link); if (io_path_cond != NULL) - _dbus_condvar_free (io_path_cond); + dbus_condvar_free (io_path_cond); if (dispatch_cond != NULL) - _dbus_condvar_free (dispatch_cond); + dbus_condvar_free (dispatch_cond); if (message_returned_cond != NULL) - _dbus_condvar_free (message_returned_cond); + dbus_condvar_free (message_returned_cond); if (mutex != NULL) - _dbus_mutex_free (mutex); + dbus_mutex_free (mutex); if (io_path_mutex != NULL) - _dbus_mutex_free (io_path_mutex); + dbus_mutex_free (io_path_mutex); if (dispatch_mutex != NULL) - _dbus_mutex_free (dispatch_mutex); + dbus_mutex_free (dispatch_mutex); if (connection != NULL) dbus_free (connection); @@ -1368,301 +1363,6 @@ _dbus_connection_handle_watch (DBusWatch *watch, return retval; } -_DBUS_DEFINE_GLOBAL_LOCK (shared_connections); -static DBusHashTable *shared_connections = NULL; - -static void -shared_connections_shutdown (void *data) -{ - _DBUS_LOCK (shared_connections); - - _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0); - _dbus_hash_table_unref (shared_connections); - shared_connections = NULL; - - _DBUS_UNLOCK (shared_connections); -} - -static dbus_bool_t -connection_lookup_shared (DBusAddressEntry *entry, - DBusConnection **result) -{ - _dbus_verbose ("checking for existing connection\n"); - - *result = NULL; - - _DBUS_LOCK (shared_connections); - - if (shared_connections == NULL) - { - _dbus_verbose ("creating shared_connections hash table\n"); - - shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING, - dbus_free, - NULL); - if (shared_connections == NULL) - { - _DBUS_UNLOCK (shared_connections); - return FALSE; - } - - if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL)) - { - _dbus_hash_table_unref (shared_connections); - shared_connections = NULL; - _DBUS_UNLOCK (shared_connections); - return FALSE; - } - - _dbus_verbose (" successfully created shared_connections\n"); - - _DBUS_UNLOCK (shared_connections); - return TRUE; /* no point looking up in the hash we just made */ - } - else - { - const char *guid; - - guid = dbus_address_entry_get_value (entry, "guid"); - - if (guid != NULL) - { - *result = _dbus_hash_table_lookup_string (shared_connections, - guid); - - if (*result) - { - /* The DBusConnection can't have been disconnected - * between the lookup and this code, because the - * disconnection will take the shared_connections lock to - * remove the connection. It can't have been finalized - * since you have to disconnect prior to finalize. - * - * Thus it's safe to ref the connection. - */ - dbus_connection_ref (*result); - - _dbus_verbose ("looked up existing connection to server guid %s\n", - guid); - } - } - - _DBUS_UNLOCK (shared_connections); - return TRUE; - } -} - -static dbus_bool_t -connection_record_shared_unlocked (DBusConnection *connection, - const char *guid) -{ - char *guid_key; - char *guid_in_connection; - - /* A separate copy of the key is required in the hash table, because - * we don't have a lock on the connection when we are doing a hash - * lookup. - */ - - _dbus_assert (connection->server_guid == NULL); - _dbus_assert (connection->shareable); - - guid_key = _dbus_strdup (guid); - if (guid_key == NULL) - return FALSE; - - guid_in_connection = _dbus_strdup (guid); - if (guid_in_connection == NULL) - { - dbus_free (guid_key); - return FALSE; - } - - _DBUS_LOCK (shared_connections); - _dbus_assert (shared_connections != NULL); - - if (!_dbus_hash_table_insert_string (shared_connections, - guid_key, connection)) - { - dbus_free (guid_key); - dbus_free (guid_in_connection); - _DBUS_UNLOCK (shared_connections); - return FALSE; - } - - connection->server_guid = guid_in_connection; - - _dbus_verbose ("stored connection to %s to be shared\n", - connection->server_guid); - - _DBUS_UNLOCK (shared_connections); - - _dbus_assert (connection->server_guid != NULL); - - return TRUE; -} - -static void -connection_forget_shared_unlocked (DBusConnection *connection) -{ - HAVE_LOCK_CHECK (connection); - - if (connection->server_guid == NULL) - return; - - _dbus_verbose ("dropping connection to %s out of the shared table\n", - connection->server_guid); - - _DBUS_LOCK (shared_connections); - - if (!_dbus_hash_table_remove_string (shared_connections, - connection->server_guid)) - _dbus_assert_not_reached ("connection was not in the shared table"); - - dbus_free (connection->server_guid); - connection->server_guid = NULL; - - _DBUS_UNLOCK (shared_connections); -} - -static DBusConnection* -connection_try_from_address_entry (DBusAddressEntry *entry, - DBusError *error) -{ - DBusTransport *transport; - DBusConnection *connection; - - transport = _dbus_transport_open (entry, error); - - if (transport == NULL) - { - _DBUS_ASSERT_ERROR_IS_SET (error); - return NULL; - } - - connection = _dbus_connection_new_for_transport (transport); - - _dbus_transport_unref (transport); - - if (connection == NULL) - { - _DBUS_SET_OOM (error); - return NULL; - } - -#ifndef DBUS_DISABLE_CHECKS - _dbus_assert (!connection->have_connection_lock); -#endif - return connection; -} - -/* - * If the shared parameter is true, then any existing connection will - * be used (and if a new connection is created, it will be available - * for use by others). If the shared parameter is false, a new - * connection will always be created, and the new connection will - * never be returned to other callers. - * - * @param address the address - * @param shared whether the connection is shared or private - * @param error error return - * @returns the connection or #NULL on error - */ -static DBusConnection* -_dbus_connection_open_internal (const char *address, - dbus_bool_t shared, - DBusError *error) -{ - DBusConnection *connection; - DBusAddressEntry **entries; - DBusError tmp_error; - DBusError first_error; - int len, i; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - _dbus_verbose ("opening %s connection to: %s\n", - shared ? "shared" : "private", address); - - if (!dbus_parse_address (address, &entries, &len, error)) - return NULL; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - connection = NULL; - - dbus_error_init (&tmp_error); - dbus_error_init (&first_error); - for (i = 0; i < len; i++) - { - if (shared) - { - if (!connection_lookup_shared (entries[i], &connection)) - _DBUS_SET_OOM (&tmp_error); - } - - if (connection == NULL) - { - connection = connection_try_from_address_entry (entries[i], - &tmp_error); - - if (connection != NULL && shared) - { - const char *guid; - - connection->shareable = TRUE; - - guid = dbus_address_entry_get_value (entries[i], "guid"); - - /* we don't have a connection lock but we know nobody - * else has a handle to the connection - */ - - if (guid && - !connection_record_shared_unlocked (connection, guid)) - { - _DBUS_SET_OOM (&tmp_error); - dbus_connection_disconnect (connection); - dbus_connection_unref (connection); - connection = NULL; - } - - /* but as of now the connection is possibly shared - * since another thread could have pulled it from the table - */ - } - } - - if (connection) - break; - - _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); - - if (i == 0) - dbus_move_error (&tmp_error, &first_error); - else - dbus_error_free (&tmp_error); - } - - /* NOTE we don't have a lock on a possibly-shared connection object */ - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error); - - if (connection == NULL) - { - _DBUS_ASSERT_ERROR_IS_SET (&first_error); - dbus_move_error (&first_error, error); - } - else - { - dbus_error_free (&first_error); - } - - dbus_address_entries_free (entries); - return connection; -} - /** @} */ /** @@ -1672,19 +1372,16 @@ _dbus_connection_open_internal (const char *address, */ /** - * Gets a connection to a remote address. If a connection to the given - * address already exists, returns the existing connection with its - * reference count incremented. Otherwise, returns a new connection - * and saves the new connection for possible re-use if a future call - * to dbus_connection_open() asks to connect to the same server. + * Opens a new connection to a remote address. * - * Use dbus_connection_open_private() to get a dedicated connection - * not shared with other callers of dbus_connection_open(). + * @todo specify what the address parameter is. Right now + * it's just the name of a UNIX domain socket. It should be + * something more complex that encodes which transport to use. * - * If the open fails, the function returns #NULL, and provides a - * reason for the failure in the error parameter. Pass #NULL for the - * error parameter if you aren't interested in the reason for - * failure. + * If the open fails, the function returns #NULL, and provides + * a reason for the failure in the result parameter. Pass + * #NULL for the result parameter if you aren't interested + * in the reason for failure. * * @param address the address. * @param error address where an error can be returned. @@ -1695,44 +1392,31 @@ dbus_connection_open (const char *address, DBusError *error) { DBusConnection *connection; + DBusTransport *transport; _dbus_return_val_if_fail (address != NULL, NULL); _dbus_return_val_if_error_is_set (error, NULL); + + transport = _dbus_transport_open (address, error); + if (transport == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + return NULL; + } + + connection = _dbus_connection_new_for_transport (transport); - connection = _dbus_connection_open_internal (address, - TRUE, - error); - - return connection; -} - -/** - * Opens a new, dedicated connection to a remote address. Unlike - * dbus_connection_open(), always creates a new connection. - * This connection will not be saved or recycled by libdbus. - * - * If the open fails, the function returns #NULL, and provides a - * reason for the failure in the error parameter. Pass #NULL for the - * error parameter if you aren't interested in the reason for - * failure. - * - * @param address the address. - * @param error address where an error can be returned. - * @returns new connection, or #NULL on failure. - */ -DBusConnection* -dbus_connection_open_private (const char *address, - DBusError *error) -{ - DBusConnection *connection; - - _dbus_return_val_if_fail (address != NULL, NULL); - _dbus_return_val_if_error_is_set (error, NULL); - - connection = _dbus_connection_open_internal (address, - FALSE, - error); + _dbus_transport_unref (transport); + + if (connection == NULL) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } +#ifndef DBUS_DISABLE_CHECKS + _dbus_assert (!connection->have_connection_lock); +#endif return connection; } @@ -1795,8 +1479,7 @@ _dbus_connection_last_unref (DBusConnection *connection) * you won't get the disconnected message. */ _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... */ _dbus_object_tree_free_all_unlocked (connection->objects); @@ -1846,7 +1529,7 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_list_clear (&connection->incoming_messages); _dbus_counter_unref (connection->outgoing_counter); - + _dbus_transport_unref (connection->transport); if (connection->disconnect_message_link) @@ -1858,13 +1541,13 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_list_clear (&connection->link_cache); - _dbus_condvar_free (connection->dispatch_cond); - _dbus_condvar_free (connection->io_path_cond); + dbus_condvar_free (connection->dispatch_cond); + dbus_condvar_free (connection->io_path_cond); - _dbus_mutex_free (connection->io_path_mutex); - _dbus_mutex_free (connection->dispatch_mutex); + dbus_mutex_free (connection->io_path_mutex); + dbus_mutex_free (connection->dispatch_mutex); - _dbus_mutex_free (connection->mutex); + dbus_mutex_free (connection->mutex); dbus_free (connection); } @@ -1937,7 +1620,6 @@ dbus_connection_disconnect (DBusConnection *connection) _dbus_verbose ("Disconnecting %p\n", connection); CONNECTION_LOCK (connection); - _dbus_transport_disconnect (connection->transport); _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); @@ -2459,9 +2141,9 @@ dbus_connection_send_with_reply (DBusConnection *connection, if (!_dbus_connection_attach_pending_call_unlocked (connection, pending)) goto error; - + dbus_pending_call_unref (pending); - + if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL)) { _dbus_connection_detach_pending_call_and_unlock (connection, @@ -3079,12 +2761,12 @@ _dbus_connection_acquire_dispatch (DBusConnection *connection) CONNECTION_UNLOCK (connection); _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_lock (connection->dispatch_mutex); + dbus_mutex_lock (connection->dispatch_mutex); while (connection->dispatch_acquired) { _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME); - _dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex); + dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex); } _dbus_assert (!connection->dispatch_acquired); @@ -3092,7 +2774,7 @@ _dbus_connection_acquire_dispatch (DBusConnection *connection) connection->dispatch_acquired = TRUE; _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_unlock (connection->dispatch_mutex); + dbus_mutex_unlock (connection->dispatch_mutex); CONNECTION_LOCK (connection); _dbus_connection_unref_unlocked (connection); @@ -3111,15 +2793,15 @@ _dbus_connection_release_dispatch (DBusConnection *connection) HAVE_LOCK_CHECK (connection); _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_lock (connection->dispatch_mutex); + dbus_mutex_lock (connection->dispatch_mutex); _dbus_assert (connection->dispatch_acquired); connection->dispatch_acquired = FALSE; - _dbus_condvar_wake_one (connection->dispatch_cond); + dbus_condvar_wake_one (connection->dispatch_cond); _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_unlock (connection->dispatch_mutex); + dbus_mutex_unlock (connection->dispatch_mutex); } static void @@ -3158,9 +2840,7 @@ _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection) { _dbus_verbose ("Sending disconnect message from %s\n", _DBUS_FUNCTION_NAME); - - connection_forget_shared_unlocked (connection); - + /* We haven't sent the disconnect message already, * and all real messages have been queued up. */ @@ -3537,7 +3217,7 @@ dbus_connection_dispatch (DBusConnection *connection) if (connection->exit_on_disconnect && dbus_message_is_signal (message, - DBUS_INTERFACE_LOCAL, + DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected")) { _dbus_verbose ("Exiting on Disconnected signal\n"); diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c index 1d6029af..f4fa82d4 100644 --- a/dbus/dbus-object-tree.c +++ b/dbus/dbus-object-tree.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ /* dbus-object-tree.c DBusObjectTree (internals of DBusConnection) * - * Copyright (C) 2003, 2005 Red Hat Inc. + * Copyright (C) 2003 Red Hat Inc. * * Licensed under the Academic Free License version 2.1 * @@ -462,7 +462,7 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, _dbus_warn ("Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered\n", path[0] ? path[0] : "null", path[1] ? path[1] : "null"); - goto unlock; + goto unlock; } #else _dbus_assert (subtree != NULL); @@ -507,7 +507,6 @@ unlock: #endif { _dbus_connection_ref_unlocked (connection); - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); _dbus_connection_unlock (connection); } @@ -612,56 +611,22 @@ _dbus_object_tree_list_registered_unlocked (DBusObjectTree *tree, } static DBusHandlerResult -handle_default_introspect_and_unlock (DBusObjectTree *tree, - DBusMessage *message, - const char **path) +handle_default_introspect_unlocked (DBusObjectTree *tree, + DBusMessage *message, + const char **path) { DBusString xml; DBusHandlerResult result; char **children; int i; - DBusMessage *reply; - DBusMessageIter iter; - const char *v_STRING; - dbus_bool_t already_unlocked; - /* We have the connection lock here */ - - already_unlocked = FALSE; - - _dbus_verbose (" considering default Introspect() handler...\n"); - - reply = NULL; - if (!dbus_message_is_method_call (message, - DBUS_INTERFACE_INTROSPECTABLE, + DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE, "Introspect")) - { -#ifdef DBUS_BUILD_TESTS - if (tree->connection) -#endif - { - _dbus_verbose ("unlock %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); - _dbus_connection_unlock (tree->connection); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - _dbus_verbose (" using default Introspect() handler!\n"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (!_dbus_string_init (&xml)) - { -#ifdef DBUS_BUILD_TESTS - if (tree->connection) -#endif - { - _dbus_verbose ("unlock %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); - _dbus_connection_unlock (tree->connection); - } - - return DBUS_HANDLER_RESULT_NEED_MEMORY; - } + return DBUS_HANDLER_RESULT_NEED_MEMORY; result = DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -669,9 +634,6 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree, if (!_dbus_object_tree_list_registered_unlocked (tree, path, &children)) goto out; - if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)) - goto out; - if (!_dbus_string_append (&xml, "\n")) goto out; @@ -687,44 +649,12 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree, if (!_dbus_string_append (&xml, "\n")) goto out; - - reply = dbus_message_new_method_return (message); - if (reply == NULL) - goto out; - - dbus_message_iter_init_append (reply, &iter); - v_STRING = _dbus_string_get_const_data (&xml); - if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &v_STRING)) - goto out; - -#ifdef DBUS_BUILD_TESTS - if (tree->connection) -#endif - { - already_unlocked = TRUE; - - if (!_dbus_connection_send_and_unlock (tree->connection, reply, NULL)) - goto out; - } result = DBUS_HANDLER_RESULT_HANDLED; out: -#ifdef DBUS_BUILD_TESTS - if (tree->connection) -#endif - { - if (!already_unlocked) - { - _dbus_verbose ("unlock %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); - _dbus_connection_unlock (tree->connection); - } - } - _dbus_string_free (&xml); dbus_free_string_array (children); - if (reply) - dbus_message_unref (reply); return result; } @@ -763,10 +693,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } + _dbus_connection_unlock (tree->connection); _dbus_verbose ("No memory to get decomposed path\n"); @@ -778,10 +705,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } + _dbus_connection_unlock (tree->connection); _dbus_verbose ("No path field in message\n"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -844,10 +768,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } + _dbus_connection_unlock (tree->connection); /* FIXME you could unregister the subtree in another thread * before we invoke the callback, and I can't figure out a @@ -876,19 +797,14 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, { /* This hardcoded default handler does a minimal Introspect() */ - result = handle_default_introspect_and_unlock (tree, message, - (const char**) path); + result = handle_default_introspect_unlocked (tree, message, + (const char**) path); } - else - { + #ifdef DBUS_BUILD_TESTS - if (tree->connection) + if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } - } + _dbus_connection_unlock (tree->connection); while (list != NULL) { @@ -1021,112 +937,11 @@ _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } + _dbus_connection_unlock (tree->connection); return result; } - - -/** Set to 1 to get a bunch of spew about disassembling the path string */ -#define VERBOSE_DECOMPOSE 0 - -/** - * Decompose an object path. A path of just "/" is - * represented as an empty vector of strings. - * The path need not be nul terminated. - * - * @param data the path data - * @param len the length of the path string - * @param path address to store new object path - * @param path_len length of stored path - */ -dbus_bool_t -_dbus_decompose_path (const char* data, - int len, - char ***path, - int *path_len) -{ - char **retval; - int n_components; - int i, j, comp; - - _dbus_assert (data != NULL); - -#if VERBOSE_DECOMPOSE - _dbus_verbose ("Decomposing path \"%s\"\n", - data); -#endif - - n_components = 0; - if (len > 1) /* if path is not just "/" */ - { - i = 0; - while (i < len) - { - if (data[i] == '/') - n_components += 1; - ++i; - } - } - - retval = dbus_new0 (char*, n_components + 1); - - if (retval == NULL) - return FALSE; - - comp = 0; - if (n_components == 0) - i = 1; - else - i = 0; - while (comp < n_components) - { - _dbus_assert (i < len); - - if (data[i] == '/') - ++i; - j = i; - - while (j < len && data[j] != '/') - ++j; - - /* Now [i, j) is the path component */ - _dbus_assert (i < j); - _dbus_assert (data[i] != '/'); - _dbus_assert (j == len || data[j] == '/'); - -#if VERBOSE_DECOMPOSE - _dbus_verbose (" (component in [%d,%d))\n", - i, j); -#endif - - retval[comp] = _dbus_memdup (&data[i], j - i + 1); - if (retval[comp] == NULL) - { - dbus_free_string_array (retval); - return FALSE; - } - retval[comp][j-i] = '\0'; -#if VERBOSE_DECOMPOSE - _dbus_verbose (" (component %d = \"%s\")\n", - comp, retval[comp]); -#endif - - ++comp; - i = j; - } - _dbus_assert (i == len); - - *path = retval; - if (path_len) - *path_len = n_components; - - return TRUE; -} - + /** @} */ #ifdef DBUS_BUILD_TESTS @@ -1137,31 +952,22 @@ static char* flatten_path (const char **path) { DBusString str; + int i; char *s; if (!_dbus_string_init (&str)) return NULL; - if (path[0] == NULL) + i = 0; + while (path[i]) { if (!_dbus_string_append_byte (&str, '/')) goto nomem; - } - else - { - int i; - - i = 0; - while (path[i]) - { - if (!_dbus_string_append_byte (&str, '/')) - goto nomem; - - if (!_dbus_string_append (&str, path[i])) - goto nomem; - - ++i; - } + + if (!_dbus_string_append (&str, path[i])) + goto nomem; + + ++i; } if (!_dbus_string_steal_data (&str, &s)) @@ -1300,7 +1106,7 @@ do_register (DBusObjectTree *tree, { DBusObjectPathVTable vtable = { test_unregister_function, test_message_function, NULL }; - + tree_test_data[i].message_handled = FALSE; tree_test_data[i].handler_unregistered = FALSE; tree_test_data[i].handler_fallback = fallback; @@ -1387,82 +1193,17 @@ do_test_dispatch (DBusObjectTree *tree, } static size_t -string_array_length (const char **array) +string_array_length (char **array) { size_t i; for (i = 0; array[i]; i++) ; return i; } -typedef struct -{ - const char *path; - const char *result[20]; -} DecomposePathTest; - -static DecomposePathTest decompose_tests[] = { - { "/foo", { "foo", NULL } }, - { "/foo/bar", { "foo", "bar", NULL } }, - { "/", { NULL } }, - { "/a/b", { "a", "b", NULL } }, - { "/a/b/c", { "a", "b", "c", NULL } }, - { "/a/b/c/d", { "a", "b", "c", "d", NULL } }, - { "/foo/bar/q", { "foo", "bar", "q", NULL } }, - { "/foo/bar/this/is/longer", { "foo", "bar", "this", "is", "longer", NULL } } -}; - -static dbus_bool_t -run_decompose_tests (void) -{ - int i; - - i = 0; - while (i < _DBUS_N_ELEMENTS (decompose_tests)) - { - char **result; - int result_len; - int expected_len; - - if (!_dbus_decompose_path (decompose_tests[i].path, - strlen (decompose_tests[i].path), - &result, &result_len)) - return FALSE; - - expected_len = string_array_length (decompose_tests[i].result); - - if (result_len != (int) string_array_length ((const char**)result) || - expected_len != result_len || - path_contains (decompose_tests[i].result, - (const char**) result) != STR_EQUAL) - { - int real_len = string_array_length ((const char**)result); - _dbus_warn ("Expected decompose of %s to have len %d, returned %d, appears to have %d\n", - decompose_tests[i].path, expected_len, result_len, - real_len); - _dbus_warn ("Decompose resulted in elements: { "); - i = 0; - while (i < real_len) - { - _dbus_warn ("\"%s\"%s", result[i], - (i + 1) == real_len ? "" : ", "); - ++i; - } - _dbus_warn ("}\n"); - _dbus_assert_not_reached ("path decompose failed\n"); - } - - dbus_free_string_array (result); - - ++i; - } - - return TRUE; -} static dbus_bool_t object_tree_test_iteration (void *data) { - const char *path0[] = { NULL }; const char *path1[] = { "foo", NULL }; const char *path2[] = { "foo", "bar", NULL }; const char *path3[] = { "foo", "bar", "baz", NULL }; @@ -1472,46 +1213,19 @@ object_tree_test_iteration (void *data) const char *path7[] = { "blah", "boof", "this", "is", "really", "long", NULL }; const char *path8[] = { "childless", NULL }; DBusObjectTree *tree; - TreeTestData tree_test_data[9]; + TreeTestData tree_test_data[8]; int i; dbus_bool_t exact_match; - if (!run_decompose_tests ()) - return FALSE; - tree = NULL; tree = _dbus_object_tree_new (NULL); if (tree == NULL) goto out; - if (!do_register (tree, path0, TRUE, 0, tree_test_data)) - goto out; - - _dbus_assert (find_subtree (tree, path0, NULL)); - _dbus_assert (!find_subtree (tree, path1, NULL)); - _dbus_assert (!find_subtree (tree, path2, NULL)); - _dbus_assert (!find_subtree (tree, path3, NULL)); - _dbus_assert (!find_subtree (tree, path4, NULL)); - _dbus_assert (!find_subtree (tree, path5, NULL)); - _dbus_assert (!find_subtree (tree, path6, NULL)); - _dbus_assert (!find_subtree (tree, path7, NULL)); - _dbus_assert (!find_subtree (tree, path8, NULL)); - - _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match); - _dbus_assert (find_handler (tree, path1, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path2, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path3, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path4, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path5, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path6, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); - - if (!do_register (tree, path1, TRUE, 1, tree_test_data)) + if (!do_register (tree, path1, TRUE, 0, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1521,7 +1235,6 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match); _dbus_assert (find_handler (tree, path1, &exact_match) && exact_match); _dbus_assert (find_handler (tree, path2, &exact_match) && !exact_match); _dbus_assert (find_handler (tree, path3, &exact_match) && !exact_match); @@ -1531,7 +1244,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match); _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); - if (!do_register (tree, path2, TRUE, 2, tree_test_data)) + if (!do_register (tree, path2, TRUE, 1, tree_test_data)) goto out; _dbus_assert (find_subtree (tree, path1, NULL)); @@ -1543,10 +1256,9 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path3, TRUE, 3, tree_test_data)) + if (!do_register (tree, path3, TRUE, 2, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1556,10 +1268,9 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path4, TRUE, 4, tree_test_data)) + if (!do_register (tree, path4, TRUE, 3, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1569,10 +1280,9 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path5, TRUE, 5, tree_test_data)) + if (!do_register (tree, path5, TRUE, 4, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1581,8 +1291,7 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path6, NULL)); _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - - _dbus_assert (find_handler (tree, path0, &exact_match) == tree->root && exact_match); + _dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match); _dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match); _dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match); @@ -1592,10 +1301,9 @@ object_tree_test_iteration (void *data) _dbus_assert (find_handler (tree, path7, &exact_match) != tree->root && !exact_match); _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); - if (!do_register (tree, path6, TRUE, 6, tree_test_data)) + if (!do_register (tree, path6, TRUE, 5, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1605,10 +1313,9 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path7, TRUE, 7, tree_test_data)) + if (!do_register (tree, path7, TRUE, 6, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1618,10 +1325,9 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path8, TRUE, 8, tree_test_data)) + if (!do_register (tree, path8, TRUE, 7, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1630,8 +1336,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path6, NULL)); _dbus_assert (find_subtree (tree, path7, NULL)); _dbus_assert (find_subtree (tree, path8, NULL)); - - _dbus_assert (find_handler (tree, path0, &exact_match) == tree->root && exact_match); + _dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match); _dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match); _dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match); @@ -1651,7 +1356,7 @@ object_tree_test_iteration (void *data) _dbus_object_tree_list_registered_unlocked (tree, path1, &child_entries); if (child_entries != NULL) { - nb = string_array_length ((const char**)child_entries); + nb = string_array_length (child_entries); _dbus_assert (nb == 1); dbus_free_string_array (child_entries); } @@ -1659,7 +1364,7 @@ object_tree_test_iteration (void *data) _dbus_object_tree_list_registered_unlocked (tree, path2, &child_entries); if (child_entries != NULL) { - nb = string_array_length ((const char**)child_entries); + nb = string_array_length (child_entries); _dbus_assert (nb == 2); dbus_free_string_array (child_entries); } @@ -1667,7 +1372,7 @@ object_tree_test_iteration (void *data) _dbus_object_tree_list_registered_unlocked (tree, path8, &child_entries); if (child_entries != NULL) { - nb = string_array_length ((const char**)child_entries); + nb = string_array_length (child_entries); _dbus_assert (nb == 0); dbus_free_string_array (child_entries); } @@ -1675,7 +1380,7 @@ object_tree_test_iteration (void *data) _dbus_object_tree_list_registered_unlocked (tree, root, &child_entries); if (child_entries != NULL) { - nb = string_array_length ((const char**)child_entries); + nb = string_array_length (child_entries); _dbus_assert (nb == 3); dbus_free_string_array (child_entries); } @@ -1697,40 +1402,25 @@ object_tree_test_iteration (void *data) if (tree == NULL) goto out; - if (!do_register (tree, path0, TRUE, 0, tree_test_data)) + if (!do_register (tree, path1, TRUE, 0, tree_test_data)) goto out; - if (!do_register (tree, path1, TRUE, 1, tree_test_data)) + if (!do_register (tree, path2, TRUE, 1, tree_test_data)) goto out; - if (!do_register (tree, path2, TRUE, 2, tree_test_data)) + if (!do_register (tree, path3, TRUE, 2, tree_test_data)) goto out; - if (!do_register (tree, path3, TRUE, 3, tree_test_data)) + if (!do_register (tree, path4, TRUE, 3, tree_test_data)) goto out; - if (!do_register (tree, path4, TRUE, 4, tree_test_data)) + if (!do_register (tree, path5, TRUE, 4, tree_test_data)) goto out; - if (!do_register (tree, path5, TRUE, 5, tree_test_data)) + if (!do_register (tree, path6, TRUE, 5, tree_test_data)) goto out; - if (!do_register (tree, path6, TRUE, 6, tree_test_data)) + if (!do_register (tree, path7, TRUE, 6, tree_test_data)) goto out; - if (!do_register (tree, path7, TRUE, 7, tree_test_data)) + if (!do_register (tree, path8, TRUE, 7, tree_test_data)) goto out; - if (!do_register (tree, path8, TRUE, 8, tree_test_data)) - goto out; - - _dbus_object_tree_unregister_and_unlock (tree, path0); - - _dbus_assert (!find_subtree (tree, path0, NULL)); - _dbus_assert (find_subtree (tree, path1, NULL)); - _dbus_assert (find_subtree (tree, path2, NULL)); - _dbus_assert (find_subtree (tree, path3, NULL)); - _dbus_assert (find_subtree (tree, path4, NULL)); - _dbus_assert (find_subtree (tree, path5, NULL)); - _dbus_assert (find_subtree (tree, path6, NULL)); - _dbus_assert (find_subtree (tree, path7, NULL)); - _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path1); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1742,7 +1432,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path2); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1754,7 +1443,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path3); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1766,7 +1454,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path4); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1778,7 +1465,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path5); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1790,7 +1476,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path6); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1802,7 +1487,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path7); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1814,7 +1498,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path8); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1833,47 +1516,43 @@ object_tree_test_iteration (void *data) } /* Register it all again, and test dispatch */ - - if (!do_register (tree, path0, TRUE, 0, tree_test_data)) - goto out; - if (!do_register (tree, path1, FALSE, 1, tree_test_data)) + + if (!do_register (tree, path1, FALSE, 0, tree_test_data)) goto out; - if (!do_register (tree, path2, TRUE, 2, tree_test_data)) + if (!do_register (tree, path2, TRUE, 1, tree_test_data)) goto out; - if (!do_register (tree, path3, TRUE, 3, tree_test_data)) + if (!do_register (tree, path3, TRUE, 2, tree_test_data)) goto out; - if (!do_register (tree, path4, TRUE, 4, tree_test_data)) + if (!do_register (tree, path4, TRUE, 3, tree_test_data)) goto out; - if (!do_register (tree, path5, TRUE, 5, tree_test_data)) + if (!do_register (tree, path5, TRUE, 4, tree_test_data)) goto out; - if (!do_register (tree, path6, FALSE, 6, tree_test_data)) + if (!do_register (tree, path6, FALSE, 5, tree_test_data)) goto out; - if (!do_register (tree, path7, TRUE, 7, tree_test_data)) + if (!do_register (tree, path7, TRUE, 6, tree_test_data)) goto out; - if (!do_register (tree, path8, TRUE, 8, tree_test_data)) + if (!do_register (tree, path8, TRUE, 7, tree_test_data)) goto out; #if 0 spew_tree (tree); #endif - - if (!do_test_dispatch (tree, path0, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) - goto out; - if (!do_test_dispatch (tree, path1, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + + if (!do_test_dispatch (tree, path1, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path2, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path2, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path3, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path3, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path4, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path4, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path5, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path5, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path6, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path6, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path7, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path7, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path8, 8, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path8, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; out: diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c index 546f42a6..3844e473 100644 --- a/dbus/dbus-pending-call.c +++ b/dbus/dbus-pending-call.c @@ -290,6 +290,24 @@ dbus_pending_call_steal_reply (DBusPendingCall *pending) return message; } +/** + * Gets the reply, or returns #NULL if none has been received yet. The + * reference count is not incremented on the returned message, so you + * have to keep a reference count on the pending call (or add one + * to the message). + * + * @todo not thread safe? I guess it has to lock though it sucks + * @todo maybe to make this threadsafe, it should be steal_reply(), i.e. only one thread can ever get the message + * + * @param pending the pending call + * @returns the reply message or #NULL. + */ +DBusMessage* +dbus_pending_call_get_reply (DBusPendingCall *pending) +{ + return pending->reply; +} + /** * Block until the pending call is completed. The blocking is as with * dbus_connection_send_with_reply_and_block(); it does not enter the diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h index 7d09f64b..c8aa8601 100644 --- a/dbus/dbus-server-protected.h +++ b/dbus/dbus-server-protected.h @@ -25,27 +25,15 @@ #include #include -#include #include #include #include #include #include -#include DBUS_BEGIN_DECLS typedef struct DBusServerVTable DBusServerVTable; -typedef union DBusGUID DBusGUID; - -/** - * A server's globally unique ID - */ -union DBusGUID -{ - dbus_uint32_t as_uint32s[4]; - unsigned char as_bytes[16]; -}; /** * Virtual table to be implemented by all server "subclasses" @@ -67,11 +55,6 @@ struct DBusServer DBusAtomic refcount; /**< Reference count. */ const DBusServerVTable *vtable; /**< Virtual methods for this instance. */ DBusMutex *mutex; /**< Lock on the server object */ - - DBusGUID guid; /**< Globally unique ID of server */ - - DBusString guid_hex; /**< Hex-encoded version of GUID */ - DBusWatchList *watches; /**< Our watches */ DBusTimeoutList *timeouts; /**< Our timeouts */ @@ -119,7 +102,6 @@ void _dbus_server_toggle_timeout (DBusServer *server, dbus_bool_t enabled); void _dbus_server_ref_unlocked (DBusServer *server); -void _dbus_server_unref_unlocked (DBusServer *server); #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(server) @@ -142,14 +124,14 @@ void _dbus_server_unref_unlocked (DBusServer *server); #define SERVER_LOCK(server) do { \ if (TRACE_LOCKS) { _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); } \ - _dbus_mutex_lock ((server)->mutex); \ + dbus_mutex_lock ((server)->mutex); \ TOOK_LOCK_CHECK (server); \ } while (0) #define SERVER_UNLOCK(server) do { \ if (TRACE_LOCKS) { _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); } \ RELEASING_LOCK_CHECK (server); \ - _dbus_mutex_unlock ((server)->mutex); \ + dbus_mutex_unlock ((server)->mutex); \ } while (0) DBUS_END_DECLS diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c index a72bccf1..e6e1c9a3 100644 --- a/dbus/dbus-server-unix.c +++ b/dbus/dbus-server-unix.c @@ -61,12 +61,6 @@ unix_finalize (DBusServer *server) _dbus_server_finalize_base (server); - if (unix_server->watch) - { - _dbus_watch_unref (unix_server->watch); - unix_server->watch = NULL; - } - dbus_free (unix_server->socket_name); dbus_free (server); } @@ -75,9 +69,6 @@ unix_finalize (DBusServer *server) * @todo unreffing the connection at the end may cause * us to drop the last ref to the connection before * disconnecting it. That is invalid. - * - * @todo doesn't this leak a server refcount if - * new_connection_function is NULL? */ /* Return value is just for memory, not other failures. */ static dbus_bool_t @@ -99,7 +90,7 @@ handle_new_client_fd_and_unlock (DBusServer *server, return TRUE; } - transport = _dbus_transport_new_for_fd (client_fd, &server->guid_hex, NULL); + transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL); if (transport == NULL) { close (client_fd); @@ -209,8 +200,6 @@ unix_disconnect (DBusServer *server) { DBusServerUnix *unix_server = (DBusServerUnix*) server; - HAVE_LOCK_CHECK (server); - if (unix_server->watch) { _dbus_server_remove_watch (server, @@ -228,8 +217,6 @@ unix_disconnect (DBusServer *server) _dbus_string_init_const (&tmp, unix_server->socket_name); _dbus_delete_file (&tmp, NULL); } - - HAVE_LOCK_CHECK (server); } static DBusServerVTable unix_vtable = { @@ -255,13 +242,12 @@ _dbus_server_new_for_fd (int fd, const DBusString *address) { DBusServerUnix *unix_server; - DBusServer *server; DBusWatch *watch; unix_server = dbus_new0 (DBusServerUnix, 1); if (unix_server == NULL) return NULL; - + watch = _dbus_watch_new (fd, DBUS_WATCH_READABLE, TRUE, @@ -281,25 +267,26 @@ _dbus_server_new_for_fd (int fd, return NULL; } - server = (DBusServer*) unix_server; - - SERVER_LOCK (server); +#ifndef DBUS_DISABLE_CHECKS + unix_server->base.have_server_lock = TRUE; +#endif if (!_dbus_server_add_watch (&unix_server->base, watch)) { - SERVER_UNLOCK (server); _dbus_server_finalize_base (&unix_server->base); _dbus_watch_unref (watch); dbus_free (unix_server); return NULL; } + +#ifndef DBUS_DISABLE_CHECKS + unix_server->base.have_server_lock = FALSE; +#endif unix_server->fd = fd; unix_server->watch = watch; - SERVER_UNLOCK (server); - return (DBusServer*) unix_server; } @@ -321,7 +308,6 @@ _dbus_server_new_for_domain_socket (const char *path, int listen_fd; DBusString address; char *path_copy; - DBusString path_str; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -331,12 +317,11 @@ _dbus_server_new_for_domain_socket (const char *path, return NULL; } - _dbus_string_init_const (&path_str, path); if ((abstract && !_dbus_string_append (&address, "unix:abstract=")) || (!abstract && !_dbus_string_append (&address, "unix:path=")) || - !_dbus_address_append_escaped (&address, &path_str)) + !_dbus_string_append (&address, path)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_0; @@ -399,7 +384,6 @@ _dbus_server_new_for_tcp_socket (const char *host, DBusServer *server; int listen_fd; DBusString address; - DBusString host_str; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -412,9 +396,8 @@ _dbus_server_new_for_tcp_socket (const char *host, if (host == NULL) host = "localhost"; - _dbus_string_init_const (&host_str, host); if (!_dbus_string_append (&address, "tcp:host=") || - !_dbus_address_append_escaped (&address, &host_str) || + !_dbus_string_append (&address, host) || !_dbus_string_append (&address, ",port=") || !_dbus_string_append_int (&address, port)) { diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 0a3b522d..788aaad7 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ /* dbus-server.c DBusServer object * - * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc. + * Copyright (C) 2002, 2003, 2004 Red Hat Inc. * * Licensed under the Academic Free License version 2.1 * @@ -52,55 +52,6 @@ * @{ */ -static void -init_guid (DBusGUID *guid) -{ - long now; - char *p; - int ts_size; - - _dbus_get_current_time (&now, NULL); - - guid->as_uint32s[0] = now; - - ts_size = sizeof (guid->as_uint32s[0]); - p = ((char*)guid->as_bytes) + ts_size; - - _dbus_generate_random_bytes_buffer (p, - sizeof (guid->as_bytes) - ts_size); -} - -/* this is a little fragile since it assumes the address doesn't - * already have a guid, but it shouldn't - */ -static char* -copy_address_with_guid_appended (const DBusString *address, - const DBusString *guid_hex) -{ - DBusString with_guid; - char *retval; - - if (!_dbus_string_init (&with_guid)) - return NULL; - - if (!_dbus_string_copy (address, 0, &with_guid, - _dbus_string_get_length (&with_guid)) || - !_dbus_string_append (&with_guid, ",guid=") || - !_dbus_string_copy (guid_hex, 0, - &with_guid, _dbus_string_get_length (&with_guid))) - { - _dbus_string_free (&with_guid); - return NULL; - } - - retval = NULL; - _dbus_string_steal_data (&with_guid, &retval); - - _dbus_string_free (&with_guid); - - return retval; /* may be NULL if steal_data failed */ -} - /** * Initializes the members of the DBusServer base class. * Chained up to by subclass constructors. @@ -115,33 +66,17 @@ _dbus_server_init_base (DBusServer *server, const DBusServerVTable *vtable, const DBusString *address) { - DBusString guid_raw; - server->vtable = vtable; server->refcount.value = 1; server->address = NULL; server->watches = NULL; server->timeouts = NULL; - - if (!_dbus_string_init (&server->guid_hex)) - return FALSE; - - init_guid (&server->guid); - - _dbus_string_init_const_len (&guid_raw, server->guid.as_bytes, - sizeof (server->guid.as_bytes)); - if (!_dbus_string_hex_encode (&guid_raw, 0, - &server->guid_hex, - _dbus_string_get_length (&server->guid_hex))) - goto failed; - server->address = copy_address_with_guid_appended (address, - &server->guid_hex); - if (server->address == NULL) + if (!_dbus_string_copy_data (address, &server->address)) goto failed; - - server->mutex = _dbus_mutex_new (); + + server->mutex = dbus_mutex_new (); if (server->mutex == NULL) goto failed; @@ -162,7 +97,7 @@ _dbus_server_init_base (DBusServer *server, failed: if (server->mutex) { - _dbus_mutex_free (server->mutex); + dbus_mutex_free (server->mutex); server->mutex = NULL; } if (server->watches) @@ -180,7 +115,6 @@ _dbus_server_init_base (DBusServer *server, dbus_free (server->address); server->address = NULL; } - _dbus_string_free (&server->guid_hex); return FALSE; } @@ -193,87 +127,23 @@ _dbus_server_init_base (DBusServer *server, */ void _dbus_server_finalize_base (DBusServer *server) -{ - /* We don't have the lock, but nobody should be accessing - * concurrently since they don't have a ref - */ -#ifndef DBUS_DISABLE_CHECKS - _dbus_assert (!server->have_server_lock); -#endif - _dbus_assert (server->disconnected); - +{ /* calls out to application code... */ _dbus_data_slot_list_free (&server->slot_list); dbus_server_set_new_connection_function (server, NULL, NULL, NULL); + if (!server->disconnected) + dbus_server_disconnect (server); + _dbus_watch_list_free (server->watches); _dbus_timeout_list_free (server->timeouts); - _dbus_mutex_free (server->mutex); + dbus_mutex_free (server->mutex); dbus_free (server->address); dbus_free_string_array (server->auth_mechanisms); - - _dbus_string_free (&server->guid_hex); -} - - -typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list, - DBusWatch *watch); -typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list, - DBusWatch *watch); -typedef void (* DBusWatchToggleFunction) (DBusWatchList *list, - DBusWatch *watch, - dbus_bool_t enabled); - -static dbus_bool_t -protected_change_watch (DBusServer *server, - DBusWatch *watch, - DBusWatchAddFunction add_function, - DBusWatchRemoveFunction remove_function, - DBusWatchToggleFunction toggle_function, - dbus_bool_t enabled) -{ - DBusWatchList *watches; - dbus_bool_t retval; - - HAVE_LOCK_CHECK (server); - - /* This isn't really safe or reasonable; a better pattern is the "do - * everything, then drop lock and call out" one; but it has to be - * propagated up through all callers - */ - - watches = server->watches; - if (watches) - { - server->watches = NULL; - _dbus_server_ref_unlocked (server); - SERVER_UNLOCK (server); - - if (add_function) - retval = (* add_function) (watches, watch); - else if (remove_function) - { - retval = TRUE; - (* remove_function) (watches, watch); - } - else - { - retval = TRUE; - (* toggle_function) (watches, watch, enabled); - } - - SERVER_LOCK (server); - server->watches = watches; - _dbus_server_unref_unlocked (server); - - return retval; - } - else - return FALSE; } /** @@ -288,9 +158,7 @@ _dbus_server_add_watch (DBusServer *server, DBusWatch *watch) { HAVE_LOCK_CHECK (server); - return protected_change_watch (server, watch, - _dbus_watch_list_add_watch, - NULL, NULL, FALSE); + return _dbus_watch_list_add_watch (server->watches, watch); } /** @@ -304,10 +172,7 @@ _dbus_server_remove_watch (DBusServer *server, DBusWatch *watch) { HAVE_LOCK_CHECK (server); - protected_change_watch (server, watch, - NULL, - _dbus_watch_list_remove_watch, - NULL, FALSE); + _dbus_watch_list_remove_watch (server->watches, watch); } /** @@ -324,70 +189,11 @@ _dbus_server_toggle_watch (DBusServer *server, DBusWatch *watch, dbus_bool_t enabled) { - _dbus_assert (watch != NULL); - HAVE_LOCK_CHECK (server); - protected_change_watch (server, watch, - NULL, NULL, - _dbus_watch_list_toggle_watch, - enabled); -} - - -typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list, - DBusTimeout *timeout); -typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list, - DBusTimeout *timeout); -typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list, - DBusTimeout *timeout, - dbus_bool_t enabled); - - -static dbus_bool_t -protected_change_timeout (DBusServer *server, - DBusTimeout *timeout, - DBusTimeoutAddFunction add_function, - DBusTimeoutRemoveFunction remove_function, - DBusTimeoutToggleFunction toggle_function, - dbus_bool_t enabled) -{ - DBusTimeoutList *timeouts; - dbus_bool_t retval; - HAVE_LOCK_CHECK (server); - - /* This isn't really safe or reasonable; a better pattern is the "do everything, then - * drop lock and call out" one; but it has to be propagated up through all callers - */ - - timeouts = server->timeouts; - if (timeouts) - { - server->timeouts = NULL; - _dbus_server_ref_unlocked (server); - SERVER_UNLOCK (server); - - if (add_function) - retval = (* add_function) (timeouts, timeout); - else if (remove_function) - { - retval = TRUE; - (* remove_function) (timeouts, timeout); - } - else - { - retval = TRUE; - (* toggle_function) (timeouts, timeout, enabled); - } - - SERVER_LOCK (server); - server->timeouts = timeouts; - _dbus_server_unref_unlocked (server); - - return retval; - } - else - return FALSE; + if (server->watches) /* null during finalize */ + _dbus_watch_list_toggle_watch (server->watches, + watch, enabled); } /** @@ -403,9 +209,9 @@ dbus_bool_t _dbus_server_add_timeout (DBusServer *server, DBusTimeout *timeout) { - return protected_change_timeout (server, timeout, - _dbus_timeout_list_add_timeout, - NULL, NULL, FALSE); + HAVE_LOCK_CHECK (server); + + return _dbus_timeout_list_add_timeout (server->timeouts, timeout); } /** @@ -418,10 +224,9 @@ void _dbus_server_remove_timeout (DBusServer *server, DBusTimeout *timeout) { - protected_change_timeout (server, timeout, - NULL, - _dbus_timeout_list_remove_timeout, - NULL, FALSE); + HAVE_LOCK_CHECK (server); + + _dbus_timeout_list_remove_timeout (server->timeouts, timeout); } /** @@ -438,10 +243,11 @@ _dbus_server_toggle_timeout (DBusServer *server, DBusTimeout *timeout, dbus_bool_t enabled) { - protected_change_timeout (server, timeout, - NULL, NULL, - _dbus_timeout_list_toggle_timeout, - enabled); + HAVE_LOCK_CHECK (server); + + if (server->timeouts) /* null during finalize */ + _dbus_timeout_list_toggle_timeout (server->timeouts, + timeout, enabled); } @@ -506,9 +312,7 @@ dbus_server_listen (const char *address, for (i = 0; i < len; i++) { - const char *method; - - method = dbus_address_entry_get_method (entries[i]); + const char *method = dbus_address_entry_get_method (entries[i]); if (strcmp (method, "unix") == 0) { @@ -674,7 +478,6 @@ DBusServer * dbus_server_ref (DBusServer *server) { _dbus_return_val_if_fail (server != NULL, NULL); - _dbus_return_val_if_fail (server->refcount.value > 0, NULL); #ifdef DBUS_HAVE_ATOMIC_INT _dbus_atomic_inc (&server->refcount); @@ -691,9 +494,9 @@ dbus_server_ref (DBusServer *server) /** * Decrements the reference count of a DBusServer. Finalizes the - * server if the reference count reaches zero. - * - * The server must be disconnected before the refcount reaches zero. + * server if the reference count reaches zero. The server connection + * will be closed as with dbus_server_disconnect() when the server is + * finalized. * * @param server the server. */ @@ -703,7 +506,6 @@ dbus_server_unref (DBusServer *server) dbus_bool_t last_unref; _dbus_return_if_fail (server != NULL); - _dbus_return_if_fail (server->refcount.value > 0); #ifdef DBUS_HAVE_ATOMIC_INT last_unref = (_dbus_atomic_dec (&server->refcount) == 1); @@ -720,9 +522,6 @@ dbus_server_unref (DBusServer *server) if (last_unref) { - /* lock not held! */ - _dbus_assert (server->disconnected); - _dbus_assert (server->vtable->finalize != NULL); (* server->vtable->finalize) (server); @@ -737,9 +536,6 @@ dbus_server_unref (DBusServer *server) void _dbus_server_ref_unlocked (DBusServer *server) { - _dbus_assert (server != NULL); - _dbus_assert (server->refcount.value > 0); - HAVE_LOCK_CHECK (server); #ifdef DBUS_HAVE_ATOMIC_INT @@ -751,42 +547,6 @@ _dbus_server_ref_unlocked (DBusServer *server) #endif } -/** - * Like dbus_server_unref() but does not acquire the lock (must already be held) - * - * @param server the server. - */ -void -_dbus_server_unref_unlocked (DBusServer *server) -{ - dbus_bool_t last_unref; - - _dbus_assert (server != NULL); - _dbus_assert (server->refcount.value > 0); - - HAVE_LOCK_CHECK (server); - -#ifdef DBUS_HAVE_ATOMIC_INT - last_unref = (_dbus_atomic_dec (&server->refcount) == 1); -#else - _dbus_assert (server->refcount.value > 0); - - server->refcount.value -= 1; - last_unref = (server->refcount.value == 0); -#endif - - if (last_unref) - { - _dbus_assert (server->disconnected); - - SERVER_UNLOCK (server); - - _dbus_assert (server->vtable->finalize != NULL); - - (* server->vtable->finalize) (server); - } -} - /** * Releases the server's address and stops listening for * new clients. If called more than once, only the first @@ -799,23 +559,18 @@ void dbus_server_disconnect (DBusServer *server) { _dbus_return_if_fail (server != NULL); - _dbus_return_if_fail (server->refcount.value > 0); SERVER_LOCK (server); - _dbus_server_ref_unlocked (server); _dbus_assert (server->vtable->disconnect != NULL); - if (!server->disconnected) - { - /* this has to be first so recursive calls to disconnect don't happen */ - server->disconnected = TRUE; - - (* server->vtable->disconnect) (server); - } + if (server->disconnected) + return; + + (* server->vtable->disconnect) (server); + server->disconnected = TRUE; SERVER_UNLOCK (server); - dbus_server_unref (server); } /** @@ -1180,7 +935,6 @@ _dbus_server_test (void) if (server == NULL) _dbus_assert_not_reached ("Failed to listen for valid address."); - dbus_server_disconnect (server); dbus_server_unref (server); /* Try disconnecting before unreffing */ @@ -1189,6 +943,7 @@ _dbus_server_test (void) _dbus_assert_not_reached ("Failed to listen for valid address."); dbus_server_disconnect (server); + dbus_server_unref (server); } diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c index 4c07d5f3..2959886a 100644 --- a/dbus/dbus-transport-unix.c +++ b/dbus/dbus-transport-unix.c @@ -1114,13 +1114,13 @@ static DBusTransportVTable unix_vtable = { * boil down to a full duplex file descriptor. * * @param fd the file descriptor. - * @param server_guid non-#NULL if this transport is on the server side of a connection + * @param server #TRUE if this transport is on the server side of a connection * @param address the transport's address * @returns the new transport, or #NULL if no memory. */ DBusTransport* _dbus_transport_new_for_fd (int fd, - const DBusString *server_guid, + dbus_bool_t server, const DBusString *address) { DBusTransportUnix *unix_transport; @@ -1151,7 +1151,7 @@ _dbus_transport_new_for_fd (int fd, if (!_dbus_transport_init_base (&unix_transport->base, &unix_vtable, - server_guid, address)) + server, address)) goto failed_4; unix_transport->fd = fd; diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index b271d944..59eb8e44 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -75,22 +75,19 @@ live_messages_size_notify (DBusCounter *counter, } /** - * Initializes the base class members of DBusTransport. Chained up to - * by subclasses in their constructor. The server GUID is the - * globally unique ID for the server creating this connection - * and will be #NULL for the client side of a connection. The GUID - * is in hex format. + * Initializes the base class members of DBusTransport. + * Chained up to by subclasses in their constructor. * * @param transport the transport being created. * @param vtable the subclass vtable. - * @param server_guid non-#NULL if this transport is on the server side of a connection + * @param server #TRUE if this transport is on the server side of a connection * @param address the address of the transport * @returns #TRUE on success. */ dbus_bool_t _dbus_transport_init_base (DBusTransport *transport, const DBusTransportVTable *vtable, - const DBusString *server_guid, + dbus_bool_t server, const DBusString *address) { DBusMessageLoader *loader; @@ -102,8 +99,8 @@ _dbus_transport_init_base (DBusTransport *transport, if (loader == NULL) return FALSE; - if (server_guid) - auth = _dbus_auth_server_new (server_guid); + if (server) + auth = _dbus_auth_server_new (); else auth = _dbus_auth_client_new (); if (auth == NULL) @@ -120,7 +117,7 @@ _dbus_transport_init_base (DBusTransport *transport, return FALSE; } - if (server_guid) + if (server) { _dbus_assert (address == NULL); address_copy = NULL; @@ -145,9 +142,9 @@ _dbus_transport_init_base (DBusTransport *transport, transport->live_messages_size = counter; transport->authenticated = FALSE; transport->disconnected = FALSE; - transport->is_server = (server_guid != NULL); - transport->send_credentials_pending = !transport->is_server; - transport->receive_credentials_pending = transport->is_server; + transport->send_credentials_pending = !server; + transport->receive_credentials_pending = server; + transport->is_server = server; transport->address = address_copy; transport->unix_user_function = NULL; @@ -198,22 +195,33 @@ _dbus_transport_finalize_base (DBusTransport *transport) } /** - * Try to open a new transport for the given address entry. (This - * opens a client-side-of-the-connection transport.) + * Opens a new transport for the given address. (This opens a + * client-side-of-the-connection transport.) + * + * @todo error messages on bad address could really be better. + * DBusResultCode is a bit limiting here. * - * @param entry the address entry + * @param address the address. * @param error location to store reason for failure. * @returns new transport of #NULL on failure. */ DBusTransport* -_dbus_transport_open (DBusAddressEntry *entry, - DBusError *error) +_dbus_transport_open (const char *address, + DBusError *error) { DBusTransport *transport; + DBusAddressEntry **entries; + DBusError tmp_error; + DBusError first_error; + int len, i; const char *address_problem_type; const char *address_problem_field; const char *address_problem_other; - const char *method; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (!dbus_parse_address (address, &entries, &len, error)) + return NULL; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -221,96 +229,125 @@ _dbus_transport_open (DBusAddressEntry *entry, address_problem_type = NULL; address_problem_field = NULL; address_problem_other = NULL; - - method = dbus_address_entry_get_method (entry); - _dbus_assert (method != NULL); - - if (strcmp (method, "unix") == 0) + + dbus_error_init (&tmp_error); + dbus_error_init (&first_error); + for (i = 0; i < len; i++) { - const char *path = dbus_address_entry_get_value (entry, "path"); - const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir"); - const char *abstract = dbus_address_entry_get_value (entry, "abstract"); + const char *method; + + method = dbus_address_entry_get_method (entries[i]); + + if (strcmp (method, "unix") == 0) + { + const char *path = dbus_address_entry_get_value (entries[i], "path"); + const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir"); + const char *abstract = dbus_address_entry_get_value (entries[i], "abstract"); - if (tmpdir != NULL) - { - address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on"; - goto bad_address; - } + if (tmpdir != NULL) + { + address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on"; + goto bad_address; + } - if (path == NULL && abstract == NULL) - { - address_problem_type = "unix"; - address_problem_field = "path or abstract"; - goto bad_address; - } + if (path == NULL && abstract == NULL) + { + address_problem_type = "unix"; + address_problem_field = "path or abstract"; + goto bad_address; + } - if (path != NULL && abstract != NULL) - { - address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address"; - goto bad_address; - } + if (path != NULL && abstract != NULL) + { + address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address"; + goto bad_address; + } - if (path) - transport = _dbus_transport_new_for_domain_socket (path, FALSE, - error); - else - transport = _dbus_transport_new_for_domain_socket (abstract, TRUE, - error); - } - else if (strcmp (method, "tcp") == 0) - { - const char *host = dbus_address_entry_get_value (entry, "host"); - const char *port = dbus_address_entry_get_value (entry, "port"); - DBusString str; - long lport; - dbus_bool_t sresult; + if (path) + transport = _dbus_transport_new_for_domain_socket (path, FALSE, + &tmp_error); + else + transport = _dbus_transport_new_for_domain_socket (abstract, TRUE, + &tmp_error); + } + else if (strcmp (method, "tcp") == 0) + { + const char *host = dbus_address_entry_get_value (entries[i], "host"); + const char *port = dbus_address_entry_get_value (entries[i], "port"); + DBusString str; + long lport; + dbus_bool_t sresult; - if (port == NULL) - { - address_problem_type = "tcp"; - address_problem_field = "port"; - goto bad_address; - } + if (port == NULL) + { + address_problem_type = "tcp"; + address_problem_field = "port"; + goto bad_address; + } - _dbus_string_init_const (&str, port); - sresult = _dbus_string_parse_int (&str, 0, &lport, NULL); - _dbus_string_free (&str); + _dbus_string_init_const (&str, port); + sresult = _dbus_string_parse_int (&str, 0, &lport, NULL); + _dbus_string_free (&str); - if (sresult == FALSE || lport <= 0 || lport > 65535) - { - address_problem_other = "Port is not an integer between 0 and 65535"; - goto bad_address; - } + if (sresult == FALSE || lport <= 0 || lport > 65535) + { + address_problem_other = "Port is not an integer between 0 and 65535"; + goto bad_address; + } - transport = _dbus_transport_new_for_tcp_socket (host, lport, error); - } + transport = _dbus_transport_new_for_tcp_socket (host, lport, &tmp_error); + } #ifdef DBUS_BUILD_TESTS - else if (strcmp (method, "debug-pipe") == 0) - { - const char *name = dbus_address_entry_get_value (entry, "name"); + else if (strcmp (method, "debug-pipe") == 0) + { + const char *name = dbus_address_entry_get_value (entries[i], "name"); - if (name == NULL) + if (name == NULL) + { + address_problem_type = "debug-pipe"; + address_problem_field = "name"; + goto bad_address; + } + + transport = _dbus_transport_debug_pipe_new (name, &tmp_error); + } +#endif + else { - address_problem_type = "debug-pipe"; - address_problem_field = "name"; + address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")"; goto bad_address; } - - transport = _dbus_transport_debug_pipe_new (name, error); + + if (transport) + break; + + _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); + + if (i == 0) + dbus_move_error (&tmp_error, &first_error); + else + dbus_error_free (&tmp_error); + } + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error); + + if (transport == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (&first_error); + dbus_move_error (&first_error, error); } -#endif else { - address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")"; - goto bad_address; + dbus_error_free (&first_error); } - - if (transport == NULL) - _DBUS_ASSERT_ERROR_IS_SET (error); + dbus_address_entries_free (entries); return transport; - + bad_address: + dbus_address_entries_free (entries); + if (address_problem_type != NULL) dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Address of type %s was missing argument %s", @@ -916,10 +953,10 @@ _dbus_transport_get_unix_user (DBusTransport *transport, { DBusCredentials auth_identity; - *uid = _DBUS_INT32_MAX; /* better than some root or system user in - * case of bugs in the caller. Caller should - * never use this value on purpose, however. - */ + *uid = _DBUS_INT_MAX; /* better than some root or system user in + * case of bugs in the caller. Caller should + * never use this value on purpose, however. + */ if (!transport->authenticated) return FALSE; -- cgit