dbus/bus activation.c, 1.33, 1.34 activation.h, 1.11, 1.12 dispatch.c, 1.56, 1.57 driver.c, 1.45, 1.46 services.c, 1.19, 1.20

Richard Hult richard at pdx.freedesktop.org
Tue Mar 16 10:00:37 PST 2004


Update of /cvs/dbus/dbus/bus
In directory pdx:/tmp/cvs-serv27501/bus

Modified Files:
	activation.c activation.h dispatch.c driver.c services.c 
Log Message:
2004-03-16  Richard Hult  <richard at imendio.com>

	* bus/activation.c: (bus_activation_service_created),
	(bus_activation_send_pending_auto_activation_messages),
	(bus_activation_activate_service):
	* bus/activation.h:
	* bus/dispatch.c: (bus_dispatch),
	(check_nonexistent_service_auto_activation),
	(check_service_auto_activated),
	(check_segfault_service_auto_activation),
	(check_existent_service_auto_activation), (bus_dispatch_test):
	* bus/driver.c: (bus_driver_handle_activate_service):
	* bus/services.c: (bus_registry_acquire_service):
	* dbus/dbus-message.c: (dbus_message_set_auto_activation),
	(dbus_message_get_auto_activation):
	* dbus/dbus-message.h:
	* dbus/dbus-protocol.h: Implement auto-activation.


Index: activation.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/activation.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- a/activation.c	12 Mar 2004 14:15:14 -0000	1.33
+++ b/activation.c	16 Mar 2004 18:00:34 -0000	1.34
@@ -76,6 +76,8 @@
 {
   DBusMessage *activation_message;
   DBusConnection *connection;
+
+  dbus_bool_t auto_activation;
 };
 
 typedef struct
@@ -904,30 +906,90 @@
       
       if (dbus_connection_get_is_connected (entry->connection))
 	{
-	  message = dbus_message_new_method_return (entry->activation_message);
-	  if (!message)
-	    {
-	      BUS_SET_OOM (error);
-	      goto error;
-	    }
-
-	  if (!dbus_message_append_args (message,
-					 DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ACTIVATED,
-					 DBUS_TYPE_INVALID))
+	  /* Only send activation replies to regular activation requests. */
+	  if (!entry->auto_activation)
 	    {
+	      message = dbus_message_new_method_return (entry->activation_message);
+	      if (!message)
+		{
+		  BUS_SET_OOM (error);
+		  goto error;
+		}
+	      
+	      if (!dbus_message_append_args (message,
+					     DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ACTIVATED,
+					     DBUS_TYPE_INVALID))
+		{
+		  dbus_message_unref (message);
+		  BUS_SET_OOM (error);
+		  goto error;
+		}
+	      
+	      if (!bus_transaction_send_from_driver (transaction, entry->connection, message))
+		{
+		  dbus_message_unref (message);
+		  BUS_SET_OOM (error);
+		  goto error;
+		}
+	      
 	      dbus_message_unref (message);
-	      BUS_SET_OOM (error);
-	      goto error;
 	    }
-          
-	  if (!bus_transaction_send_from_driver (transaction, entry->connection, message))
+	}
+      
+      link = next;
+    }
+
+  return TRUE;
+
+ error:
+  return FALSE;
+}
+
+dbus_bool_t
+bus_activation_send_pending_auto_activation_messages (BusActivation  *activation,
+						      BusService     *service,
+						      BusTransaction *transaction,
+						      DBusError      *error)
+{
+  BusPendingActivation *pending_activation;
+  DBusList *link;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  
+  /* Check if it's a pending activation */
+  pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations,
+						       bus_service_get_name (service));
+
+  if (!pending_activation)
+    return TRUE;
+
+  link = _dbus_list_get_first_link (&pending_activation->entries);
+  while (link != NULL)
+    {
+      BusPendingActivationEntry *entry = link->data;
+      DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
+
+      if (entry->auto_activation && dbus_connection_get_is_connected (entry->connection))
+	{
+	  DBusConnection *addressed_recipient;
+	  
+	  addressed_recipient = bus_service_get_primary_owner (service);
+
+	  /* Check the security policy, which has the side-effect of adding an
+	   * expected pending reply.
+	   */
+          if (!bus_context_check_security_policy (activation->context, transaction,
+						  entry->connection,
+						  addressed_recipient,
+						  addressed_recipient,
+						  entry->activation_message, error))
+	    goto error;
+
+	  if (!bus_transaction_send (transaction, addressed_recipient, entry->activation_message))
 	    {
-	      dbus_message_unref (message);
 	      BUS_SET_OOM (error);
 	      goto error;
 	    }
-          
-          dbus_message_unref (message);
 	}
 
       link = next;
@@ -940,7 +1002,7 @@
       goto error;
     }
   
