From 51781f541094a4936d47119cd62682e0431c41e9 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Thu, 10 Apr 2003 05:12:19 +0000 Subject: 2003-04-10 Havoc Pennington * bus/dispatch.c: lots of fixes * dbus/dbus-mainloop.c (_dbus_loop_dispatch): export (_dbus_loop_iterate): remove old "quit if no callbacks" code, that was crack, broke the test service. * dbus/dbus-transport.c (_dbus_transport_open): fix error handling to avoid piling up errors if we get a failure on the first address. * dbus/dbus-internals.c (_dbus_real_assert_not_reached): include pid in assertion failures. * dbus/dbus-mainloop.c (_dbus_loop_iterate): use static arrays up to some fixed size of file descriptor array. Don't return TRUE anytime a timeout exists, that led to lots of busy loop silliness in the tests. --- bus/activation.c | 2 + bus/connection.c | 10 +- bus/dispatch.c | 308 ++++++++++++++++++++++++++++++++++++------------------- bus/driver.c | 3 +- bus/test.c | 10 ++ 5 files changed, 223 insertions(+), 110 deletions(-) (limited to 'bus') diff --git a/bus/activation.c b/bus/activation.c index 8ecf6ecb..13c147ea 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -722,6 +722,8 @@ bus_activation_activate_service (BusActivation *activation, _dbus_string_init_const (&service_str, service_name); if (bus_registry_lookup (bus_context_get_registry (activation->context), &service_str) != NULL) { + _dbus_verbose ("Service \"%s\" is already active\n", service_name); + message = dbus_message_new_reply (activation_message); if (!message) diff --git a/bus/connection.c b/bus/connection.c index aeb4f6e0..80a9ae7a 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -193,7 +193,10 @@ connection_watch_callback (DBusWatch *watch, { DBusConnection *connection = data; dbus_bool_t retval; - + +#if 0 + _dbus_verbose ("Calling handle_watch\n"); +#endif retval = dbus_connection_handle_watch (connection, watch, condition); return retval; @@ -863,7 +866,10 @@ bus_transaction_send_message (BusTransaction *transaction, BusConnectionData *d; DBusList *link; - _dbus_verbose (" trying to add message %s to transaction%s\n", + _dbus_verbose (" trying to add %s %s to transaction%s\n", + dbus_message_get_is_error (message) ? "error" : + dbus_message_get_reply_serial (message) != 0 ? "reply" : + "message", dbus_message_get_name (message), dbus_connection_get_is_connected (connection) ? "" : " (disconnected)"); diff --git a/bus/dispatch.c b/bus/dispatch.c index 43fccdc9..e867674b 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -451,6 +451,30 @@ typedef dbus_bool_t (* Check2Func) (BusContext *context, static dbus_bool_t check_no_leftovers (BusContext *context); +static void +block_connection_until_message_from_bus (BusContext *context, + DBusConnection *connection) +{ + while (dbus_connection_get_dispatch_status (connection) == + DBUS_DISPATCH_COMPLETE && + dbus_connection_get_is_connected (connection)) + { + bus_test_run_bus_loop (context, TRUE); + bus_test_run_clients_loop (FALSE); + } +} + +/* compensate for fact that pop_message() can return #NULL due to OOM */ +static DBusMessage* +pop_message_waiting_for_memory (DBusConnection *connection) +{ + while (dbus_connection_get_dispatch_status (connection) == + DBUS_DISPATCH_NEED_MEMORY) + _dbus_wait_for_memory (); + + return dbus_connection_pop_message (connection); +} + typedef struct { const char *expected_service_name; @@ -470,7 +494,7 @@ check_service_deleted_foreach (DBusConnection *connection, d->failed = TRUE; service_name = NULL; - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Did not receive a message on %p, expecting %s\n", @@ -600,7 +624,7 @@ check_no_messages_foreach (DBusConnection *connection, CheckNoMessagesData *d = data; DBusMessage *message; - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message != NULL) { _dbus_warn ("Received message %s on %p, expecting no messages\n", @@ -636,7 +660,7 @@ check_service_created_foreach (DBusConnection *connection, d->failed = TRUE; service_name = NULL; - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Did not receive a message on %p, expecting %s\n", @@ -746,7 +770,7 @@ check_hello_message (BusContext *context, retval = FALSE; - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Did not receive a reply to %s %d on %p\n", @@ -831,7 +855,7 @@ check_hello_message (BusContext *context, /* Client should also have gotten ServiceAcquired */ dbus_message_unref (message); - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Expecting %s, got nothing\n", @@ -970,6 +994,8 @@ check_nonexistent_service_activation (BusContext *context, dbus_message_unref (message); message = NULL; + bus_test_run_everything (context); + block_connection_until_message_from_bus (context, connection); bus_test_run_everything (context); if (!dbus_connection_get_is_connected (connection)) @@ -980,7 +1006,7 @@ check_nonexistent_service_activation (BusContext *context, retval = FALSE; - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Did not receive a reply to %s %d on %p\n", @@ -1057,16 +1083,26 @@ check_base_service_activated (BusContext *context, { char *service_name; CheckServiceCreatedData scd; - + + reget_service_name_arg: if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service_name, DBUS_TYPE_INVALID)) { - _dbus_warn ("Message %s doesn't have a service name: %s\n", - dbus_message_get_name (message), - error.message); - dbus_error_free (&error); - goto out; + if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) + { + dbus_error_free (&error); + _dbus_wait_for_memory (); + goto reget_service_name_arg; + } + else + { + _dbus_warn ("Message %s doesn't have a service name: %s\n", + dbus_message_get_name (message), + error.message); + dbus_error_free (&error); + goto out; + } } if (*service_name != ':') @@ -1088,6 +1124,12 @@ check_base_service_activated (BusContext *context, if (scd.failed) goto out; } + else + { + _dbus_warn ("Expected to get base service ServiceCreated, instead got %s\n", + dbus_message_get_name (message)); + goto out; + } retval = TRUE; @@ -1130,16 +1172,26 @@ check_service_activated (BusContext *context, { char *service_name; CheckServiceCreatedData scd; - + + reget_service_name_arg: if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service_name, DBUS_TYPE_INVALID)) { - _dbus_warn ("Message %s doesn't have a service name: %s\n", - dbus_message_get_name (message), - error.message); - dbus_error_free (&error); - goto out; + if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) + { + dbus_error_free (&error); + _dbus_wait_for_memory (); + goto reget_service_name_arg; + } + else + { + _dbus_warn ("Message %s doesn't have a service name: %s\n", + dbus_message_get_name (message), + error.message); + dbus_error_free (&error); + goto out; + } } if (strcmp (service_name, activated_name) != 0) @@ -1162,7 +1214,7 @@ check_service_activated (BusContext *context, goto out; dbus_message_unref (message); - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Expected a reply to %s, got nothing\n", @@ -1170,7 +1222,13 @@ check_service_activated (BusContext *context, goto out; } } - + else + { + _dbus_warn ("Expected to get service %s ServiceCreated, instead got %s\n", + activated_name, dbus_message_get_name (message)); + goto out; + } + if (!dbus_message_name_is (message, DBUS_MESSAGE_ACTIVATE_SERVICE)) { _dbus_warn ("Expected reply to %s, got message %s instead\n", @@ -1277,6 +1335,113 @@ check_service_deactivated (BusContext *context, return retval; } +static dbus_bool_t +check_send_exit_to_service (BusContext *context, + DBusConnection *connection, + const char *service_name, + const char *base_service) +{ + dbus_bool_t got_error; + DBusMessage *message; + dbus_int32_t serial; + dbus_bool_t retval; + + _dbus_verbose ("Sending exit message to the test service\n"); + + retval = FALSE; + + /* Kill off the test service by sending it a quit message */ + message = dbus_message_new (service_name, + "org.freedesktop.DBus.TestSuiteExit"); + + if (message == NULL) + { + /* Do this again; we still need the service to exit... */ + if (!check_send_exit_to_service (context, connection, + service_name, base_service)) + goto out; + + return TRUE; + } + + if (!dbus_connection_send (connection, message, &serial)) + { + dbus_message_unref (message); + + /* Do this again; we still need the service to exit... */ + if (!check_send_exit_to_service (context, connection, + service_name, base_service)) + goto out; + + return TRUE; + } + + dbus_message_unref (message); + message = NULL; + + /* send message */ + bus_test_run_clients_loop (TRUE); + + /* read it in and write it out to test service */ + bus_test_run_bus_loop (context, FALSE); + + /* see if we got an error during message bus dispatching */ + bus_test_run_clients_loop (FALSE); + message = dbus_connection_borrow_message (connection); + got_error = message != NULL && dbus_message_get_is_error (message); + if (message) + dbus_connection_return_message (connection, message); + + if (!got_error) + { + /* If no error, wait for the test service to exit */ + block_connection_until_message_from_bus (context, connection); + + bus_test_run_everything (context); + } + + if (got_error) + { + message = pop_message_waiting_for_memory (connection); + _dbus_assert (message != NULL); + + if (!dbus_message_get_is_error (message)) + { + _dbus_warn ("expecting an error reply to asking test service to exit, got %s\n", + dbus_message_get_name (message)); + goto out; + } + else if (!dbus_message_name_is (message, DBUS_ERROR_NO_MEMORY)) + { + _dbus_warn ("not expecting error %s when asking test service to exit\n", + dbus_message_get_name (message)); + goto out; + } + + _dbus_verbose ("Got error %s when asking test service to exit\n", + dbus_message_get_name (message)); + + /* Do this again; we still need the service to exit... */ + if (!check_send_exit_to_service (context, connection, + service_name, base_service)) + goto out; + } + else + { + if (!check_service_deactivated (context, connection, + service_name, base_service)) + goto out; + } + + retval = TRUE; + + out: + if (message) + dbus_message_unref (message); + + return retval; +} + #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService" /* returns TRUE if the correct thing happens, @@ -1322,12 +1487,11 @@ check_existent_service_activation (BusContext *context, bus_test_run_everything (context); - if (dbus_connection_get_dispatch_status (connection) == - DBUS_DISPATCH_COMPLETE) - /* now wait for the message bus to hear back from the activated service */ - bus_test_run_bus_loop (context, TRUE); - - /* and process everything again */ + /* now wait for the message bus to hear back from the activated + * service. + */ + block_connection_until_message_from_bus (context, connection); + bus_test_run_everything (context); if (!dbus_connection_get_is_connected (connection)) @@ -1338,7 +1502,7 @@ check_existent_service_activation (BusContext *context, retval = FALSE; - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Did not receive any messages after %s %d on %p\n", @@ -1346,8 +1510,9 @@ check_existent_service_activation (BusContext *context, goto out; } - _dbus_verbose ("Received %s on %p\n", - dbus_message_get_name (message), connection); + _dbus_verbose ("Received %s on %p after sending %s\n", + dbus_message_get_name (message), connection, + DBUS_MESSAGE_ACTIVATE_SERVICE); if (dbus_message_get_is_error (message)) { @@ -1395,9 +1560,7 @@ check_existent_service_activation (BusContext *context, message = NULL; /* We may need to block here for the test service to exit or finish up */ - if (dbus_connection_get_dispatch_status (connection) == - DBUS_DISPATCH_COMPLETE) - bus_test_run_bus_loop (context, TRUE); + block_connection_until_message_from_bus (context, connection); message = dbus_connection_borrow_message (connection); if (message == NULL) @@ -1427,15 +1590,12 @@ check_existent_service_activation (BusContext *context, goto out; /* Now we should get an error about the service exiting */ - if (dbus_connection_get_dispatch_status (connection) == - DBUS_DISPATCH_COMPLETE) - /* wait for the message bus to hear back from the activated service exiting */ - bus_test_run_bus_loop (context, TRUE); + block_connection_until_message_from_bus (context, connection); /* and process everything again */ bus_test_run_everything (context); - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Did not get an error from the service %s exiting\n", @@ -1461,9 +1621,7 @@ check_existent_service_activation (BusContext *context, } else { - dbus_bool_t got_error; - - message = dbus_connection_pop_message (connection); + message = pop_message_waiting_for_memory (connection); if (message == NULL) { _dbus_warn ("Failed to pop message we just put back! should have been a ServiceCreated\n"); @@ -1483,74 +1641,10 @@ check_existent_service_activation (BusContext *context, _dbus_warn ("Messages were left over after successful activation\n"); goto out; } - - /* Now kill off the test service by sending it a quit message */ - message = dbus_message_new (EXISTENT_SERVICE_NAME, - "org.freedesktop.DBus.TestSuiteExit"); - - if (message == NULL) - { - dbus_free (base_service); - return TRUE; - } - - if (!dbus_connection_send (connection, message, &serial)) - { - dbus_message_unref (message); - dbus_free (base_service); - return TRUE; - } - - dbus_message_unref (message); - message = NULL; - /* send message */ - bus_test_run_clients_loop (TRUE); - - /* read it in and write it out to test service */ - bus_test_run_bus_loop (context, FALSE); - - /* see if we got an error */ - bus_test_run_clients_loop (FALSE); - message = dbus_connection_borrow_message (connection); - got_error = message != NULL && dbus_message_get_is_error (message); - if (message) - dbus_connection_return_message (connection, message); - - if (!got_error) - { - if (dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_COMPLETE) - /* now wait for the message bus to hear back from the activated service exiting */ - bus_test_run_bus_loop (context, TRUE); - - /* and process everything again */ - bus_test_run_everything (context); - } - - if (got_error) - { - message = dbus_connection_pop_message (connection); - _dbus_assert (message != NULL); - - if (!dbus_message_get_is_error (message)) - { - _dbus_warn ("expecting an error reply to asking test service to exit, got %s\n", - dbus_message_get_name (message)); - goto out; - } - else if (!dbus_message_name_is (message, DBUS_ERROR_NO_MEMORY)) - { - _dbus_warn ("not expecting error %s when asking test service to exit\n", - dbus_message_get_name (message)); - goto out; - } - } - else - { - if (!check_service_deactivated (context, connection, - EXISTENT_SERVICE_NAME, base_service)) - goto out; - } + if (!check_send_exit_to_service (context, connection, + EXISTENT_SERVICE_NAME, base_service)) + goto out; } } diff --git a/bus/driver.c b/bus/driver.c index a3fe7c59..bb8ac296 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -1,7 +1,8 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ /* driver.c Bus client (driver) * - * Copyright (C) 2003 CodeFactory AB + * Copyright (C) 2003 CodeFactory AB + * Copyright (C) 2003 Red Hat, Inc. * * Licensed under the Academic Free License version 1.2 * diff --git a/bus/test.c b/bus/test.c index ded23ba8..c4d999f9 100644 --- a/bus/test.c +++ b/bus/test.c @@ -301,6 +301,11 @@ bus_test_run_clients_loop (dbus_bool_t block_once) { if (client_loop == NULL) return; + + /* dispatch before we block so pending dispatches + * won't make our block return early + */ + _dbus_loop_dispatch (client_loop); /* Do one blocking wait, since we're expecting data */ _dbus_loop_iterate (client_loop, block_once); @@ -314,6 +319,11 @@ void bus_test_run_bus_loop (BusContext *context, dbus_bool_t block_once) { + /* dispatch before we block so pending dispatches + * won't make our block return early + */ + _dbus_loop_dispatch (bus_context_get_loop (context)); + /* Do one blocking wait, since we're expecting data */ _dbus_loop_iterate (bus_context_get_loop (context), block_once); -- cgit