diff options
| author | Colin Walters <walters@verbum.org> | 2005-06-30 18:22:10 +0000 | 
|---|---|---|
| committer | Colin Walters <walters@verbum.org> | 2005-06-30 18:22:10 +0000 | 
| commit | 03d040311afd4b988b9a277a8aa360fa20243c92 (patch) | |
| tree | 727854d43f1bc8b3757ce198675f12751edc85c1 | |
| parent | b3c42d226438fd0fda2db19b92944dec5e226d3f (diff) | |
2005-06-30  Colin Walters  <walters@verbum.org>
	* test/glib/test-dbus-glib.c:
	* test/glib/test-service-glib.c:
	* test/glib/test-service-glib.xml: Update tests for new error
	setting bits, also add async tests (patch from Ross Burton).
	* test/glib/Makefile.am (test_service_glib_LDADD): Add
	DBUS_GLIB_THREADS_LIBS.
	* glib/dbus-gproxy.c (get_name_owner)
	(dbus_g_pending_call_end_valist): Ditto.
	* glib/dbus-gobject.c (error_metadata): New mapping from GError
	domain (GQuark) to DBusGErrorInfo.
	(gerror_domaincode_to_dbus_error_name): Attempt to look up error
	quark in error_metadata.  Take message interface as default
	error message interface.
	(gerror_to_dbus_error_message): Pass message interface.
	(dbus_set_g_error): Resurrected.
	(dbus_g_error_info_free): New function.
	(dbus_g_object_type_install_info): Use g_type_class_ref instead
	of _peek to actually create the object class if it hasn't been
	created yet.
	(dbus_g_error_domain_register): New function.
	* glib/dbus-gmain.c (dbus_g_bus_get): Switch to dbus_set_g_error.
	* glib/dbus-gparser.c (validate_signature): Ditto.
	* dbus/dbus-glib.h (dbus_g_error_set): Delete.
	(dbus_g_error_domain_register): Prototype.
	* glib/dbus-glib.c (dbus_g_error_set): Delete.
	Update tests.
