2003-04-10 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Thu, 10 Apr 2003 05:12:19 +0000 (05:12 +0000)
committerHavoc Pennington <hp@redhat.com>
Thu, 10 Apr 2003 05:12:19 +0000 (05:12 +0000)
* 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.

14 files changed:
ChangeLog
bus/activation.c
bus/connection.c
bus/dispatch.c
bus/driver.c
bus/test.c
dbus/dbus-connection.c
dbus/dbus-internals.c
dbus/dbus-mainloop.c
dbus/dbus-mainloop.h
dbus/dbus-message.c
dbus/dbus-transport-unix.c
dbus/dbus-transport.c
test/test-service.c

index f27504b..4222dc6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2003-04-10  Havoc Pennington  <hp@pobox.com>
+
+       * 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  <hp@redhat.com>
 
        * dbus/dbus-mainloop.c (check_timeout): fix timeouts, I thought
index 8ecf6ec..13c147e 100644 (file)
@@ -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)
index aeb4f6e..80a9ae7 100644 (file)
@@ -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)");
index 43fccdc..e867674 100644 (file)
@@ -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",
@@ -971,6 +995,8 @@ check_nonexistent_service_activation (BusContext     *context,
   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;
         }
     }
 
index a3fe7c5..bb8ac29 100644 (file)
@@ -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
  * 
index ded23ba..c4d999f 100644 (file)
@@ -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);
 
index 3be4ee4..0961e49 100644 (file)
@@ -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);
index 6a662e5..230c8ef 100644 (file)
@@ -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;
index 721eedf..bf01108 100644 (file)
@@ -26,6 +26,8 @@
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-sysdeps.h>
 
+#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 ());
 }
 
index 7aaf9de..ac5731f 100644 (file)
@@ -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);
index 35cf1b5..6bddc3f 100644 (file)
@@ -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);
index d2bc6d7..50d8630 100644 (file)
@@ -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;
 }
index d074480..e715bd1 100644 (file)
@@ -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)
index 732e5b1..9d5ecee 100644 (file)
@@ -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);