diff options
| author | Olivier Andrieu <oliv__a@users.sourceforge.net> | 2004-09-24 10:43:36 +0000 | 
|---|---|---|
| committer | Olivier Andrieu <oliv__a@users.sourceforge.net> | 2004-09-24 10:43:36 +0000 | 
| commit | 85f8f62da6bb26d7033310af9d3260b073efe4bf (patch) | |
| tree | 9b4bc616ed867cba0e8b48873c9b9e91cd326bbb | |
| parent | 64b63e84b7f08695bf194a05aadd074600c8e622 (diff) | |
* doc/dbus-specification.xml: document ServiceOwnerChanged signal.
* bus/driver.c, bus/driver.h, bus/services.c: Use ServiceOwnerChanged
signal instead of ServiceCreated and ServiceDeleted.
* bus/dispatch.c: update testcase for the new signal.
| -rw-r--r-- | ChangeLog | 11 | ||||
| -rw-r--r-- | bus/dispatch.c | 780 | ||||
| -rw-r--r-- | bus/driver.c | 72 | ||||
| -rw-r--r-- | bus/driver.h | 11 | ||||
| -rw-r--r-- | bus/services.c | 22 | ||||
| -rw-r--r-- | doc/dbus-specification.xml | 59 | 
6 files changed, 485 insertions, 470 deletions
@@ -1,3 +1,14 @@ +2004-09-24  Olivier Andrieu  <oliv__a@users.sourceforge.net> + +	* doc/dbus-specification.xml: document ServiceOwnerChanged +	signal. +	 +	* bus/driver.c, bus/driver.h, bus/services.c: Use +	ServiceOwnerChanged signal instead of ServiceCreated and +	ServiceDeleted. +	 +	* bus/dispatch.c: update testcase for the new signal. +  2004-09-20  Jon Trowbridge  <trow@ximian.com>  	Patch from Nat Friedman <nat@novell.com> diff --git a/bus/dispatch.c b/bus/dispatch.c index 54e4583d..3cd1c3e4 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -93,8 +93,7 @@ bus_dispatch_matches (BusTransaction *transaction,    matchmaker = bus_context_get_matchmaker (context);    recipients = NULL; -  if (!bus_matchmaker_get_recipients (matchmaker, -                                      bus_context_get_connections (context), +  if (!bus_matchmaker_get_recipients (matchmaker, connections,                                        sender, addressed_recipient, message,                                        &recipients))      { @@ -482,70 +481,114 @@ verbose_message_received (DBusConnection *connection,                   connection);  } +typedef enum +{ +  SERVICE_CREATED, +  OWNER_CHANGED, +  SERVICE_DELETED +} ServiceInfoKind; +  typedef struct  { +  ServiceInfoKind expected_kind;    const char *expected_service_name;    dbus_bool_t failed; -} CheckServiceDeletedData; +  DBusConnection *skip_connection; +} CheckServiceOwnerChangedData;  static dbus_bool_t -check_service_deleted_foreach (DBusConnection *connection, -                               void           *data) +check_service_owner_changed_foreach (DBusConnection *connection, +				     void           *data)  { -  CheckServiceDeletedData *d = data; +  CheckServiceOwnerChangedData *d = data;    DBusMessage *message;    DBusError error; -  char *service_name; +  char *service_name, *old_owner, *new_owner; + +  if (d->expected_kind == SERVICE_CREATED  +      && connection == d->skip_connection) +    return TRUE;    dbus_error_init (&error);    d->failed = TRUE; -  service_name = NULL;    message = pop_message_waiting_for_memory (connection);    if (message == NULL)      {        _dbus_warn ("Did not receive a message on %p, expecting %s\n", -                  connection, "ServiceDeleted"); +                  connection, "ServiceOwnerChanged");        goto out;      }    else if (!dbus_message_is_signal (message,                                      DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, -                                    "ServiceDeleted")) +                                    "ServiceOwnerChanged"))      { -      warn_unexpected (connection, message, "ServiceDeleted"); +      warn_unexpected (connection, message, "ServiceOwnerChanged");        goto out;      }    else      { -      if (!dbus_message_get_args (message, &error, -                                  DBUS_TYPE_STRING, &service_name, -                                  DBUS_TYPE_INVALID)) +    reget_service_info_data: +      service_name = NULL; +      old_owner = NULL; +      new_owner = NULL; + +      dbus_message_get_args (message, &error, +                             DBUS_TYPE_STRING, &service_name, +                             DBUS_TYPE_STRING, &old_owner, +                             DBUS_TYPE_STRING, &new_owner, +                             DBUS_TYPE_INVALID); + +      if (dbus_error_is_set (&error)) +	{ +	  if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) +	    { +              dbus_free (service_name); +              dbus_free (old_owner); +              dbus_free (new_owner); +              dbus_error_free (&error); +              _dbus_wait_for_memory ();               +              goto reget_service_info_data; +	    } +	  else +	    { +	      _dbus_warn ("Did not get the expected arguments\n"); +	      goto out; +	    } +	} + +      if ((d->expected_kind == SERVICE_CREATED    && ( old_owner[0] || !new_owner[0])) +          || (d->expected_kind == OWNER_CHANGED   && (!old_owner[0] || !new_owner[0])) +          || (d->expected_kind == SERVICE_DELETED && (!old_owner[0] ||  new_owner[0])))          { -          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) -            { -              _dbus_verbose ("no memory to get service name arg\n"); -            } -          else -            { -              _dbus_assert (dbus_error_is_set (&error)); -              _dbus_warn ("Did not get the expected single string argument\n"); -              goto out; -            } +          _dbus_warn ("inconsistent ServiceOwnerChanged arguments"); +          goto out;          } -      else if (strcmp (service_name, d->expected_service_name) != 0) + +      if (strcmp (service_name, d->expected_service_name) != 0)          { -          _dbus_warn ("expected deletion of service %s, got deletion of %s\n", +          _dbus_warn ("expected info on service %s, got info on %s\n",                        d->expected_service_name,                        service_name);            goto out;          } + +      if (*service_name == ':' && new_owner[0]  +          && strcmp (service_name, new_owner) != 0) +        { +          _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])\n", +                      service_name, old_owner, new_owner); +          goto out; +        }      }    d->failed = FALSE;   out:    dbus_free (service_name); +  dbus_free (old_owner); +  dbus_free (new_owner);    dbus_error_free (&error);    if (message) @@ -554,13 +597,14 @@ check_service_deleted_foreach (DBusConnection *connection,    return !d->failed;  } +  static void  kill_client_connection (BusContext     *context,                          DBusConnection *connection)  {    char *base_service;    const char *s; -  CheckServiceDeletedData csdd; +  CheckServiceOwnerChangedData socd;    _dbus_verbose ("killing connection %p\n", connection); @@ -588,16 +632,18 @@ kill_client_connection (BusContext     *context,    connection = NULL;    _dbus_assert (!bus_test_client_listed (connection)); -  csdd.expected_service_name = base_service; -  csdd.failed = FALSE; - -  bus_test_clients_foreach (check_service_deleted_foreach, -                            &csdd); +  socd.expected_kind = SERVICE_DELETED; +  socd.expected_service_name = base_service; +  socd.failed = FALSE; +  socd.skip_connection = NULL; +   +  bus_test_clients_foreach (check_service_owner_changed_foreach, +                            &socd);    dbus_free (base_service); -  if (csdd.failed) -    _dbus_assert_not_reached ("didn't get the expected ServiceDeleted messages"); +  if (socd.failed) +    _dbus_assert_not_reached ("didn't get the expected ServiceOwnerChanged (deletion) messages");    if (!check_no_leftovers (context))      _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client"); @@ -646,81 +692,6 @@ check_no_messages_foreach (DBusConnection *connection,    return !d->failed;  } -typedef struct -{ -  DBusConnection *skip_connection; -  const char *expected_service_name; -  dbus_bool_t failed; -} CheckServiceCreatedData; - -static dbus_bool_t -check_service_created_foreach (DBusConnection *connection, -                               void           *data) -{ -  CheckServiceCreatedData *d = data; -  DBusMessage *message; -  DBusError error; -  char *service_name; - -  if (connection == d->skip_connection) -    return TRUE; - -  dbus_error_init (&error); -  d->failed = TRUE; -  service_name = NULL; -   -  message = pop_message_waiting_for_memory (connection); -  if (message == NULL) -    { -      _dbus_warn ("Did not receive a message on %p, expecting %s\n", -                  connection, "ServiceCreated"); -      goto out; -    } -  else if (!dbus_message_is_signal (message, -                                    DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, -                                    "ServiceCreated")) -    { -      warn_unexpected (connection, message, "ServiceCreated"); -      goto out; -    } -  else -    { -      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_verbose ("no memory to get service name arg\n"); -            } -          else -            { -              _dbus_assert (dbus_error_is_set (&error)); -              _dbus_warn ("Did not get the expected single string argument\n"); -              goto out; -            } -        } -      else if (strcmp (service_name, d->expected_service_name) != 0) -        { -          _dbus_warn ("expected creation of service %s, got creation of %s\n", -                      d->expected_service_name, -                      service_name); -          goto out; -        } -    } - -  d->failed = FALSE; -   - out: -  dbus_free (service_name); -  dbus_error_free (&error); -   -  if (message) -    dbus_message_unref (message); - -  return !d->failed; -} -  static dbus_bool_t  check_no_leftovers (BusContext *context)  { @@ -826,7 +797,7 @@ check_hello_message (BusContext     *context,      }    else      { -      CheckServiceCreatedData scd; +      CheckServiceOwnerChangedData socd;        if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)          { @@ -864,13 +835,14 @@ check_hello_message (BusContext     *context,        while (!dbus_bus_set_base_service (connection, name))          _dbus_wait_for_memory (); -      scd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */ -      scd.failed = FALSE; -      scd.expected_service_name = name; -      bus_test_clients_foreach (check_service_created_foreach, -                                &scd); +      socd.expected_kind = SERVICE_CREATED; +      socd.expected_service_name = name; +      socd.failed = FALSE; +      socd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */ +      bus_test_clients_foreach (check_service_owner_changed_foreach, +                                &socd); -      if (scd.failed) +      if (socd.failed)          goto out;        /* Client should also have gotten ServiceAcquired */ @@ -882,6 +854,13 @@ check_hello_message (BusContext     *context,                        "ServiceAcquired");            goto out;          } +      if (! dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, +				    "ServiceAcquired")) +        { +          _dbus_warn ("Expecting %s, got smthg else\n", +                      "ServiceAcquired"); +          goto out; +        }      retry_get_acquired_name:        if (!dbus_message_get_args (message, &error, @@ -1489,9 +1468,6 @@ check_nonexistent_service_activation (BusContext     *context,    DBusMessage *message;    dbus_uint32_t serial;    dbus_bool_t retval; -  DBusError error; -   -  dbus_error_init (&error);    message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,                                            DBUS_PATH_ORG_FREEDESKTOP_DBUS, @@ -1593,10 +1569,7 @@ check_nonexistent_service_auto_activation (BusContext     *context,    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", @@ -1690,66 +1663,87 @@ check_base_service_activated (BusContext     *context,    DBusMessage *message;    dbus_bool_t retval;    DBusError error; -  char *base_service; +  char *base_service, *base_service_from_bus, *old_owner; -  base_service = NULL;    retval = FALSE;    dbus_error_init (&error); +  base_service = NULL; +  old_owner = NULL; +  base_service_from_bus = NULL;    message = initial_message;    dbus_message_ref (message);      if (dbus_message_is_signal (message,                                DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, -                              "ServiceCreated")) +                              "ServiceOwnerChanged"))      { -      char *service_name; -      CheckServiceCreatedData scd; +      CheckServiceOwnerChangedData socd;      reget_service_name_arg: +      base_service = NULL; +      old_owner = NULL; +      base_service_from_bus = NULL; +        if (!dbus_message_get_args (message, &error, -                                  DBUS_TYPE_STRING, &service_name, +                                  DBUS_TYPE_STRING, &base_service, +				  DBUS_TYPE_STRING, &old_owner, +                                  DBUS_TYPE_STRING, &base_service_from_bus,                                    DBUS_TYPE_INVALID))          {            if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))              {                dbus_error_free (&error); +              dbus_free (base_service); +              dbus_free (old_owner); +              dbus_free (base_service_from_bus);                _dbus_wait_for_memory ();                goto reget_service_name_arg;              }            else              {                _dbus_warn ("Message %s doesn't have a service name: %s\n", -                          "ServiceCreated", +                          "ServiceOwnerChanged (creation)",                            error.message); -              dbus_error_free (&error);                goto out;              }          } -      if (*service_name != ':') +      if (*base_service != ':')          {            _dbus_warn ("Expected base service activation, got \"%s\" instead\n", -                      service_name); +                      base_service);            goto out;          } -               -      base_service = service_name; -      service_name = NULL; -       -      scd.skip_connection = connection; -      scd.failed = FALSE; -      scd.expected_service_name = base_service; -      bus_test_clients_foreach (check_service_created_foreach, -                                &scd); +          +      if (strcmp (base_service, base_service_from_bus) != 0) +	{ +          _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"\n", +                      base_service, base_service_from_bus); +          goto out; +        } + +      if (old_owner[0]) +        { +          _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"\n", +                      old_owner); +          goto out; +        } +      +      socd.expected_kind = SERVICE_CREATED; +      socd.expected_service_name = base_service; +      socd.failed = FALSE; +      socd.skip_connection = connection; +      bus_test_clients_foreach (check_service_owner_changed_foreach, +                                &socd); -      if (scd.failed) +      if (socd.failed)          goto out;      }    else      { -      warn_unexpected (connection, message, "ServiceCreated for base service"); +      warn_unexpected (connection, message, "ServiceOwnerChanged (creation) for base service");        goto out;      } @@ -1765,10 +1759,11 @@ check_base_service_activated (BusContext     *context,   out:    if (message)      dbus_message_unref (message); +  dbus_free (base_service); +  dbus_free (base_service_from_bus); +  dbus_free (old_owner); +  dbus_error_free (&error); -  if (base_service) -    dbus_free (base_service); -      return retval;  } @@ -1793,28 +1788,39 @@ check_service_activated (BusContext     *context,    if (dbus_message_is_signal (message,                                DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, -                              "ServiceCreated")) +                              "ServiceOwnerChanged"))      { -      char *service_name; -      CheckServiceCreatedData scd; +      CheckServiceOwnerChangedData socd; +      char *service_name, *base_service_from_bus, *old_owner;      reget_service_name_arg: +      service_name = NULL; +      old_owner = NULL; +      base_service_from_bus = NULL; +        if (!dbus_message_get_args (message, &error,                                    DBUS_TYPE_STRING, &service_name, + 				  DBUS_TYPE_STRING, &old_owner, +                                  DBUS_TYPE_STRING, &base_service_from_bus,                                    DBUS_TYPE_INVALID))          {            if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))              {                dbus_error_free (&error); + 	      dbus_free (service_name); + 	      dbus_free (old_owner); + 	      dbus_free (base_service_from_bus);                _dbus_wait_for_memory ();                goto reget_service_name_arg;              }            else              {                _dbus_warn ("Message %s doesn't have a service name: %s\n", -                          "ServiceCreated", +                          "ServiceOwnerChanged (creation)",                            error.message); -              dbus_error_free (&error); + 	      dbus_free (service_name); + 	      dbus_free (old_owner); + 	      dbus_free (base_service_from_bus);                goto out;              }          } @@ -1824,18 +1830,43 @@ check_service_activated (BusContext     *context,            _dbus_warn ("Expected to see service %s created, saw %s instead\n",                        activated_name, service_name);            dbus_free (service_name); +          dbus_free (old_owner); +          dbus_free (base_service_from_bus);            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) +      if (strcmp (base_service_name, base_service_from_bus) != 0) +        { +          _dbus_warn ("ServiceOwnerChanged reports wrong base service: %s owner, expected %s instead\n", +                      base_service_from_bus, base_service_name); +          dbus_free (service_name); +          dbus_free (old_owner); +          dbus_free (base_service_from_bus); +          goto out; +        } +      dbus_free (base_service_from_bus); + +      if (old_owner[0]) +        { +          _dbus_warn ("expected a %s, got a %s\n", +                      "ServiceOwnerChanged (creation)", +                      "ServiceOwnerChanged (change)"); +          dbus_free (service_name); +          dbus_free (old_owner); +          goto out; +        } +      dbus_free (old_owner); + +      socd.expected_kind = SERVICE_CREATED; +      socd.skip_connection = connection; +      socd.failed = FALSE; +      socd.expected_service_name = service_name; +      bus_test_clients_foreach (check_service_owner_changed_foreach, +                                &socd); + +      dbus_free (service_name); +           +      if (socd.failed)          goto out;        dbus_message_unref (message); @@ -1849,7 +1880,7 @@ check_service_activated (BusContext     *context,      }    else      { -      warn_unexpected (connection, message, "ServiceCreated for the activated name"); +      warn_unexpected (connection, message, "ServiceOwnerChanged for the activated name");        goto out;      } @@ -1870,7 +1901,6 @@ check_service_activated (BusContext     *context,          {            _dbus_warn ("Did not have activation result first argument to %s: %s\n",                        "ActivateService", error.message); -          dbus_error_free (&error);            goto out;          } @@ -1904,6 +1934,7 @@ check_service_activated (BusContext     *context,   out:    if (message)      dbus_message_unref (message); +  dbus_error_free (&error);    return retval;  } @@ -1928,10 +1959,10 @@ check_service_auto_activated (BusContext     *context,    if (dbus_message_is_signal (message,                                DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, -                              "ServiceCreated")) +                              "ServiceOwnerChanged"))      {        char *service_name; -      CheckServiceCreatedData scd; +      CheckServiceOwnerChangedData socd;      reget_service_name_arg:        if (!dbus_message_get_args (message, &error, @@ -1947,7 +1978,7 @@ check_service_auto_activated (BusContext     *context,            else              {                _dbus_warn ("Message %s doesn't have a service name: %s\n", -                          "ServiceCreated", +                          "ServiceOwnerChanged",                            error.message);                dbus_error_free (&error);                goto out; @@ -1962,15 +1993,16 @@ check_service_auto_activated (BusContext     *context,            goto out;          } -      scd.skip_connection = connection; -      scd.failed = FALSE; -      scd.expected_service_name = service_name; -      bus_test_clients_foreach (check_service_created_foreach, -				&scd); +      socd.expected_kind = SERVICE_CREATED; +      socd.expected_service_name = service_name; +      socd.failed = FALSE; +      socd.skip_connection = connection;  +      bus_test_clients_foreach (check_service_owner_changed_foreach, +				&socd);        dbus_free (service_name); -      if (scd.failed) +      if (socd.failed)          goto out;        /* Note that this differs from regular activation in that we don't get a @@ -1982,7 +2014,7 @@ check_service_auto_activated (BusContext     *context,      }    else      { -      warn_unexpected (connection, message, "ServiceCreated for the activated name"); +      warn_unexpected (connection, message, "ServiceOwnerChanged for the activated name");        goto out;      } @@ -2003,28 +2035,32 @@ check_service_deactivated (BusContext     *context,                             const char     *base_service)  {    dbus_bool_t retval; -  CheckServiceDeletedData csdd; +  CheckServiceOwnerChangedData socd;    retval = FALSE; -  /* Now we are expecting ServiceDeleted messages for the base +  /* Now we are expecting ServiceOwnerChanged (deletion) messages for the base     * service and the activated_name.  The base service     * notification is required to come last.     */ -  csdd.expected_service_name = activated_name; -  csdd.failed = FALSE; -  bus_test_clients_foreach (check_service_deleted_foreach, -                            &csdd);       - -  if (csdd.failed) +  socd.expected_kind = SERVICE_DELETED; +  socd.expected_service_name = activated_name; +  socd.failed = FALSE; +  socd.skip_connection = NULL; +  bus_test_clients_foreach (check_service_owner_changed_foreach, +                            &socd);       + +  if (socd.failed)      goto out; -  csdd.expected_service_name = base_service; -  csdd.failed = FALSE; -  bus_test_clients_foreach (check_service_deleted_foreach, -                            &csdd); - -  if (csdd.failed) +  socd.expected_kind = SERVICE_DELETED; +  socd.expected_service_name = base_service; +  socd.failed = FALSE; +  socd.skip_connection = NULL; +  bus_test_clients_foreach (check_service_owner_changed_foreach, +                            &socd); + +  if (socd.failed)      goto out;    retval = TRUE; @@ -2244,6 +2280,73 @@ check_got_error (BusContext     *context,    return retval;  } +typedef enum +{  +  GOT_SERVICE_CREATED, +  GOT_SERVICE_DELETED, +  GOT_ERROR, +  GOT_SOMETHING_ELSE  +} GotServiceInfo; + +static GotServiceInfo +check_got_service_info (DBusMessage *message) +{ +  GotServiceInfo message_kind; + +  if (dbus_message_is_signal (message, +                              DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, +                              "ServiceOwnerChanged")) +    { +      DBusError error; +      char *service_name, *old_owner, *new_owner; +      dbus_error_init (&error); + +    reget_service_info_data: +      service_name = NULL; +      old_owner = NULL; +      new_owner = NULL; + +      dbus_message_get_args (message, &error, +                             DBUS_TYPE_STRING, &service_name, +                             DBUS_TYPE_STRING, &old_owner, +                             DBUS_TYPE_STRING, &new_owner, +                             DBUS_TYPE_INVALID); +      if (dbus_error_is_set (&error)) +        { +          if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) +            { +              dbus_error_free (&error); +              dbus_free (service_name); +              dbus_free (old_owner); +              dbus_free (new_owner); +              goto reget_service_info_data; +            } +          else +            { +              _dbus_warn ("unexpected arguments for ServiceOwnerChanged message"); +              message_kind = GOT_SOMETHING_ELSE; +            } +        } +      else if (!old_owner[0]) +        message_kind = GOT_SERVICE_CREATED; +      else if (!new_owner[0]) +        message_kind = GOT_SERVICE_DELETED; +      else +        message_kind = GOT_SOMETHING_ELSE; + +      dbus_free (service_name); +      dbus_free (old_owner); +      dbus_free (new_owner); +      dbus_error_free (&error); +    } +  else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) +    message_kind = GOT_ERROR; +  else +    message_kind = GOT_SOMETHING_ELSE; + +  return message_kind; +} +  #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"  /* returns TRUE if the correct thing happens, @@ -2256,13 +2359,10 @@ check_existent_service_activation (BusContext     *context,    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 (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,                                            DBUS_PATH_ORG_FREEDESKTOP_DBUS,                                            DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, @@ -2348,8 +2448,7 @@ check_existent_service_activation (BusContext     *context,      }    else      { -      dbus_bool_t got_service_deleted; -      dbus_bool_t got_error; +      GotServiceInfo message_kind;        if (!check_base_service_activated (context, connection,                                           message, &base_service)) @@ -2368,65 +2467,72 @@ check_existent_service_activation (BusContext     *context,            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; -       +      message_kind = check_got_service_info (message); +        dbus_connection_return_message (connection, message);        message = NULL; -      if (got_error) -        { +      switch (message_kind) +	{ +	case GOT_SOMETHING_ELSE: +          _dbus_warn ("Unexpected message after ActivateService " +                      "(should be an error or a service announcement"); +	  goto out; + +	case 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; +	  /* fall through */ -          /* 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); +	case GOT_SERVICE_DELETED: +	  { +	    /* The service started up and got a base address, but then +	     * failed to register under EXISTENT_SERVICE_NAME +	     */ +	    CheckServiceOwnerChangedData socd; + +	    socd.expected_kind = SERVICE_DELETED; +	    socd.expected_service_name = base_service; +	    socd.failed = FALSE; +	    socd.skip_connection = NULL; +	     +	    bus_test_clients_foreach (check_service_owner_changed_foreach, +				      &socd); + +	    if (socd.failed) +	      goto out; + +	    /* Now we should get an error about the service exiting +	     * if we didn't get it before. +	     */ +	    if (message_kind != GOT_ERROR) +	      { +		block_connection_until_message_from_bus (context, connection); -              /* and process everything again */ -              bus_test_run_everything (context); +		/* and process everything again */ +		bus_test_run_everything (context); -              if (!check_got_error (context, connection, -                                    DBUS_ERROR_SPAWN_CHILD_EXITED, -                                    NULL)) -                goto out; -            } -        } -      else -        { +		if (!check_got_error (context, connection, +				      DBUS_ERROR_SPAWN_CHILD_EXITED, +				      NULL)) +		  goto out; +	      } +	    break; +	  } + +	case GOT_SERVICE_CREATED:            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"); +              _dbus_warn ("Failed to pop message we just put back! " +			  "should have been a ServiceOwnerChanged (creation)\n");                goto out;              } @@ -2437,7 +2543,6 @@ check_existent_service_activation (BusContext     *context,            dbus_message_unref (message);            message = NULL; -            if (!check_no_leftovers (context))              {                _dbus_warn ("Messages were left over after successful activation\n"); @@ -2447,9 +2552,11 @@ check_existent_service_activation (BusContext     *context,            if (!check_send_exit_to_service (context, connection,                                             EXISTENT_SERVICE_NAME, base_service))              goto out; -        } + +	  break; +	}      } -   +    retval = TRUE;   out: @@ -2472,9 +2579,6 @@ check_segfault_service_activation (BusContext     *context,    DBusMessage *message;    dbus_uint32_t serial;    dbus_bool_t retval; -  DBusError error; -   -  dbus_error_init (&error);    message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,                                            DBUS_PATH_ORG_FREEDESKTOP_DBUS, @@ -2578,11 +2682,6 @@ check_segfault_service_auto_activation (BusContext     *context,    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", @@ -2679,13 +2778,10 @@ check_existent_service_auto_activation (BusContext     *context,    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", @@ -2729,7 +2825,6 @@ check_existent_service_auto_activation (BusContext     *context,    retval = FALSE; -  /* Should get ServiceCreated for the base service, or an error. */    message = pop_message_waiting_for_memory (connection);    if (message == NULL)      { @@ -2739,38 +2834,13 @@ check_existent_service_auto_activation (BusContext     *context,      }    verbose_message_received (connection, message); -  _dbus_verbose ("  (after sending %s)\n", "ActivateService"); +  _dbus_verbose ("  (after sending %s)\n", "auto activation"); -  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) +  /* we should get zero or two ServiceOwnerChanged signals */ +  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)      { -      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; -        } +      GotServiceInfo message_kind; -      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; @@ -2781,113 +2851,101 @@ check_existent_service_auto_activation (BusContext     *context,        /* 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. +      /* Should get a service creation notification for the activated +       * service name, or a service deletion on the base service name         */        message = dbus_connection_borrow_message (connection);        if (message == NULL)          { -          _dbus_warn ("Did not receive any messages after base service creation notification\n"); +	  _dbus_warn ("No message after auto activation " +		      "(should be a service announcement)"); +	  dbus_connection_return_message (connection, message); +	  message = NULL;            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; +      message_kind = check_got_service_info (message);        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 -        { +      switch (message_kind)  +	{ +	case GOT_SERVICE_CREATED:  	  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, +	    { +	      _dbus_warn ("Failed to pop message we just put back! " +			  "should have been a ServiceOwnerChanged (creation)\n"); +	      goto out; +	    } +	     +	  /* Check that ServiceOwnerChanged (creation) was correctly received */ +	  if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME,  					     base_service, message)) -            goto out; +	    goto out; +	   +	  dbus_message_unref (message); +	  message = NULL; -          dbus_message_unref (message); -          message = NULL; -	} +	  break; -      /* 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; -	} +	case GOT_SERVICE_DELETED: +	  { +	    /* The service started up and got a base address, but then +	     * failed to register under EXISTENT_SERVICE_NAME +	     */ +	    CheckServiceOwnerChangedData socd; +           +	    socd.expected_kind = SERVICE_DELETED; +	    socd.expected_service_name = base_service; +	    socd.failed = FALSE; +	    socd.skip_connection = NULL; +	    bus_test_clients_foreach (check_service_owner_changed_foreach, +				      &socd); + +	    if (socd.failed) +	      goto out; -      if (dbus_message_get_reply_serial (message) != serial) -	{ -	  _dbus_warn ("Wrong reply serial\n"); +	    break; +	  } + +        case GOT_ERROR: +	case GOT_SOMETHING_ELSE: +	  _dbus_warn ("Unexpected message after auto activation\n");  	  goto out;  	} +    } -      dbus_message_unref (message); -      message = NULL; +  /* OK, now we've dealt with ServiceOwnerChanged signals, now should +   * come the method reply (or error) from the initial method call +   */ + +  /* 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); -      if (!check_send_exit_to_service (context, connection, -				       EXISTENT_SERVICE_NAME, -				       base_service)) -	goto out; +  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; diff --git a/bus/driver.c b/bus/driver.c index 39d8b126..b426912f 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -39,20 +39,25 @@ static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,                                                      DBusError      *error);  dbus_bool_t -bus_driver_send_service_deleted (const char     *service_name, -                                 BusTransaction *transaction, -                                 DBusError      *error) +bus_driver_send_service_owner_changed (const char     *service_name, +				       const char     *old_owner, +				       const char     *new_owner, +				       BusTransaction *transaction, +				       DBusError      *error)  {    DBusMessage *message;    dbus_bool_t retval; +  const char null_service[] = { '\000' };    _DBUS_ASSERT_ERROR_IS_CLEAR (error); -  _dbus_verbose ("sending service deleted: %s\n", service_name); +  _dbus_verbose ("sending service owner changed: %s [%s -> %s]", service_name,  +                 old_owner ? old_owner : null_service,  +                 new_owner ? new_owner : null_service);    message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,                                       DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, -                                     "ServiceDeleted"); +                                     "ServiceOwnerChanged");    if (message == NULL)      { @@ -60,62 +65,25 @@ bus_driver_send_service_deleted (const char     *service_name,        return FALSE;      } -  if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) || -      !dbus_message_append_args (message, +  if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) +    goto oom; + +  if (!dbus_message_append_args (message,                                   DBUS_TYPE_STRING, service_name, +                                 DBUS_TYPE_STRING, old_owner ? old_owner : null_service, +                                 DBUS_TYPE_STRING, new_owner ? new_owner : null_service,                                   DBUS_TYPE_INVALID)) -    { -      dbus_message_unref (message); -      BUS_SET_OOM (error); -      return FALSE; -    } +    goto oom;    retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);    dbus_message_unref (message);    return retval; -} -dbus_bool_t -bus_driver_send_service_created (const char     *service_name, -                                 BusTransaction *transaction, -                                 DBusError      *error) -{ -  DBusMessage *message; -  dbus_bool_t retval; - -  _DBUS_ASSERT_ERROR_IS_CLEAR (error); -   -  message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS, -                                     DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, -                                     "ServiceCreated"); -   -  if (message == NULL) -    { -      BUS_SET_OOM (error); -      return FALSE; -    } -   -  if (!dbus_message_set_sender (message, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS)) -    { -      dbus_message_unref (message); -      BUS_SET_OOM (error); -      return FALSE; -    } -   -  if (!dbus_message_append_args (message, -                                 DBUS_TYPE_STRING, service_name, -                                 DBUS_TYPE_INVALID)) -    { -      dbus_message_unref (message); -      BUS_SET_OOM (error); -      return FALSE; -    } -   -  retval = bus_dispatch_matches (transaction, NULL, NULL, message, error); + oom:    dbus_message_unref (message); - -  return retval; +  BUS_SET_OOM (error); +  return FALSE;  }  dbus_bool_t diff --git a/bus/driver.h b/bus/driver.h index f971838a..bc430520 100644 --- a/bus/driver.h +++ b/bus/driver.h @@ -32,9 +32,6 @@ dbus_bool_t bus_driver_handle_message        (DBusConnection *connection,                                                BusTransaction *transaction,                                                DBusMessage    *message,                                                DBusError      *error); -dbus_bool_t bus_driver_send_service_deleted  (const char     *service_name, -                                              BusTransaction *transaction, -                                              DBusError      *error);  dbus_bool_t bus_driver_send_service_lost     (DBusConnection *connection,                                                const char     *service_name,                                                BusTransaction *transaction, @@ -43,8 +40,10 @@ dbus_bool_t bus_driver_send_service_acquired (DBusConnection *connection,                                                const char     *service_name,                                                BusTransaction *transaction,                                                DBusError      *error); -dbus_bool_t bus_driver_send_service_created  (const char     *service_name, -                                              BusTransaction *transaction, -                                              DBusError      *error); +dbus_bool_t bus_driver_send_service_owner_changed  (const char     *service_name, +						    const char     *old_owner, +						    const char     *new_owner, +						    BusTransaction *transaction, +						    DBusError      *error);  #endif /* BUS_DRIVER_H */ diff --git a/bus/services.c b/bus/services.c index f5ef4cc2..0ba3225d 100644 --- a/bus/services.c +++ b/bus/services.c @@ -164,7 +164,10 @@ bus_registry_ensure (BusRegistry               *registry,        return NULL;      } -  if (!bus_driver_send_service_created (service->name, transaction, error)) +  if (!bus_driver_send_service_owner_changed (service->name,  +					      NULL, +					      bus_connection_get_name (owner_if_created), +					      transaction, error))      {        bus_service_unref (service);        return NULL; @@ -726,20 +729,31 @@ bus_service_remove_owner (BusService     *service,      }    else if (_dbus_list_length_is_one (&service->owners))      { -      if (!bus_driver_send_service_deleted (service->name, -                                            transaction, error)) +      if (!bus_driver_send_service_owner_changed (service->name, + 						  bus_connection_get_name (owner), + 						  NULL, + 						  transaction, error))          return FALSE;      }    else      {        DBusList *link; +      DBusConnection *new_owner;        link = _dbus_list_get_first_link (&service->owners);        _dbus_assert (link != NULL);        link = _dbus_list_get_next_link (&service->owners, link);        _dbus_assert (link != NULL); +      new_owner = link->data; + +      if (!bus_driver_send_service_owner_changed (service->name, + 						  bus_connection_get_name (owner), + 						  bus_connection_get_name (new_owner), + 						  transaction, error)) +        return FALSE; +        /* This will be our new owner */ -      if (!bus_driver_send_service_acquired (link->data, +      if (!bus_driver_send_service_acquired (new_owner,                                               service->name,                                               transaction,                                               error)) diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index f0d1727e..4793278f 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -2277,19 +2277,14 @@          <para>            This message is sent to a specific application when it loses primary            ownership of a service. - -          [FIXME instead of ServiceLost/ServiceCreated going only to  -          a specific app, why not just OwnerChanged that covers both  -          lost and created and changed owner and deleted]          </para>        </sect3> -      <sect3 id="bus-messages-service-created"> -        <title><literal>org.freedesktop.DBus.ServiceCreated</literal></title> +      <sect3 id="bus-messages-service-owner-changed"> +        <title><literal>org.freedesktop.DBus.ServiceOwnerChanged</literal></title>          <para> -          As a method:            <programlisting> -            ServiceCreated (in STRING service_name) +            ServiceOwnerChanged (STRING service_name, STRING old_owner, STRING new_owner)            </programlisting>            Message arguments:            <informaltable> @@ -2309,46 +2304,15 @@                  </row>  	        <row>  		  <entry>1</entry> -		  <entry>UINT32</entry> -		  <entry>Flags</entry> +		  <entry>STRING</entry> +		  <entry>Base service of previous owner, empty string if the +		  service is newly created</entry>  	        </row> -              </tbody> -            </tgroup> -          </informaltable> -        </para> -        <para> -          This message is broadcast to all applications when a service has been -          successfully registered on the message bus. -        </para> -      </sect3> - -      <sect3 id="bus-messages-service-deleted"> -        <title><literal>org.freedesktop.DBus.ServiceDeleted</literal></title> -        <para> -          As a method: -          <programlisting> -            ServiceDeleted (in STRING service_name) -          </programlisting> -          Message arguments: -          <informaltable> -            <tgroup cols="3"> -              <thead> -                <row> -                  <entry>Argument</entry> -                  <entry>Type</entry> -                  <entry>Description</entry> -                </row> -              </thead> -              <tbody> -                <row> -                  <entry>0</entry> -                  <entry>STRING</entry> -                  <entry>Name of the service</entry> -                </row>  	        <row> -		  <entry>1</entry> -		  <entry>UINT32</entry> -		  <entry>Flags</entry> +		  <entry>2</entry> +		  <entry>STRING</entry> +		  <entry>Base service of new owner, empty string if the +		  service is no longer available</entry>  	        </row>                </tbody>              </tgroup> @@ -2356,7 +2320,8 @@          </para>          <para>            This message is broadcast to all applications when a service has been -          deleted from the message bus. +          successfully registered on the message bus, has been deleted +          or its primary owner has changed.          </para>        </sect3>  | 