-  _dbus_hash_table_remove_string (activation->pending_activations, service_name);
+  _dbus_hash_table_remove_string (activation->pending_activations, bus_service_get_name (service));
 
   return TRUE;
 
@@ -1225,6 +1287,7 @@
 bus_activation_activate_service (BusActivation  *activation,
 				 DBusConnection *connection,
                                  BusTransaction *transaction,
+				 dbus_bool_t     auto_activation,
 				 DBusMessage    *activation_message,
                                  const char     *service_name,
 				 DBusError      *error)
@@ -1300,6 +1363,8 @@
       return FALSE;
     }
 
+  pending_activation_entry->auto_activation = auto_activation;
+
   pending_activation_entry->activation_message = activation_message;
   dbus_message_ref (activation_message);
   pending_activation_entry->connection = connection;

Index: activation.h
===================================================================
RCS file: /cvs/dbus/dbus/bus/activation.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- a/activation.h	2 Dec 2003 10:44:21 -0000	1.11
+++ b/activation.h	16 Mar 2004 18:00:34 -0000	1.12
@@ -29,21 +29,28 @@
 #include "bus.h"
 
 BusActivation* bus_activation_new              (BusContext        *context,
-                                                const DBusString  *address,
-                                                DBusList         **directories,
-                                                DBusError         *error);
+						const DBusString  *address,
+						DBusList         **directories,
+						DBusError         *error);
 BusActivation* bus_activation_ref              (BusActivation     *activation);
 void           bus_activation_unref            (BusActivation     *activation);
 dbus_bool_t    bus_activation_activate_service (BusActivation     *activation,
-                                                DBusConnection    *connection,
-                                                BusTransaction    *transaction,
-                                                DBusMessage       *activation_message,
-                                                const char        *service_name,
-                                                DBusError         *error);
+						DBusConnection    *connection,
+						BusTransaction    *transaction,
+						dbus_bool_t        auto_activation,
+						DBusMessage       *activation_message,
+						const char        *service_name,
+						DBusError         *error);
 dbus_bool_t    bus_activation_service_created  (BusActivation     *activation,
-                                                const char        *service_name,
-                                                BusTransaction    *transaction,
-                                                DBusError         *error);
+						const char        *service_name,
+						BusTransaction    *transaction,
+						DBusError         *error);
+
+dbus_bool_t    bus_activation_send_pending_auto_activation_messages (BusActivation     *activation,
+								     BusService        *service,
+								     BusTransaction    *transaction,
+								     DBusError         *error);
+
 
 
 #endif /* BUS_ACTIVATION_H */

Index: dispatch.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/dispatch.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- a/dispatch.c	2 Dec 2003 10:44:21 -0000	1.56
+++ b/dispatch.c	16 Mar 2004 18:00:34 -0000	1.57
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2003  CodeFactory AB
  * Copyright (C) 2003  Red Hat, Inc.
+ * Copyright (C) 2004  Imendio HB
  *
  * Licensed under the Academic Free License version 2.0
  * 
@@ -26,6 +27,7 @@
 #include "connection.h"
 #include "driver.h"
 #include "services.h"
+#include "activation.h"
 #include "utils.h"
 #include "bus.h"
 #include "signals.h"
@@ -257,7 +259,27 @@
       _dbus_string_init_const (&service_string, service_name);
       service = bus_registry_lookup (registry, &service_string);
 