| -rw-r--r-- | ChangeLog | 36 | ||||
| -rw-r--r-- | dbus/dbus-glib.h | 7 | ||||
| -rw-r--r-- | glib/dbus-glib.c | 45 | ||||
| -rw-r--r-- | glib/dbus-gmain.c | 3 | ||||
| -rw-r--r-- | glib/dbus-gobject.c | 127 | ||||
| -rw-r--r-- | glib/dbus-gparser.c | 3 | ||||
| -rw-r--r-- | glib/dbus-gproxy.c | 6 | ||||
| -rw-r--r-- | test/glib/Makefile.am | 2 | ||||
| -rw-r--r-- | test/glib/test-dbus-glib.c | 16 | ||||
| -rw-r--r-- | test/glib/test-service-glib.c | 99 | ||||
| -rw-r--r-- | test/glib/test-service-glib.xml | 10 | 
11 files changed, 293 insertions, 61 deletions
@@ -1,3 +1,39 @@ +2005-06-30  Colin Walters  <walters@verbum.org> + +	* test/glib/test-dbus-glib.c: +	* test/glib/test-service-glib.c: +	* test/glib/test-service-glib.xml: Update tests for new error +	setting bits, also add async tests (patch from Ross Burton). + +	* test/glib/Makefile.am (test_service_glib_LDADD): Add +	DBUS_GLIB_THREADS_LIBS. + +	* glib/dbus-gproxy.c (get_name_owner) +	(dbus_g_pending_call_end_valist): Ditto. + +	* glib/dbus-gobject.c (error_metadata): New mapping from GError +	domain (GQuark) to DBusGErrorInfo.   +	(gerror_domaincode_to_dbus_error_name): Attempt to look up error +	quark in error_metadata.  Take message interface as default +	error message interface. +	(gerror_to_dbus_error_message): Pass message interface. +	(dbus_set_g_error): Resurrected. +	(dbus_g_error_info_free): New function. +	(dbus_g_object_type_install_info): Use g_type_class_ref instead +	of _peek to actually create the object class if it hasn't been +	created yet. +	(dbus_g_error_domain_register): New function. + +	* glib/dbus-gmain.c (dbus_g_bus_get): Switch to dbus_set_g_error. + +	* glib/dbus-gparser.c (validate_signature): Ditto. + +	* dbus/dbus-glib.h (dbus_g_error_set): Delete. +	(dbus_g_error_domain_register): Prototype. + +	* glib/dbus-glib.c (dbus_g_error_set): Delete. +	Update tests. +  2005-06-29  Colin Walters  <walters@verbum.org>  	* dbus/dbus-glib.h: Delete DBUS_TYPE_G_PROXY_ARRAY.  Add diff --git a/dbus/dbus-glib.h b/dbus/dbus-glib.h index 5e791e01..41b3d9c1 100644 --- a/dbus/dbus-glib.h +++ b/dbus/dbus-glib.h @@ -81,9 +81,6 @@ typedef enum  #include <dbus/dbus-glib-error-enum.h>      } DBusGError; -void             dbus_g_error_set         (GError     **error, -					   const char  *name, -					   const char  *msg);  gboolean         dbus_g_error_has_name    (GError      *error,  					   const char  *name);  const char *     dbus_g_error_get_name    (GError      *error); @@ -126,6 +123,10 @@ struct _DBusGObjectInfo  void       dbus_g_object_type_install_info     (GType                 object_type,                                                  const DBusGObjectInfo *info); +void       dbus_g_error_domain_register        (GQuark                domain, +						const char *          default_iface, +						GType                 code_enum); +  void       dbus_g_connection_register_g_object (DBusGConnection       *connection,  						const char            *at_path,  						GObject               *object); diff --git a/glib/dbus-glib.c b/glib/dbus-glib.c index 3153deef..5b30ce7a 100644 --- a/glib/dbus-glib.c +++ b/glib/dbus-glib.c @@ -26,6 +26,7 @@  #include <dbus/dbus-glib-lowlevel.h>  #include "dbus-gtest.h"  #include "dbus-gutils.h" +#include "dbus-gobject.h"  #include <string.h>  #include <libintl.h> @@ -149,41 +150,6 @@ dbus_g_error_quark (void)    return quark;  } -#include "dbus-glib-error-switch.h" - -/** - * Set a GError return location from a D-BUS error name and message. - * This function should only be used in the implementation of service - * methods. - * - * @param gerror location to store a GError, or #NULL - * @param name the D-BUS error name - * @param msg the D-BUS error detailed message - */ -void -dbus_g_error_set (GError    **gerror, -                  const char *name, -		  const char *msg) -{ -  int code; -  g_return_if_fail (name != NULL); -  g_return_if_fail (msg != NULL); - -  code = dbus_error_to_gerror_code (name); -  if (code == DBUS_GERROR_REMOTE_EXCEPTION) -    g_set_error (gerror, DBUS_GERROR, -		 code, -		 "%s%c%s", -		 msg, -		 '\0', -		 name); -  else -    g_set_error (gerror, DBUS_GERROR, -		 code, -		 "%s", -		 msg); -} -  /**   * Determine whether D-BUS error name for a remote exception matches   * the given name.  This function is intended to be invoked on a @@ -463,7 +429,7 @@ _dbus_glib_test (const char *test_data_dir)    dbus_error_init (&err);    dbus_set_error_const (&err, DBUS_ERROR_NO_MEMORY, "Out of memory!"); -  dbus_g_error_set (&gerror, err.name, err.message); +  dbus_set_g_error (&gerror, &err);    g_assert (gerror != NULL);    g_assert (gerror->domain == DBUS_GERROR);    g_assert (gerror->code == DBUS_GERROR_NO_MEMORY); @@ -472,13 +438,6 @@ _dbus_glib_test (const char *test_data_dir)    dbus_error_init (&err);    g_clear_error (&gerror); -  dbus_g_error_set (&gerror, "com.example.Foo.BlahFailed", "blah failed"); -  g_assert (gerror != NULL); -  g_assert (gerror->domain == DBUS_GERROR); -  g_assert (gerror->code == DBUS_GERROR_REMOTE_EXCEPTION); -  g_assert (dbus_g_error_has_name (gerror, "com.example.Foo.BlahFailed")); -  g_assert (!strcmp (gerror->message, "blah failed")); -    return TRUE;  } diff --git a/glib/dbus-gmain.c b/glib/dbus-gmain.c index 6d3b56c8..9d45ca0e 100644 --- a/glib/dbus-gmain.c +++ b/glib/dbus-gmain.c @@ -28,6 +28,7 @@  #include "dbus-gtest.h"  #include "dbus-gutils.h"  #include "dbus-gvalue.h" +#include "dbus-gobject.h"  #include "dbus-gvalue-utils.h"  #include <string.h> @@ -720,7 +721,7 @@ dbus_g_bus_get (DBusBusType     type,    connection = dbus_bus_get (type, &derror);    if (connection == NULL)      { -      dbus_g_error_set (error, derror.name, derror.message); +      dbus_set_g_error (error, &derror);        dbus_error_free (&derror);        return NULL;      } diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c index 8e399796..c91f1851 100644 --- a/glib/dbus-gobject.c +++ b/glib/dbus-gobject.c @@ -39,9 +39,16 @@   * @{   */ +typedef struct +{ +  char *default_iface; +  GType code_enum; +} DBusGErrorInfo; +  static GStaticRWLock globals_lock = G_STATIC_RW_LOCK_INIT;  static GHashTable *info_hash = NULL;  static GHashTable *marshal_table = NULL; +static GData *error_metadata = NULL;  static char*  uscore_to_wincaps (const char *uscore) @@ -696,6 +703,7 @@ lookup_object_and_method (GObject      *object,  static char *  gerror_domaincode_to_dbus_error_name (const DBusGObjectInfo *object_info, +				      const char *msg_interface,  				      GQuark domain, gint code)  {    const char *domain_str; @@ -707,6 +715,36 @@ gerror_domaincode_to_dbus_error_name (const DBusGObjectInfo *object_info,    if (!domain_str || !code_str)      { +      DBusGErrorInfo *info; + +      g_static_rw_lock_reader_lock (&globals_lock); + +      if (error_metadata != NULL) +	info = g_datalist_id_get_data (&error_metadata, domain); +      else +	info = NULL; + +      g_static_rw_lock_reader_unlock (&globals_lock); + +      if (info) +	{ +	  GEnumValue *value; +	  GEnumClass *klass; + +	  klass = g_type_class_ref (info->code_enum); +	  value = g_enum_get_value (klass, code); +	  g_type_class_unref (klass); + +	  domain_str = info->default_iface; +	  code_str = value->value_nick; +	} +    } + +  if (!domain_str) +    domain_str = msg_interface; + +  if (!domain_str || !code_str) +    {        /* If we can't map it sensibly, make up an error name */        char *domain_from_quark; @@ -752,7 +790,9 @@ gerror_to_dbus_error_message (const DBusGObjectInfo *object_info,        else  	{  	  char *error_name; -	  error_name = gerror_domaincode_to_dbus_error_name (object_info, error->domain, error->code); +	  error_name = gerror_domaincode_to_dbus_error_name (object_info, +							     dbus_message_get_interface (message), +							     error->domain, error->code);  	  reply = dbus_message_new_error (message, error_name, error->message);  	  g_free (error_name);   	} @@ -1256,6 +1296,40 @@ export_signals (DBusGConnection *connection, const DBusGObjectInfo *info, GObjec      }  } +#include "dbus-glib-error-switch.h" + +void +dbus_set_g_error (GError    **gerror, +		  DBusError  *error) +{ +  int code; + +  code = dbus_error_to_gerror_code (error->name); +  if (code != DBUS_GERROR_REMOTE_EXCEPTION) +    g_set_error (gerror, DBUS_GERROR, +		 code, +		 "%s", +		 error->message); +  else +    g_set_error (gerror, DBUS_GERROR, +		 code, +		 "%s%c%s", +		 error->message, +		 '\0', +		 error->name); +} + +static void +dbus_g_error_info_free (gpointer p) +{ +  DBusGErrorInfo *info; + +  info = p; + +  g_free (info->default_iface); +  g_free (info); +} +  /** @} */ /* end of internals */  /** @@ -1287,7 +1361,7 @@ dbus_g_object_type_install_info (GType                  object_type,    dbus_g_value_types_init (); -  object_class = g_type_class_peek (object_type); +  object_class = g_type_class_ref (object_type);    g_return_if_fail (G_IS_OBJECT_CLASS (object_class)); @@ -1301,6 +1375,55 @@ dbus_g_object_type_install_info (GType                  object_type,    g_hash_table_replace (info_hash, object_class, (void*) info);    g_static_rw_lock_writer_unlock (&globals_lock); + +  g_type_class_unref (object_class); +} + +/** + * Register a GError domain and set of codes with D-BUS.  You must + * have created a GEnum for the error codes.  This function will not + * be needed with an introspection-capable GLib. + * + * @param domain the GError domain  + * @param default_iface the D-BUS interface used for error values by default, or #NULL + * @param code_enum a GType for a GEnum of the error codes + */ +void +dbus_g_error_domain_register (GQuark                domain, +			      const char           *default_iface, +			      GType                 code_enum) +{ +  DBusGErrorInfo *info; +   +  g_return_if_fail (g_quark_to_string (domain) != NULL); +  g_return_if_fail (code_enum != G_TYPE_INVALID); +  g_return_if_fail (G_TYPE_FUNDAMENTAL (code_enum) == G_TYPE_ENUM); + +  g_static_rw_lock_writer_lock (&globals_lock); + +  if (error_metadata == NULL) +    g_datalist_init (&error_metadata); + +  info = g_datalist_id_get_data (&error_metadata, domain); + +  if (info != NULL) +    { +      g_warning ("Metadata for error domain \"%s\" already registered\n", +		 g_quark_to_string (domain)); +    } +  else +    { +      info = g_new0 (DBusGErrorInfo, 1); +      info->default_iface = g_strdup (default_iface); +      info->code_enum = code_enum; + +      g_datalist_id_set_data_full (&error_metadata, +				   domain, +				   info, +				   dbus_g_error_info_free); +    } + +  g_static_rw_lock_writer_unlock (&globals_lock);  }  static void diff --git a/glib/dbus-gparser.c b/glib/dbus-gparser.c index 90798b19..daf9bc8e 100644 --- a/glib/dbus-gparser.c +++ b/glib/dbus-gparser.c @@ -23,6 +23,7 @@  #include "dbus-gparser.h"  #include "dbus/dbus-glib-lowlevel.h"  #include "dbus-gidl.h" +#include "dbus-gobject.h"  #include "dbus/dbus-signature.h"  #include <string.h> @@ -474,7 +475,7 @@ validate_signature (const char *str,    if (!dbus_signature_validate (str, &derror))      { -      dbus_g_error_set (error, derror.name, derror.message); +      dbus_set_g_error (&derror, error);        return FALSE;      }    return TRUE; diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 9ea4c16c..91cda82f 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -818,7 +818,7 @@ get_name_owner (DBusConnection     *connection,   error:    g_assert (dbus_error_is_set (&derror)); -  dbus_g_error_set (error, derror.name, derror.message); +  dbus_set_g_error (error, &derror);    dbus_error_free (&derror);   out: @@ -2009,14 +2009,14 @@ dbus_g_pending_call_end_valist (DBusGConnection   *connection,        break;      case DBUS_MESSAGE_TYPE_ERROR:        dbus_set_error_from_message (&derror, reply); -      dbus_g_error_set (error, derror.name, derror.message); +      dbus_set_g_error (error, &derror);        dbus_error_free (&derror);        goto out;        break;      default:        dbus_set_error (&derror, DBUS_ERROR_FAILED,                        "Reply was neither a method return nor an exception"); -      dbus_g_error_set (error, derror.name, derror.message); +      dbus_set_g_error (error, &derror);        dbus_error_free (&derror);        goto out;        break; diff --git a/test/glib/Makefile.am b/test/glib/Makefile.am index 77ee1906..04d9c644 100644 --- a/test/glib/Makefile.am +++ b/test/glib/Makefile.am @@ -61,7 +61,7 @@ my-object-marshal.h: Makefile my-object-marshal.list  CLEANFILES = $(BUILT_SOURCES) -test_service_glib_LDADD= $(top_builddir)/glib/libdbus-glib-1.la +test_service_glib_LDADD= $(top_builddir)/glib/libdbus-glib-1.la $(DBUS_GLIB_THREADS_LIBS)   else  ### not building tests diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c index e8cb74af..fd71d743 100644 --- a/test/glib/test-dbus-glib.c +++ b/test/glib/test-dbus-glib.c @@ -441,7 +441,8 @@ main (int argc, char **argv)    if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID) != FALSE)      lose ("ThrowError call unexpectedly succeeded!");    if (!dbus_g_error_has_name (error, "org.freedesktop.DBus.Tests.MyObject.Foo")) -    lose ("ThrowError call returned unexpected error %s", dbus_g_error_get_name (error)); +    lose ("ThrowError call returned unexpected error \"%s\": %s", dbus_g_error_get_name (error), +	  error->message);    g_print ("ThrowError failed (as expected) returned error: %s\n", error->message);    g_clear_error (&error); @@ -490,6 +491,13 @@ main (int argc, char **argv)    if (v_UINT32_2 != 43)      lose ("(wrapped) increment call returned %d, should be 43", v_UINT32_2); +  v_UINT32_2 = 0; +  if (!org_freedesktop_DBus_Tests_MyObject_async_increment (proxy, 42, &v_UINT32_2, &error)) +    lose_gerror ("Failed to complete (wrapped) AsyncIncrement call", error); + +  if (v_UINT32_2 != 43) +    lose ("(wrapped) async increment call returned %d, should be 43", v_UINT32_2); +    g_print ("Calling (wrapped) throw_error\n");    if (org_freedesktop_DBus_Tests_MyObject_throw_error (proxy, &error) != FALSE)      lose ("(wrapped) ThrowError call unexpectedly succeeded!"); @@ -497,6 +505,12 @@ main (int argc, char **argv)    g_print ("(wrapped) ThrowError failed (as expected) returned error: %s\n", error->message);    g_clear_error (&error); +  if (org_freedesktop_DBus_Tests_MyObject_async_throw_error (proxy, &error) != FALSE) +    lose ("(wrapped) AsyncThrowError call unexpectedly succeeded!"); + +  g_print ("(wrapped) AsyncThrowError failed (as expected) returned error: %s\n", error->message); +  g_clear_error (&error); +    g_print ("Calling (wrapped) uppercase\n");    if (!org_freedesktop_DBus_Tests_MyObject_uppercase (proxy, "foobar", &v_STRING_2, &error))       lose_gerror ("Failed to complete (wrapped) Uppercase call", error); diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c index 9d5dfcc8..84b57c68 100644 --- a/test/glib/test-service-glib.c +++ b/test/glib/test-service-glib.c @@ -44,7 +44,9 @@ typedef enum    MY_OBJECT_ERROR_BAR  } MyObjectError; -#define MY_OBJECT_ERROR my_object_error_quark () +#define MY_OBJECT_ERROR (my_object_error_quark ()) + +#define MY_TYPE_ERROR (my_object_error_get_type ())   gboolean my_object_do_nothing (MyObject *obj, GError **error); @@ -85,10 +87,16 @@ gboolean my_object_emit_frobnicate (MyObject *obj, GError **error);  gboolean my_object_terminate (MyObject *obj, GError **error); +gboolean my_object_async_increment (MyObject *obj, gint32 x, DBusGMethodInvocation *context); + +gboolean my_object_async_throw_error (MyObject *obj, DBusGMethodInvocation *context); +  #include "test-service-glib-glue.h"  GQuark my_object_error_quark (void); +GType my_object_error_get_type (void); +  /* Properties */  enum  { @@ -231,6 +239,30 @@ my_object_error_quark (void)    return quark;  } +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +my_object_error_get_type (void) +{ +	static GType etype = 0; + +	if (etype == 0) +	{ +		static const GEnumValue values[] = +		{ + +			ENUM_ENTRY (MY_OBJECT_ERROR_FOO, "Foo"), +			ENUM_ENTRY (MY_OBJECT_ERROR_BAR, "Bar"), +			{ 0, 0, 0 } +		}; + +		etype = g_enum_register_static ("MyObjectError", values); +	} + +	return etype; +} +  static GObject *obj;  static GObject *obj2; @@ -250,9 +282,11 @@ my_object_increment (MyObject *obj, gint32 x, gint32 *ret, GError **error)  gboolean  my_object_throw_error (MyObject *obj, GError **error)  { -  dbus_g_error_set (error, -		    "org.freedesktop.DBus.Tests.MyObject.Foo", -		    "this method always loses");     +  g_set_error (error, +	       MY_OBJECT_ERROR, +	       MY_OBJECT_ERROR_FOO, +	       "%s", +	       "this method always loses");        return FALSE;  } @@ -464,6 +498,53 @@ my_object_emit_signal2 (MyObject *obj, GError **error)    return TRUE;  } +typedef struct { +  gint32 x; +  DBusGMethodInvocation *context; +} IncrementData; + +static gboolean +do_async_increment (IncrementData *data) +{ +  gint32 newx = data->x + 1; +  dbus_g_method_return (data->context, newx); +  g_free (data); +  return FALSE; +} + +gboolean +my_object_async_increment (MyObject *obj, gint32 x, DBusGMethodInvocation *context) +{ +  IncrementData *data = g_new0 (IncrementData, 1); +  data->x = x; +  data->context = context; +  g_idle_add ((GSourceFunc)do_async_increment, data); +  return TRUE; +} + +static gboolean +do_async_error (IncrementData *data) +{ +  GError *error; +  error = g_error_new (MY_OBJECT_ERROR, +		       MY_OBJECT_ERROR_FOO, +		       "%s", +		       "this method always loses"); +  dbus_g_method_return_error (data->context, error); +  g_free (data); +  return FALSE; +} + +gboolean +my_object_async_throw_error (MyObject *obj, DBusGMethodInvocation *context) +{ +  IncrementData *data = g_new0(IncrementData, 1); +  data->context = context; +  g_idle_add ((GSourceFunc)do_async_error,  data); +  return TRUE; +} + +  static GMainLoop *loop;  gboolean @@ -484,6 +565,14 @@ main (int argc, char **argv)    guint32 request_name_ret;    g_type_init (); +  g_thread_init (NULL); dbus_g_thread_init (); + +  dbus_g_object_type_install_info (MY_TYPE_OBJECT, +				   &dbus_glib_my_object_object_info); + +  dbus_g_error_domain_register (MY_OBJECT_ERROR, +				NULL, +				MY_TYPE_ERROR);    g_printerr ("Launching test-service-glib\n"); @@ -506,8 +595,6 @@ main (int argc, char **argv)    obj = g_object_new (MY_TYPE_OBJECT, NULL);    obj2 = g_object_new (MY_TYPE_OBJECT, NULL); -  dbus_g_object_type_install_info (MY_TYPE_OBJECT, -				   &dbus_glib_my_object_object_info);    dbus_g_connection_register_g_object (connection,                                         "/org/freedesktop/DBus/Tests/MyTestObject",                                         obj); diff --git a/test/glib/test-service-glib.xml b/test/glib/test-service-glib.xml index 83240b47..58058626 100644 --- a/test/glib/test-service-glib.xml +++ b/test/glib/test-service-glib.xml @@ -77,6 +77,16 @@      <method name="IncrementVal">      </method> +    <method name="AsyncIncrement"> +      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> +      <arg type="u" name="x" /> +      <arg type="u" direction="out" /> +    </method> + +    <method name="AsyncThrowError"> +      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> +    </method> +          <method name="GetVal">        <arg type="u" direction="out" />      </method>  | 
