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. --- ChangeLog | 20 +++ bus/activation.c | 2 + bus/connection.c | 10 +- bus/dispatch.c | 308 +++++++++++++++++++++++++++++---------------- bus/driver.c | 3 +- bus/test.c | 10 ++ dbus/dbus-connection.c | 20 +-- dbus/dbus-internals.c | 14 ++- dbus/dbus-mainloop.c | 121 ++++++++++++------ dbus/dbus-mainloop.h | 1 + dbus/dbus-message.c | 12 +- dbus/dbus-transport-unix.c | 35 +++++- dbus/dbus-transport.c | 48 +++++-- test/test-service.c | 5 +- 14 files changed, 432 insertions(+), 177 deletions(-) diff --git a/ChangeLog b/ChangeLog index f27504b1..4222dc62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +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. + 2003-04-09 Havoc Pennington * dbus/dbus-mainloop.c (check_timeout): fix timeouts, I thought 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); diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 3be4ee45..0961e49d 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -313,12 +313,14 @@ _dbus_connection_message_sent (DBusConnection *connection, _dbus_assert (message == _dbus_list_get_last (&connection->outgoing_messages)); _dbus_list_pop_last (&connection->outgoing_messages); - dbus_message_unref (message); connection->n_outgoing -= 1; - _dbus_verbose ("Message %p removed from outgoing queue %p, %d left to send\n", - message, connection, connection->n_outgoing); + _dbus_verbose ("Message %p (%s) removed from outgoing queue %p, %d left to send\n", + message, dbus_message_get_name (message), + connection, connection->n_outgoing); + + dbus_message_unref (message); if (connection->n_outgoing == 0) _dbus_transport_messages_pending (connection->transport, @@ -1721,8 +1723,9 @@ _dbus_connection_pop_message_link_unlocked (DBusConnection *connection) link = _dbus_list_pop_first_link (&connection->incoming_messages); connection->n_incoming -= 1; - _dbus_verbose ("Message %p removed from incoming queue %p, %d incoming\n", - link->data, connection, connection->n_incoming); + _dbus_verbose ("Message %p (%s) removed from incoming queue %p, %d incoming\n", + link->data, dbus_message_get_name (link->data), + connection, connection->n_incoming); return link; } @@ -1777,8 +1780,10 @@ dbus_connection_pop_message (DBusConnection *connection) return NULL; dbus_mutex_lock (connection->mutex); - + message = _dbus_connection_pop_message_unlocked (connection); + + _dbus_verbose ("Returning popped message %p\n", message); dbus_mutex_unlock (connection->mutex); @@ -2065,7 +2070,8 @@ dbus_connection_dispatch (DBusConnection *connection) */ dbus_mutex_unlock (connection->mutex); - _dbus_verbose (" running app handler on message %p\n", message); + _dbus_verbose (" running app handler on message %p (%s)\n", + message, dbus_message_get_name (message)); result = _dbus_message_handler_handle_message (handler, connection, message); diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c index 6a662e5d..230c8efe 100644 --- a/dbus/dbus-internals.c +++ b/dbus/dbus-internals.c @@ -363,8 +363,8 @@ _dbus_real_assert (dbus_bool_t condition, { if (!condition) { - _dbus_warn ("Assertion failed \"%s\" file \"%s\" line %d\n", - condition_text, file, line); + _dbus_warn ("Assertion failed \"%s\" file \"%s\" line %d process %lu\n", + condition_text, file, line, _dbus_getpid ()); _dbus_abort (); } } @@ -384,8 +384,8 @@ _dbus_real_assert_not_reached (const char *explanation, const char *file, int line) { - _dbus_warn ("File \"%s\" line %d should not have been reached: %s\n", - file, line, explanation); + _dbus_warn ("File \"%s\" line %d process %lu should not have been reached: %s\n", + file, line, _dbus_getpid (), explanation); _dbus_abort (); } #endif /* DBUS_DISABLE_ASSERT */ @@ -442,12 +442,14 @@ _dbus_test_oom_handling (const char *description, _dbus_set_fail_alloc_counter (_DBUS_INT_MAX); + _dbus_verbose ("Running once to count mallocs\n"); + if (!(* func) (data)) return FALSE; approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter (); - _dbus_verbose ("=================\n%s: about %d mallocs total\n=================\n", + _dbus_verbose ("\n=================\n%s: about %d mallocs total\n=================\n", description, approx_mallocs); _dbus_set_fail_alloc_failures (1); @@ -466,7 +468,7 @@ _dbus_test_oom_handling (const char *description, if (!run_failing_each_malloc (approx_mallocs, description, func, data)) return FALSE; - _dbus_verbose ("=================\n%s: all iterations passed\n=================\n", + _dbus_verbose ("\n=================\n%s: all iterations passed\n=================\n", description); return TRUE; diff --git a/dbus/dbus-mainloop.c b/dbus/dbus-mainloop.c index 721eedf7..bf011082 100644 --- a/dbus/dbus-mainloop.c +++ b/dbus/dbus-mainloop.c @@ -26,6 +26,8 @@ #include #include +#define MAINLOOP_SPEW 1 + struct DBusLoop { int refcount; @@ -403,21 +405,29 @@ check_timeout (unsigned long tv_sec, *timeout = msec_remaining; -#if 0 - printf ("Timeout expires in %d milliseconds\n", *timeout); +#if MAINLOOP_SPEW + _dbus_verbose (" timeout expires in %d milliseconds\n", *timeout); #endif return msec_remaining == 0; } -static void +dbus_bool_t _dbus_loop_dispatch (DBusLoop *loop) { + +#if MAINLOOP_SPEW + _dbus_verbose (" %d connections to dispatch\n", _dbus_list_get_length (&loop->need_dispatch)); +#endif + + if (loop->need_dispatch == NULL) + return FALSE; + next: while (loop->need_dispatch != NULL) { DBusConnection *connection = _dbus_list_pop_first (&loop->need_dispatch); - + while (TRUE) { DBusDispatchStatus status; @@ -436,13 +446,14 @@ _dbus_loop_dispatch (DBusLoop *loop) } } } + + return TRUE; } dbus_bool_t _dbus_loop_queue_dispatch (DBusLoop *loop, DBusConnection *connection) { - if (_dbus_list_append (&loop->need_dispatch, connection)) { dbus_connection_ref (connection); @@ -459,11 +470,14 @@ _dbus_loop_queue_dispatch (DBusLoop *loop, dbus_bool_t _dbus_loop_iterate (DBusLoop *loop, dbus_bool_t block) -{ +{ +#define N_STATIC_DESCRIPTORS 64 dbus_bool_t retval; DBusPollFD *fds; + DBusPollFD static_fds[N_STATIC_DESCRIPTORS]; int n_fds; WatchCallback **watches_for_fds; + WatchCallback *static_watches_for_fds[N_STATIC_DESCRIPTORS]; int i; DBusList *link; int n_ready; @@ -479,16 +493,13 @@ _dbus_loop_iterate (DBusLoop *loop, oom_watch_pending = FALSE; orig_depth = loop->depth; -#if 0 - _dbus_verbose (" iterate %d timeouts %d watches\n", - loop->timeout_count, loop->watch_count); +#if MAINLOOP_SPEW + _dbus_verbose ("Iteration block=%d depth=%d timeout_count=%d watch_count=%d\n", + block, loop->depth, loop->timeout_count, loop->watch_count); #endif if (loop->callbacks == NULL) - { - _dbus_loop_quit (loop); - goto next_iteration; - } + goto next_iteration; /* count enabled watches */ n_fds = 0; @@ -512,18 +523,30 @@ _dbus_loop_iterate (DBusLoop *loop, /* fill our array of fds and watches */ if (n_fds > 0) { - fds = dbus_new0 (DBusPollFD, n_fds); - while (fds == NULL) + if (n_fds > N_STATIC_DESCRIPTORS) { - _dbus_wait_for_memory (); fds = dbus_new0 (DBusPollFD, n_fds); - } + + while (fds == NULL) + { + _dbus_wait_for_memory (); + fds = dbus_new0 (DBusPollFD, n_fds); + } - watches_for_fds = dbus_new (WatchCallback*, n_fds); - while (watches_for_fds == NULL) - { - _dbus_wait_for_memory (); watches_for_fds = dbus_new (WatchCallback*, n_fds); + while (watches_for_fds == NULL) + { + _dbus_wait_for_memory (); + watches_for_fds = dbus_new (WatchCallback*, n_fds); + } + } + else + { + memset (static_fds, '\0', sizeof (static_fds[0]) * n_fds); + memset (static_watches_for_fds, '\0', sizeof (static_watches_for_fds[0]) * n_fds); + + fds = static_fds; + watches_for_fds = static_watches_for_fds; } i = 0; @@ -544,6 +567,13 @@ _dbus_loop_iterate (DBusLoop *loop, */ wcb->last_iteration_oom = FALSE; oom_watch_pending = TRUE; + + retval = TRUE; /* return TRUE here to keep the loop going, + * since we don't know the watch is inactive + */ + + _dbus_verbose (" skipping watch on fd %d as it was out of memory last time\n", + dbus_watch_get_fd (wcb->watch)); } else if (dbus_watch_get_enabled (wcb->watch)) { @@ -572,8 +602,6 @@ _dbus_loop_iterate (DBusLoop *loop, { unsigned long tv_sec; unsigned long tv_usec; - - retval = TRUE; _dbus_get_current_time (&tv_sec, &tv_usec); @@ -610,8 +638,8 @@ _dbus_loop_iterate (DBusLoop *loop, if (!block || loop->need_dispatch != NULL) { timeout = 0; -#if 0 - printf ("timeout is 0 as we aren't blocking\n"); +#if MAINLOOP_SPEW + _dbus_verbose (" timeout is 0 as we aren't blocking\n"); #endif } @@ -620,6 +648,10 @@ _dbus_loop_iterate (DBusLoop *loop, */ if (oom_watch_pending) timeout = MIN (timeout, _dbus_get_oom_wait ()); + +#if MAINLOOP_SPEW + _dbus_verbose (" polling on %d descriptors timeout %ld\n", n_fds, timeout); +#endif n_ready = _dbus_poll (fds, n_fds, timeout); @@ -658,12 +690,14 @@ _dbus_loop_iterate (DBusLoop *loop, tcb->last_tv_sec = tv_sec; tcb->last_tv_usec = tv_usec; -#if 0 - printf (" invoking timeout\n"); +#if MAINLOOP_SPEW + _dbus_verbose (" invoking timeout\n"); #endif (* tcb->function) (tcb->timeout, cb->data); + + retval = TRUE; } } @@ -715,6 +749,11 @@ _dbus_loop_iterate (DBusLoop *loop, ((Callback*)wcb)->data)) wcb->last_iteration_oom = TRUE; +#if MAINLOOP_SPEW + _dbus_verbose (" Invoked watch, oom = %d\n", + wcb->last_iteration_oom); +#endif + retval = TRUE; } } @@ -724,14 +763,17 @@ _dbus_loop_iterate (DBusLoop *loop, } next_iteration: - dbus_free (fds); - dbus_free (watches_for_fds); + if (fds && fds != static_fds) + dbus_free (fds); + if (watches_for_fds && watches_for_fds != static_watches_for_fds) + dbus_free (watches_for_fds); + + if (_dbus_loop_dispatch (loop)) + retval = TRUE; - if (loop->need_dispatch != NULL) - { - retval = TRUE; - _dbus_loop_dispatch (loop); - } +#if MAINLOOP_SPEW + _dbus_verbose ("Returning %d\n", retval); +#endif return retval; } @@ -741,10 +783,15 @@ _dbus_loop_run (DBusLoop *loop) { int our_exit_depth; + _dbus_assert (loop->depth >= 0); + _dbus_loop_ref (loop); our_exit_depth = loop->depth; loop->depth += 1; + + _dbus_verbose ("Running main loop, depth %d -> %d\n", + loop->depth - 1, loop->depth); while (loop->depth != our_exit_depth) _dbus_loop_iterate (loop, TRUE); @@ -755,9 +802,12 @@ _dbus_loop_run (DBusLoop *loop) void _dbus_loop_quit (DBusLoop *loop) { - _dbus_assert (loop->depth > 0); + _dbus_assert (loop->depth > 0); loop->depth -= 1; + + _dbus_verbose ("Quit main loop, depth %d -> %d\n", + loop->depth + 1, loop->depth); } int @@ -774,6 +824,7 @@ _dbus_get_oom_wait (void) void _dbus_wait_for_memory (void) { + _dbus_verbose ("Waiting for more memory\n"); _dbus_sleep_milliseconds (_dbus_get_oom_wait ()); } diff --git a/dbus/dbus-mainloop.h b/dbus/dbus-mainloop.h index 7aaf9de0..ac5731f5 100644 --- a/dbus/dbus-mainloop.h +++ b/dbus/dbus-mainloop.h @@ -63,6 +63,7 @@ void _dbus_loop_run (DBusLoop *loop); void _dbus_loop_quit (DBusLoop *loop); dbus_bool_t _dbus_loop_iterate (DBusLoop *loop, dbus_bool_t block); +dbus_bool_t _dbus_loop_dispatch (DBusLoop *loop); int _dbus_get_oom_wait (void); void _dbus_wait_for_memory (void); diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 35cf1b5a..6bddc3f0 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -3453,9 +3453,6 @@ decode_header_data (const DBusString *data, _dbus_assert (_DBUS_ALIGN_ADDRESS (field, 4) == field); - /* I believe FROM_BE is right, but if not we'll find out - * I guess. ;-) - */ switch (DBUS_UINT32_FROM_BE (*(int*)field)) { case DBUS_HEADER_FIELD_SERVICE_AS_UINT32: @@ -3732,7 +3729,10 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) message = dbus_message_new_empty_header (); if (message == NULL) - return FALSE; + { + _dbus_verbose ("Failed to allocate empty message\n"); + return FALSE; + } message->byte_order = byte_order; message->header_padding = header_padding; @@ -3747,6 +3747,7 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) if (!_dbus_list_append (&loader->messages, message)) { + _dbus_verbose ("Failed to append new message to loader queue\n"); dbus_message_unref (message); return FALSE; } @@ -3759,6 +3760,7 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0)) { + _dbus_verbose ("Failed to move header into new message\n"); _dbus_list_remove_last (&loader->messages, message); dbus_message_unref (message); return FALSE; @@ -3768,6 +3770,8 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) { dbus_bool_t result; + _dbus_verbose ("Failed to move body into new message\n"); + /* put the header back, we'll try again later */ result = _dbus_string_copy_len (&message->header, 0, header_len, &loader->data, 0); diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c index d2bc6d7f..50d86301 100644 --- a/dbus/dbus-transport-unix.c +++ b/dbus/dbus-transport-unix.c @@ -404,11 +404,22 @@ do_writing (DBusTransport *transport) /* No messages without authentication! */ if (!_dbus_transport_get_is_authenticated (transport)) - return TRUE; + { + _dbus_verbose ("Not authenticated, not writing anything\n"); + return TRUE; + } if (transport->disconnected) - return TRUE; + { + _dbus_verbose ("Not connected, not writing anything\n"); + return TRUE; + } +#if 0 + _dbus_verbose ("do_writing(), have_messages = %d\n", + _dbus_connection_have_messages_to_send (transport->connection)); +#endif + oom = FALSE; total = 0; @@ -528,7 +539,7 @@ do_writing (DBusTransport *transport) } } else - { + { _dbus_verbose (" wrote %d bytes of %d\n", bytes_written, total_bytes_to_write); @@ -677,6 +688,7 @@ do_reading (DBusTransport *transport) if (_dbus_transport_queue_messages (transport) == DBUS_DISPATCH_NEED_MEMORY) { oom = TRUE; + _dbus_verbose (" out of memory when queueing messages we just read in the transport\n"); goto out; } @@ -726,7 +738,8 @@ unix_handle_watch (DBusTransport *transport, (flags & DBUS_WATCH_WRITABLE)) { #if 0 - _dbus_verbose ("handling write watch\n"); + _dbus_verbose ("handling write watch, messages_need_sending = %d\n", + transport->messages_need_sending); #endif if (!do_authentication (transport, FALSE, TRUE)) return FALSE; @@ -734,6 +747,20 @@ unix_handle_watch (DBusTransport *transport, if (!do_writing (transport)) return FALSE; } +#ifdef DBUS_ENABLE_VERBOSE_MODE + else + { + if (watch == unix_transport->read_watch) + _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n", + flags); + else if (watch == unix_transport->write_watch) + _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n", + flags); + else + _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n", + watch, dbus_watch_get_fd (watch)); + } +#endif /* DBUS_ENABLE_VERBOSE_MODE */ return TRUE; } diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index d074480a..e715bd1a 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -213,6 +213,8 @@ _dbus_transport_open (const char *address, { DBusTransport *transport; DBusAddressEntry **entries; + DBusError tmp_error; + DBusError first_error; int len, i; const char *address_problem_type; const char *address_problem_field; @@ -223,15 +225,21 @@ _dbus_transport_open (const char *address, if (!dbus_parse_address (address, &entries, &len, error)) return NULL; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + transport = NULL; address_problem_type = NULL; address_problem_field = NULL; address_problem_other = NULL; - + + dbus_error_init (&tmp_error); + dbus_error_init (&first_error); for (i = 0; i < len; i++) { - const char *method = dbus_address_entry_get_method (entries[i]); + 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"); @@ -250,7 +258,7 @@ _dbus_transport_open (const char *address, goto bad_address; } - transport = _dbus_transport_new_for_domain_socket (path, error); + transport = _dbus_transport_new_for_domain_socket (path, &tmp_error); } else if (strcmp (method, "tcp") == 0) { @@ -277,7 +285,7 @@ _dbus_transport_open (const char *address, 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") == 0) @@ -290,8 +298,8 @@ _dbus_transport_open (const char *address, address_problem_field = "name"; goto bad_address; } - - transport = _dbus_transport_debug_client_new (name, error); + + transport = _dbus_transport_debug_client_new (name, &tmp_error); } else if (strcmp (method, "debug-pipe") == 0) { @@ -303,8 +311,8 @@ _dbus_transport_open (const char *address, address_problem_field = "name"; goto bad_address; } - - transport = _dbus_transport_debug_pipe_new (name, error); + + transport = _dbus_transport_debug_pipe_new (name, &tmp_error); } #endif else @@ -314,9 +322,29 @@ _dbus_transport_open (const char *address, } if (transport) - break; + 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); + } + else + { + dbus_error_free (&first_error); + } + dbus_address_entries_free (entries); return transport; @@ -771,6 +799,8 @@ dbus_bool_t _dbus_transport_queue_messages (DBusTransport *transport) { DBusDispatchStatus status; + + _dbus_verbose ("_dbus_transport_queue_messages()\n"); /* Queue any messages */ while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS) diff --git a/test/test-service.c b/test/test-service.c index 732e5b13..9d5eceef 100644 --- a/test/test-service.c +++ b/test/test-service.c @@ -2,7 +2,7 @@ #include "test-utils.h" static DBusLoop *loop; -static dbus_bool_t already_quit; +static dbus_bool_t already_quit = FALSE; static void quit (void) @@ -140,7 +140,8 @@ main (int argc, dbus_error_free (&error); exit (1); } - + + _dbus_verbose ("*** Test service entering main loop\n"); _dbus_loop_run (loop); test_connection_shutdown (loop, connection); -- cgit