-      if (service == NULL)
+      if (service == NULL && dbus_message_get_auto_activation (message))
+        {
+	  BusActivation *activation;
+
+	  /* We can't do the security policy check here, since the addressed
+	   * recipient service doesn't exist yet. We do it before sending the
+	   * message after the service has been created.
+	   */
+	  activation = bus_connection_get_activation (connection);
+
+	  if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
+						message, service_name, &error))
+	    {
+	      _DBUS_ASSERT_ERROR_IS_SET (&error);
+	      _dbus_verbose ("bus_activation_activate_service() failed\n");
+	      goto out;
+	    }
+	  
+	  goto out;
+	}
+      else if (service == NULL)
         {
           dbus_set_error (&error,
                           DBUS_ERROR_SERVICE_DOES_NOT_EXIST,
@@ -378,6 +400,8 @@
 
 #ifdef DBUS_BUILD_TESTS
 
+#include <stdio.h>
+
 typedef dbus_bool_t (* Check1Func) (BusContext     *context);
 typedef dbus_bool_t (* Check2Func) (BusContext     *context,
                                     DBusConnection *connection);
@@ -1170,6 +1194,104 @@
   return retval;
 }
 
+/* returns TRUE if the correct thing happens,
+ * but the correct thing may include OOM errors.
+ */
+static dbus_bool_t
+check_nonexistent_service_auto_activation (BusContext     *context,
+					   DBusConnection *connection)
+{
+  DBusMessage *message;
+  dbus_uint32_t serial;
+  dbus_bool_t retval;
+  DBusError error;
+    
+  dbus_error_init (&error);
+
+  message = dbus_message_new_method_call (NONEXISTENT_SERVICE_NAME,
+                                          "/org/freedesktop/TestSuite",
+                                          "org.freedesktop.TestSuite",
+                                          "Echo");
+  
+  if (message == NULL)
+    return TRUE;
+
+  dbus_message_set_auto_activation (message, TRUE);
+ 
+  if (!dbus_connection_send (connection, message, &serial))
+    {
+      dbus_message_unref (message);
+      return TRUE;
+    }
+
+  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))
+    {
+      _dbus_verbose ("connection was disconnected\n");
+      return TRUE;
+    }
+  
+  retval = FALSE;
+  
+  message = pop_message_waiting_for_memory (connection);
+
+  if (message == NULL)
+    {
+      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+                  "Echo message (auto activation)", serial, connection);
+      goto out;
+    }
+
+  verbose_message_received (connection, message);
+
+  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
+    {
+      if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
+        {
+          _dbus_warn ("Message has wrong sender %s\n",
+                      dbus_message_get_sender (message) ?
+                      dbus_message_get_sender (message) : "(none)");
+          goto out;
+        }
+      
+      if (dbus_message_is_error (message,
+                                 DBUS_ERROR_NO_MEMORY))
+        {
+          ; /* good, this is a valid response */
+        }
+      else if (dbus_message_is_error (message,
+                                      DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND))
+        {
+          ; /* good, this is expected also */
+        }
+      else
+        {
+          warn_unexpected (connection, message, "not this error");
+          goto out;
+        }
+    }
+  else
+    {
+      _dbus_warn ("Did not expect to successfully activate %s\n",
+                  NONEXISTENT_SERVICE_NAME);
+      goto out;
+    }
+
+  retval = TRUE;
+  
+ out:
+  if (message)
+    dbus_message_unref (message);
+  
+  return retval;
+}
+
 static dbus_bool_t
 check_base_service_activated (BusContext     *context,
                               DBusConnection *connection,
@@ -1398,6 +1520,94 @@
 }
 
 static dbus_bool_t
+check_service_auto_activated (BusContext     *context,
+			      DBusConnection *connection,
+			      const char     *activated_name,
+			      const char     *base_service_name,
+			      DBusMessage    *initial_message)
+{
+  DBusMessage *message;
+  dbus_bool_t retval;
+  DBusError error;
+  
+  retval = FALSE;
+  
+  dbus_error_init (&error);
+
+  message = initial_message;
+  dbus_message_ref (message);
+
+  if (dbus_message_is_signal (message,
+                              DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+                              "ServiceCreated"))
+    {
+      char *service_name;
+      CheckServiceCreatedData scd;
+      
+    reget_service_name_arg:
+      if (!dbus_message_get_args (message, &error,
+                                  DBUS_TYPE_STRING, &service_name,
+                                  DBUS_TYPE_INVALID))
+        {
+          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",
+                          "ServiceCreated",
+                          error.message);
+              dbus_error_free (&error);
+              goto out;
+            }
+        }
+      
+      if (strcmp (service_name, activated_name) != 0)
+        {
+          _dbus_warn ("Expected to see service %s created, saw %s instead\n",
+                      activated_name, service_name);
+          dbus_free (service_name);
+          goto out;
+        }
+      
+      scd.skip_connection = connection;
+      scd.failed = FALSE;
+      scd.expected_service_name = service_name;
+      bus_test_clients_foreach (check_service_created_foreach,
+				&scd);
+      
+      dbus_free (service_name);
+      
+      if (scd.failed)
+        goto out;
+      
+      /* Note that this differs from regular activation in that we don't get a
+       * reply to ActivateService here.
+       */
+      
+      dbus_message_unref (message);
+      message = NULL;
+    }
+  else
+    {
+      warn_unexpected (connection, message, "ServiceCreated for the activated name");
+      
+      goto out;
+    }
+  
+  retval = TRUE;
+  
+ out:
+  if (message)
+    dbus_message_unref (message);
+  
+  return retval;
+}
+
+static dbus_bool_t
 check_service_deactivated (BusContext     *context,
                            DBusConnection *connection,
                            const char     *activated_name,
@@ -1974,6 +2184,340 @@
   return retval;
 }
 
+
+/* returns TRUE if the correct thing happens,
+ * but the correct thing may include OOM errors.
+ */
+static dbus_bool_t
+check_segfault_service_auto_activation (BusContext     *context,
+					DBusConnection *connection)
+{
+  DBusMessage *message;
+  dbus_uint32_t serial;
+  dbus_bool_t retval;
+  DBusError error;
+
+  dbus_error_init (&error);
+
+  dbus_error_init (&error);
+
+  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteSegfaultService",
+                                          "/org/freedesktop/TestSuite",
+                                          "org.freedesktop.TestSuite",
+                                          "Echo");
+  
+  if (message == NULL)
+    return TRUE;
+
+  dbus_message_set_auto_activation (message, TRUE);
+  
+  if (!dbus_connection_send (connection, message, &serial))
+    {
+      dbus_message_unref (message);
+      return TRUE;
+    }
+
+  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))
+    {
+      _dbus_verbose ("connection was disconnected\n");
+      return TRUE;
+    }
+  
+  retval = FALSE;
+  
+  message = pop_message_waiting_for_memory (connection);
+  if (message == NULL)
+    {
+      _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+                  "Echo message (auto activation)", serial, connection);
+      goto out;
+    }
+
+  verbose_message_received (connection, message);
+
+  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
+    {
+      if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
+        {
+          _dbus_warn ("Message has wrong sender %s\n",
+                      dbus_message_get_sender (message) ?
+                      dbus_message_get_sender (message) : "(none)");
+          goto out;
+        }
+      
+      if (dbus_message_is_error (message,
+                                 DBUS_ERROR_NO_MEMORY))
+        {
+          ; /* good, this is a valid response */
+        }
+      else if (dbus_message_is_error (message,
+                                      DBUS_ERROR_SPAWN_CHILD_SIGNALED))
+        {
+          ; /* good, this is expected also */
+        }
+      else
+        {
+          warn_unexpected (connection, message, "not this error");
+
+          goto out;
+        }
+    }
+  else
+    {
+      _dbus_warn ("Did not expect to successfully activate segfault service\n");
+      goto out;
+    }
+
+  retval = TRUE;
+  
+ out:
+  if (message)
+    dbus_message_unref (message);
+  
+  return retval;
+}
+
+#define TEST_ECHO_MESSAGE "Test echo message"
+
+/* returns TRUE if the correct thing happens,
+ * but the correct thing may include OOM errors.
+ */
+static dbus_bool_t
+check_existent_service_auto_activation (BusContext     *context,
+					DBusConnection *connection)
+{
+  DBusMessage *message;
+  dbus_uint32_t serial;
+  dbus_bool_t retval;
+  DBusError error;
+  char *base_service;
+
+  base_service = NULL;
+
+  dbus_error_init (&error);
+
+  message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
+                                          "/org/freedesktop/TestSuite",
+                                          "org.freedesktop.TestSuite",
+                                          "Echo");
+  
+  if (message == NULL)
+    return TRUE;
+
+  dbus_message_set_auto_activation (message, TRUE);
+
+  if (!dbus_message_append_args (message,
+                                 DBUS_TYPE_STRING, TEST_ECHO_MESSAGE,
+                                 DBUS_TYPE_INVALID))
+    {
+      dbus_message_unref (message);
+      return TRUE;
+    }
+
+  if (!dbus_connection_send (connection, message, &serial))
+    {
+      dbus_message_unref (message);
+      return TRUE;
+    }
+
+  dbus_message_unref (message);
+  message = NULL;
+
+  bus_test_run_everything (context);
+
+  /* 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))
+    {
+      _dbus_verbose ("connection was disconnected\n");
+      return TRUE;
+    }
+
+  retval = FALSE;
+  
+  /* Should get ServiceCreated for the base service, or an error. */
+  message = pop_message_waiting_for_memory (connection);
+  if (message == NULL)
+    {
+      _dbus_warn ("Did not receive any messages after auto activation %d on %p\n",
+                  serial, connection);
+      goto out;
+    }
+
+  verbose_message_received (connection, message);
+  _dbus_verbose ("  (after sending %s)\n", "ActivateService");
+
+  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
+    {
+      if (!dbus_message_has_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
+        {
+          _dbus_warn ("Message has wrong sender %s\n",
+                      dbus_message_get_sender (message) ?
+                      dbus_message_get_sender (message) : "(none)");
+	  goto out;
+        }
+
+      if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY) ||
+	  dbus_message_is_error (message, DBUS_ERROR_SPAWN_CHILD_EXITED) ||
+	  dbus_message_is_error (message, DBUS_ERROR_TIMED_OUT))
+        {
+          ; /* good, those are expected */
+	  retval = TRUE;
+	  goto out;
+        }
+      else
+        {
+          _dbus_warn ("Did not expect error %s\n",
+                      dbus_message_get_error_name (message));
+          goto out;
+        }
+    }
+  else
+    {
+      dbus_bool_t got_service_deleted;
+      dbus_bool_t got_error;
+      
+      if (!check_base_service_activated (context, connection,
+                                         message, &base_service))
+	goto out;
+
+      dbus_message_unref (message);
+      message = NULL;
+
+      /* We may need to block here for the test service to exit or finish up */
+      block_connection_until_message_from_bus (context, connection);
+
+      /* Should get ServiceCreated for the activated service name,
+       * ServiceDeleted on the base service name, or an error.
+       */
+      message = dbus_connection_borrow_message (connection);
+      if (message == NULL)
+        {
+          _dbus_warn ("Did not receive any messages after base service creation notification\n");
+          goto out;
+        }
+
+      got_service_deleted = dbus_message_is_signal (message,
+                                                    DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+                                                    "ServiceDeleted");
+      got_error = dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
+
+      dbus_connection_return_message (connection, message);
+      message = NULL;
+
+      if (got_error)
+        {
+          if (!check_got_error (context, connection,
+                                DBUS_ERROR_SPAWN_CHILD_EXITED,
+                                DBUS_ERROR_NO_MEMORY,
+                                NULL))
+            goto out;
+
+          /* A service deleted should be coming along now after this error.
+           * We can also get the error *after* the service deleted.
+           */
+          got_service_deleted = TRUE;
+        }
+      
+      if (got_service_deleted)
+        {
+          /* The service started up and got a base address, but then
+           * failed to register under EXISTENT_SERVICE_NAME
+           */
+          CheckServiceDeletedData csdd;
+          
+          csdd.expected_service_name = base_service;
+          csdd.failed = FALSE;
+          bus_test_clients_foreach (check_service_deleted_foreach,
+                                    &csdd);
+
+          if (csdd.failed)
+            goto out;
+	  
+          /* Now we should get an error about the service exiting
+           * if we didn't get it before.
+           */
+          if (!got_error)
+            {
+              block_connection_until_message_from_bus (context, connection);
+              
+              /* and process everything again */
+              bus_test_run_everything (context);
+
+              if (!check_got_error (context, connection,
+                                    DBUS_ERROR_SPAWN_CHILD_EXITED,
+                                    NULL))
+                goto out;
+            }
+        }
+      else
+        {
+	  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");
+              goto out;
+            }
+
+	  /* Check that ServiceCreated was correctly received */
+          if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME,
+					     base_service, message))
+            goto out;
+
+          dbus_message_unref (message);
+          message = NULL;
+	}
+
+      /* Note: if this test is run in OOM mode, it will block when the bus
+       * doesn't send a reply due to OOM.
+       */
+      block_connection_until_message_from_bus (context, connection);
+      
+      message = pop_message_waiting_for_memory (connection);
+      if (message == NULL)
+	{
+	  _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
+	  goto out;
+	}
+
+      if (dbus_message_get_reply_serial (message) != serial)
+	{
+	  _dbus_warn ("Wrong reply serial\n");
+	  goto out;
+	}
+
+      dbus_message_unref (message);
+      message = NULL;
+      
+      if (!check_send_exit_to_service (context, connection,
+				       EXISTENT_SERVICE_NAME,
+				       base_service))
+	goto out;
+    }
+  
+  retval = TRUE;
+
+ out:
+  if (message)
+    dbus_message_unref (message);
+
+  if (base_service)
+    dbus_free (base_service);
+
+  return retval;
+}
+
 typedef struct
 {
   Check1Func func;
@@ -2126,6 +2670,24 @@
   check2_try_iterations (context, foo, "existent_service_activation",
                          check_existent_service_activation);
   
+  check2_try_iterations (context, foo, "nonexistent_service_auto_activation",
+			 check_nonexistent_service_auto_activation);
+  
+  check2_try_iterations (context, foo, "segfault_service_auto_activation",
+			 check_segfault_service_auto_activation);
+
+#if 0
+  /* Note: need to resolve some issues with the testing code in order to run
+   * this in oom (handle that we sometimes don't get replies back from the bus
+   * when oom happens, without blocking the test).
+   */
+  check2_try_iterations (context, foo, "existent_service_auto_activation",
+			 check_existent_service_auto_activation);
+#endif
+  
+  if (!check_existent_service_auto_activation (context, foo))
+    _dbus_assert_not_reached ("existent service auto activation failed");
+
   _dbus_verbose ("Disconnecting foo, bar, and baz\n");
 
   kill_client_connection_unchecked (foo);

Index: driver.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/driver.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- a/driver.c	2 Dec 2003 10:44:21 -0000	1.45
+++ b/driver.c	16 Mar 2004 18:00:34 -0000	1.46
@@ -587,7 +587,7 @@
 
   retval = FALSE;
 
-  if (!bus_activation_activate_service (activation, connection, transaction,
+  if (!bus_activation_activate_service (activation, connection, transaction, FALSE,
                                         message, name, error))
     {
       _DBUS_ASSERT_ERROR_IS_SET (error);

Index: services.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/services.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- a/services.c	24 Feb 2004 19:50:25 -0000	1.19
+++ b/services.c	16 Mar 2004 18:00:34 -0000	1.20
@@ -262,6 +262,7 @@
   DBusConnection *current_owner;
   BusClientPolicy *policy;
   BusService *service;
+  BusActivation  *activation;
   
   retval = FALSE;
 
@@ -376,7 +377,11 @@
       *result = DBUS_SERVICE_REPLY_PRIMARY_OWNER;
     }
 
-  retval = TRUE;
+  activation = bus_context_get_activation (registry->context);
+  retval = bus_activation_send_pending_auto_activation_messages (activation,
+								 service,
+								 transaction,
+								 error);
   
  out:
   return retval;




More information about the dbus-commit mailing list