From 2ca6e95764dc3491458dcf077ce77cbbabf00ddf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 6 Jul 2005 21:27:53 +0000 Subject: 2005-07-06 Colin Walters * dbus/dbus-glib.h (DBusGPendingCall, DBusGPendingCallNotify) (DBUS_TYPE_G_PENDING_CALL, dbus_g_pending_call_get_g_type) (dbus_g_pending_call_ref, dbus_g_pending_call_unref): Delete. (dbus_g_pending_call_set_notify, dbus_g_pending_call_cancel): Delete in favor of dbus_g_proxy_begin_call and dbus_g_proxy_cancel_call. (DBusGProxyCall, DBusGProxyCallNotify): New. (dbus_g_proxy_begin_call): Change prototype to take callback, user data, and destroy function. This replaces dbus_g_pending_call_set_notify. (dbus_g_proxy_cancel_call): Prototype. (DBusGAsyncData): Delete, shouldn't be needed anymore. * glib/dbus-gproxy.c (struct _DBusGProxy): Add call_id_counter and pending_calls map. (struct _DBusGProxyManager): Add bus_proxy member, which is an internal proxy for calls to the bus. Remove pending_nameowner_calls, now the internal proxy keeps track. (dbus_g_proxy_manager_unref): Unref bus proxy, remove reference to pending_nameowner_calls. (got_name_owner_cb): Update prototype, and use dbus_g_proxy_end_call. (got_name_owner_cb): Remove reference to pending_nameowner_calls. (dbus_g_proxy_manager_register): Delete directly libdbus code in favor of using internal proxy. (dbus_g_proxy_manager_unregister): Update to use dbus_g_proxy_cancel_call for any pending GetNameOwner call. (dbus_g_proxy_init): Initialize pending calls map. (dbus_g_proxy_constructor): New. (dbus_g_proxy_class_init): Add get/set property functions, constructor, and add NAME, PATH, and INTERFACE properties. (cancel_pending_call): New function. (dbus_g_proxy_dispose): Iterate over any outstanding calls and cancel them. (dbus_g_proxy_set_property, dbus_g_proxy_get_property): New. (GPendingNotifyClosure): New structure. (d_pending_call_notify, d_pending_call_free): Moved here from dbus-glib.c. (DBUS_G_VALUE_ARRAY_COLLECT_ALL): Moved around to satisfy function ordering. (manager_begin_bus_call): New internal function for talking to internal bus proxy. (dbus_g_proxy_new): Construct object using GObjet properties. (dbus_g_proxy_begin_call_internal): Update to take user data, etc. Create closure of same, and insert call into map of pending calls. (dbus_g_proxy_end_call_internal): Take call id instead of pending call. Look up pending call in current set. Remove it when we've completed. (dbus_g_pending_call_end, dbus_g_proxy_end_call_internal): Delete. (dbus_g_proxy_begin_call): Change API to take callback, user data, and destroy function directly. (dbus_g_proxy_end_call): Update to take DBusGProxyCall. (dbus_g_proxy_call): Invoke with NULL callback. (dbus_g_proxy_cancel_call): New function, replaces dbus_g_pending_call_cancel. * glib/dbus-gparser.c (validate_signature): Fix call to dbus_set_g_error. * glib/dbus-gobject.c (dbus_g_object_type_dbus_metadata_quark): New quark for attaching metadata to GType. (info_hash): Delete. (lookup_object_info): Look up using quark. (dbus_g_object_type_install_info): Check that a type is classed, not that it's an object. Also just install type data using quark instead of using global hash. * glib/dbus-glib.c (dbus_g_pending_call_ref) (dbus_g_pending_call_unref, dbus_pending_call_get_g_type) (GPendingNotifyClosure): Delete. (d_pending_call_notify, d_pending_call_free): Move to dbus-gproxy.c. (dbus_g_pending_call_set_notify, dbus_g_pending_call_cancel): Delete. * glib/dbus-binding-tool-glib.c (generate_client_glue): Disable async client method generation until we can fix it... * tools/dbus-viewer.c (load_child_nodes): Use dbus_g_proxy_call. (load_from_service_thread_func): Ditto. * tools/dbus-names-model.c (struct NamesModel): Hold DBusGProxyCall. (have_names_notify): Update prototype, use dbus_g_proxy_cancel_call. (names_model_reload): Update for new dbus_g_proxy_begin_call API. * tools/dbus-monitor.c (filter_func): Update for print_message API change. * test/glib/test-dbus-glib.c: Add more tests for async invocations. Update many begin_call/end_call pairs to just use dbus_g_proxy_call. * tools/dbus-send.c (main): Add --print-reply=literal mode. This allows us to dump print-introspect.c. * tools/dbus-print-message.h (print_message): Add literal argument to print_message which is intended to allow printing arguments without metadata like "string=". * tools/dbus-print-message.c (print_iter): Add literal argument. (print_message): Allow printing string messages literally. --- ChangeLog | 104 ++++++++ dbus/dbus-glib.h | 38 +-- glib/dbus-binding-tool-glib.c | 2 + glib/dbus-glib.c | 140 ----------- glib/dbus-gobject.c | 44 ++-- glib/dbus-gparser.c | 2 +- glib/dbus-gproxy.c | 555 ++++++++++++++++++++++++++++-------------- test/glib/test-dbus-glib.c | 216 +++++++++------- tools/dbus-monitor.c | 2 +- tools/dbus-names-model.c | 15 +- tools/dbus-print-message.c | 69 +++--- tools/dbus-print-message.h | 2 +- tools/dbus-send.c | 10 +- tools/dbus-viewer.c | 37 +-- tools/print-introspect.c | 8 +- 15 files changed, 706 insertions(+), 538 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4bd49240..f7320f96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,107 @@ +2005-07-06 Colin Walters + + * dbus/dbus-glib.h (DBusGPendingCall, DBusGPendingCallNotify) + (DBUS_TYPE_G_PENDING_CALL, dbus_g_pending_call_get_g_type) + (dbus_g_pending_call_ref, dbus_g_pending_call_unref): Delete. + (dbus_g_pending_call_set_notify, dbus_g_pending_call_cancel): + Delete in favor of dbus_g_proxy_begin_call and + dbus_g_proxy_cancel_call. + (DBusGProxyCall, DBusGProxyCallNotify): New. + (dbus_g_proxy_begin_call): Change prototype to take callback, user + data, and destroy function. This replaces + dbus_g_pending_call_set_notify. + (dbus_g_proxy_cancel_call): Prototype. + (DBusGAsyncData): Delete, shouldn't be needed anymore. + + * glib/dbus-gproxy.c (struct _DBusGProxy): Add call_id_counter and + pending_calls map. + (struct _DBusGProxyManager): Add bus_proxy member, which is an + internal proxy for calls to the bus. Remove + pending_nameowner_calls, now the internal proxy keeps track. + (dbus_g_proxy_manager_unref): Unref bus proxy, remove reference to + pending_nameowner_calls. + (got_name_owner_cb): Update prototype, and use + dbus_g_proxy_end_call. + (got_name_owner_cb): Remove reference to pending_nameowner_calls. + (dbus_g_proxy_manager_register): Delete directly libdbus code in + favor of using internal proxy. + (dbus_g_proxy_manager_unregister): Update to use + dbus_g_proxy_cancel_call for any pending GetNameOwner call. + (dbus_g_proxy_init): Initialize pending calls map. + (dbus_g_proxy_constructor): New. + (dbus_g_proxy_class_init): Add get/set property functions, + constructor, and add NAME, PATH, and INTERFACE properties. + (cancel_pending_call): New function. + (dbus_g_proxy_dispose): Iterate over any outstanding calls and + cancel them. + (dbus_g_proxy_set_property, dbus_g_proxy_get_property): New. + (GPendingNotifyClosure): New structure. + (d_pending_call_notify, d_pending_call_free): Moved here from + dbus-glib.c. + (DBUS_G_VALUE_ARRAY_COLLECT_ALL): Moved around to satisfy function + ordering. + (manager_begin_bus_call): New internal function for talking to + internal bus proxy. + (dbus_g_proxy_new): Construct object using GObjet properties. + (dbus_g_proxy_begin_call_internal): Update to take user data, etc. + Create closure of same, and insert call into map of pending calls. + (dbus_g_proxy_end_call_internal): Take call id instead of pending + call. Look up pending call in current set. Remove it when we've + completed. + (dbus_g_pending_call_end, dbus_g_proxy_end_call_internal): Delete. + (dbus_g_proxy_begin_call): Change API to take callback, user data, + and destroy function directly. + (dbus_g_proxy_end_call): Update to take DBusGProxyCall. + (dbus_g_proxy_call): Invoke with NULL callback. + (dbus_g_proxy_cancel_call): New function, replaces + dbus_g_pending_call_cancel. + + * glib/dbus-gparser.c (validate_signature): Fix call to + dbus_set_g_error. + + * glib/dbus-gobject.c (dbus_g_object_type_dbus_metadata_quark): + New quark for attaching metadata to GType. + (info_hash): Delete. + (lookup_object_info): Look up using quark. + (dbus_g_object_type_install_info): Check that a type is classed, + not that it's an object. Also just install type data using quark + instead of using global hash. + + * glib/dbus-glib.c (dbus_g_pending_call_ref) + (dbus_g_pending_call_unref, dbus_pending_call_get_g_type) + (GPendingNotifyClosure): Delete. + (d_pending_call_notify, d_pending_call_free): Move to dbus-gproxy.c. + (dbus_g_pending_call_set_notify, dbus_g_pending_call_cancel): Delete. + + * glib/dbus-binding-tool-glib.c (generate_client_glue): Disable async + client method generation until we can fix it... + + * tools/dbus-viewer.c (load_child_nodes): Use dbus_g_proxy_call. + (load_from_service_thread_func): Ditto. + + * tools/dbus-names-model.c (struct NamesModel): Hold + DBusGProxyCall. + (have_names_notify): Update prototype, use + dbus_g_proxy_cancel_call. + (names_model_reload): Update for new dbus_g_proxy_begin_call API. + + * tools/dbus-monitor.c (filter_func): Update for print_message + API change. + + * test/glib/test-dbus-glib.c: Add more tests for async + invocations. Update many begin_call/end_call pairs to just use + dbus_g_proxy_call. + + * tools/dbus-send.c (main): Add --print-reply=literal mode. This + allows us to dump print-introspect.c. + + * tools/dbus-print-message.h (print_message): Add literal argument + to print_message which is intended to allow printing arguments without + metadata like "string=". + + * tools/dbus-print-message.c (print_iter): Add literal argument. + (print_message): Allow printing string messages literally. + 2005-07-05 Colin Walters * glib/dbus-gproxy.c (marshal_dbus_message_to_g_marshaller): diff --git a/dbus/dbus-glib.h b/dbus/dbus-glib.h index 41b3d9c1..4b3672c2 100644 --- a/dbus/dbus-glib.h +++ b/dbus/dbus-glib.h @@ -40,39 +40,21 @@ typedef struct _DBusGConnection DBusGConnection; * Convert to DBusMessage with dbus_g_message_get_message() in dbus-glib-lowlevel.h */ typedef struct _DBusGMessage DBusGMessage; -/** - * Deliberately not possible to convert to DBusPendingCall - */ -typedef struct _DBusGPendingCall DBusGPendingCall; - -typedef void (* DBusGPendingCallNotify) (DBusGPendingCall *pending, - void *user_data); #define DBUS_TYPE_G_CONNECTION (dbus_g_connection_get_g_type ()) #define DBUS_TYPE_G_MESSAGE (dbus_g_message_get_g_type ()) -#define DBUS_TYPE_G_PENDING_CALL (dbus_g_message_get_g_type ()) GType dbus_g_connection_get_g_type (void) G_GNUC_CONST; GType dbus_g_message_get_g_type (void) G_GNUC_CONST; -GType dbus_g_pending_call_get_g_type (void) G_GNUC_CONST; DBusGConnection* dbus_g_connection_ref (DBusGConnection *connection); void dbus_g_connection_unref (DBusGConnection *connection); -DBusGPendingCall* dbus_g_pending_call_ref (DBusGPendingCall *call); -void dbus_g_pending_call_unref (DBusGPendingCall *call); DBusGMessage* dbus_g_message_ref (DBusGMessage *message); void dbus_g_message_unref (DBusGMessage *message); void dbus_g_connection_flush (DBusGConnection *connection); -void dbus_g_pending_call_set_notify (DBusGPendingCall *call, - DBusGPendingCallNotify callback, - void *callback_data, - GDestroyNotify free_data_func); -void dbus_g_pending_call_cancel (DBusGPendingCall *call); - - GQuark dbus_g_error_quark (void); #define DBUS_GERROR dbus_g_error_quark () @@ -221,6 +203,11 @@ typedef struct _DBusGProxyClass DBusGProxyClass; #define DBUS_G_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUS_TYPE_G_PROXY, DBusGProxyClass)) +typedef struct _DBusGProxyCall DBusGProxyCall; +typedef void (* DBusGProxyCallNotify) (DBusGProxy *proxy, + DBusGProxyCall *call_id, + void *user_data); + GType dbus_g_proxy_get_type (void) G_GNUC_CONST; DBusGProxy* dbus_g_proxy_new_for_name (DBusGConnection *connection, const char *name, @@ -266,15 +253,20 @@ void dbus_g_proxy_call_no_reply (DBusGProxy *proxy, GType first_arg_type, ...); -DBusGPendingCall* dbus_g_proxy_begin_call (DBusGProxy *proxy, +DBusGProxyCall * dbus_g_proxy_begin_call (DBusGProxy *proxy, const char *method, + DBusGProxyCallNotify notify, + gpointer data, + GDestroyNotify destroy, GType first_arg_type, ...); gboolean dbus_g_proxy_end_call (DBusGProxy *proxy, - DBusGPendingCall *pending, + DBusGProxyCall *call, GError **error, GType first_arg_type, ...); +void dbus_g_proxy_cancel_call (DBusGProxy *proxy, + DBusGProxyCall *call); const char* dbus_g_proxy_get_path (DBusGProxy *proxy); @@ -288,12 +280,6 @@ void dbus_g_method_return (DBusGMethodInvocation *con void dbus_g_method_return_error (DBusGMethodInvocation *context, GError *error); -typedef struct { - DBusGProxy *proxy; - gpointer cb; - gpointer userdata; -} DBusGAsyncData; - #undef DBUS_INSIDE_DBUS_GLIB_H G_END_DECLS diff --git a/glib/dbus-binding-tool-glib.c b/glib/dbus-binding-tool-glib.c index 4a33176b..18ce1fcf 100644 --- a/glib/dbus-binding-tool-glib.c +++ b/glib/dbus-binding-tool-glib.c @@ -1350,7 +1350,9 @@ generate_client_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error WRITE_OR_LOSE ("G_TYPE_INVALID);\n}\n\n"); +#if 0 write_async_method_client (channel, interface, method, error); +#endif } if (!write_printf_to_iochannel ("#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_%s */\n\n", channel, error, iface_prefix)) diff --git a/glib/dbus-glib.c b/glib/dbus-glib.c index 5b30ce7a..5dbcdf08 100644 --- a/glib/dbus-glib.c +++ b/glib/dbus-glib.c @@ -111,30 +111,6 @@ dbus_g_message_unref (DBusGMessage *gmessage) dbus_message_unref (c); } -/** - * Increments refcount on a pending call. - * - * @param call the call - * @returns the same call - */ -DBusGPendingCall* -dbus_g_pending_call_ref (DBusGPendingCall *call) -{ - dbus_pending_call_ref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call)); - return call; -} - -/** - * Decrements refcount on a pending call. - * - * @param call the call - */ -void -dbus_g_pending_call_unref (DBusGPendingCall *call) -{ - dbus_pending_call_unref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call)); -} - /** * The implementation of DBUS_GERROR error domain. See documentation * for GError in GLib reference manual. @@ -234,24 +210,6 @@ dbus_message_get_g_type (void) return our_type; } -/** - * Get the GLib type ID for a DBusPendingCall boxed type. - * - * @returns GLib type - */ -GType -dbus_pending_call_get_g_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = g_boxed_type_register_static ("DBusPendingCall", - (GBoxedCopyFunc) dbus_pending_call_ref, - (GBoxedFreeFunc) dbus_pending_call_unref); - - return our_type; -} - /** * Get the GLib type ID for a DBusGConnection boxed type. * @@ -288,24 +246,6 @@ dbus_g_message_get_g_type (void) return our_type; } -/** - * Get the GLib type ID for a DBusGPendingCall boxed type. - * - * @returns GLib type - */ -GType -dbus_g_pending_call_get_g_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = g_boxed_type_register_static ("DBusGPendingCall", - (GBoxedCopyFunc) dbus_g_pending_call_ref, - (GBoxedFreeFunc) dbus_g_pending_call_unref); - - return our_type; -} - /** * Get the DBusConnection corresponding to this DBusGConnection. * The return value does not have its refcount incremented. @@ -330,86 +270,6 @@ dbus_g_message_get_message (DBusGMessage *gmessage) return DBUS_MESSAGE_FROM_G_MESSAGE (gmessage); } -typedef struct -{ - DBusGPendingCallNotify func; - void *data; - GDestroyNotify free_data_func; -} GPendingNotifyClosure; - -static void -d_pending_call_notify (DBusPendingCall *dcall, - void *data) -{ - GPendingNotifyClosure *closure = data; - DBusGPendingCall *gcall = DBUS_G_PENDING_CALL_FROM_PENDING_CALL (dcall); - - (* closure->func) (gcall, closure->data); -} - -static void -d_pending_call_free (void *data) -{ - GPendingNotifyClosure *closure = data; - - if (closure->free_data_func) - (* closure->free_data_func) (closure->data); - - g_free (closure); -} - -/** - * Sets up a notification to be invoked when the pending call - * is ready to be ended without blocking. - * You can call dbus_g_proxy_end_call() at any time, - * but it will block if no reply or error has been received yet. - * This function lets you handle the reply asynchronously. - * - * @param call the pending call - * @param callback the callback - * @param callback_data data for the callback - * @param free_data_func free the callback data with this - */ -void -dbus_g_pending_call_set_notify (DBusGPendingCall *call, - DBusGPendingCallNotify callback, - void *callback_data, - GDestroyNotify free_data_func) -{ - GPendingNotifyClosure *closure; - DBusPendingCall *dcall; - - g_return_if_fail (callback != NULL); - - closure = g_new (GPendingNotifyClosure, 1); - - closure->func = callback; - closure->data = callback_data; - closure->free_data_func = free_data_func; - - dcall = DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call); - dbus_pending_call_set_notify (dcall, d_pending_call_notify, - closure, - d_pending_call_free); -} - -/** - * Cancels a pending call. Does not affect the reference count - * of the call, but it means you will never be notified of call - * completion, and can't call dbus_g_proxy_end_call(). - * - * @param call the call - */ -void -dbus_g_pending_call_cancel (DBusGPendingCall *call) -{ - DBusPendingCall *dcall; - - dcall = DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call); - - dbus_pending_call_cancel (dcall); -} - /** @} */ /* end of public API */ diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c index c91f1851..ed1f81ce 100644 --- a/glib/dbus-gobject.c +++ b/glib/dbus-gobject.c @@ -46,7 +46,6 @@ typedef struct } 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; @@ -222,6 +221,16 @@ propsig_iterate (const char *data, const char **iface, const char **name) return string_table_next (data); } +static GQuark +dbus_g_object_type_dbus_metadata_quark (void) +{ + static GQuark quark; + + if (!quark) + quark = g_quark_from_static_string ("DBusGObjectTypeDBusMetadataQuark"); + return quark; +} + static const DBusGObjectInfo * lookup_object_info (GObject *object) { @@ -230,16 +239,11 @@ lookup_object_info (GObject *object) ret = NULL; - g_static_rw_lock_reader_lock (&globals_lock); - - if (info_hash == NULL) - goto out; - for (classtype = G_TYPE_FROM_INSTANCE (object); classtype != 0; classtype = g_type_parent (classtype)) { const DBusGObjectInfo *info; - info = g_hash_table_lookup (info_hash, g_type_class_peek (classtype)); + info = g_type_get_qdata (classtype, dbus_g_object_type_dbus_metadata_quark ()); if (info != NULL && info->format_version == 0) { @@ -248,9 +252,6 @@ lookup_object_info (GObject *object) } } - out: - g_static_rw_lock_reader_unlock (&globals_lock); - return ret; } @@ -1355,28 +1356,13 @@ void dbus_g_object_type_install_info (GType object_type, const DBusGObjectInfo *info) { - GObjectClass *object_class; - - g_return_if_fail (G_TYPE_IS_OBJECT (object_type)); + g_return_if_fail (G_TYPE_IS_CLASSED (object_type)); dbus_g_value_types_init (); - object_class = g_type_class_ref (object_type); - - g_return_if_fail (G_IS_OBJECT_CLASS (object_class)); - - g_static_rw_lock_writer_lock (&globals_lock); - - if (info_hash == NULL) - { - info_hash = g_hash_table_new (NULL, NULL); /* direct hash */ - } - - g_hash_table_replace (info_hash, object_class, (void*) info); - - g_static_rw_lock_writer_unlock (&globals_lock); - - g_type_class_unref (object_class); + g_type_set_qdata (object_type, + dbus_g_object_type_dbus_metadata_quark (), + (gpointer) info); } /** diff --git a/glib/dbus-gparser.c b/glib/dbus-gparser.c index daf9bc8e..49593839 100644 --- a/glib/dbus-gparser.c +++ b/glib/dbus-gparser.c @@ -475,7 +475,7 @@ validate_signature (const char *str, if (!dbus_signature_validate (str, &derror)) { - dbus_set_g_error (&derror, error); + dbus_set_g_error (error, &derror); return FALSE; } return TRUE; diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 1a7292de..fd78b04d 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -32,6 +32,9 @@ #include #include +#define DBUS_G_PROXY_CALL_TO_ID(x) (GPOINTER_TO_UINT(x)) +#define DBUS_G_PROXY_ID_TO_CALL(x) (GUINT_TO_POINTER(x)) + /** * @addtogroup DBusGLibInternals * @@ -56,11 +59,16 @@ struct _DBusGProxy char *path; /**< Path messages go to or NULL */ char *interface; /**< Interface messages go to or NULL */ - DBusGPendingCall *name_call;/**< Pending call to retrieve name owner */ + DBusGProxyCall *name_call; /**< Pending call id to retrieve name owner */ guint for_owner : 1; /**< Whether or not this proxy is for a name owner */ guint associated : 1; /**< Whether or not this proxy is associated (for name proxies) */ + /* FIXME: make threadsafe? */ + guint call_id_counter; /**< Integer counter for pending calls */ + GData *signal_signatures; /**< D-BUS signatures for each signal */ + + GHashTable *pending_calls; /**< Calls made on this proxy which have not yet returned */ }; /** @@ -73,18 +81,42 @@ struct _DBusGProxyClass static void dbus_g_proxy_init (DBusGProxy *proxy); static void dbus_g_proxy_class_init (DBusGProxyClass *klass); +static GObject *dbus_g_proxy_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties); +static void dbus_g_proxy_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void dbus_g_proxy_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + static void dbus_g_proxy_finalize (GObject *object); static void dbus_g_proxy_dispose (GObject *object); static void dbus_g_proxy_destroy (DBusGProxy *proxy); static void dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy, DBusMessage *message); -static gboolean dbus_g_pending_call_end (DBusGConnection *connection, - DBusGProxy *proxycon, - DBusGPendingCall *pending, - GError **error, - GType first_arg_type, - ...); +static DBusGProxyCall *manager_begin_bus_call (DBusGProxyManager *manager, + const char *method, + DBusGProxyCallNotify notify, + gpointer data, + GDestroyNotify destroy, + GType first_arg_type, + ...); +static guint dbus_g_proxy_begin_call_internal (DBusGProxy *proxy, + const char *method, + DBusGProxyCallNotify notify, + gpointer data, + GDestroyNotify destroy, + GValueArray *args); +static gboolean dbus_g_proxy_end_call_internal (DBusGProxy *proxy, + guint call_id, + GError **error, + GType first_arg_type, + va_list args); /** * A list of proxies with a given name+path+interface, used to @@ -112,6 +144,8 @@ struct _DBusGProxyManager int refcount; /**< Reference count */ DBusConnection *connection; /**< Connection we're associated with. */ + DBusGProxy *bus_proxy; /**< Special internal proxy used to talk to the bus */ + GHashTable *proxy_lists; /**< Hash used to route incoming signals * and iterate over proxies */ @@ -119,9 +153,6 @@ struct _DBusGProxyManager * base name -> [name,name,...] for proxies which * are for names. */ - GSList *pending_nameowner_calls; /**< List to keep track of pending - * GetNameOwner calls - */ GSList *unassociated_proxies; /**< List of name proxies for which * there was no result for * GetNameOwner @@ -168,7 +199,7 @@ dbus_g_proxy_manager_get (DBusConnection *connection) manager->refcount = 1; manager->connection = connection; - + g_static_mutex_init (&manager->lock); /* Proxy managers keep the connection alive, which means that @@ -215,6 +246,9 @@ dbus_g_proxy_manager_unref (DBusGProxyManager *manager) { UNLOCK_MANAGER (manager); + if (manager->bus_proxy) + g_object_unref (manager->bus_proxy); + if (manager->proxy_lists) { /* can't have any proxies left since they hold @@ -238,7 +272,6 @@ dbus_g_proxy_manager_unref (DBusGProxyManager *manager) manager->owner_names = NULL; } - g_assert (manager->pending_nameowner_calls == NULL); g_assert (manager->unassociated_proxies == NULL); g_static_mutex_free (&manager->lock); @@ -723,13 +756,13 @@ dbus_g_proxy_manager_replace_name_owner (DBusGProxyManager *manager, } static void -got_name_owner_cb (DBusGPendingCall *pending, +got_name_owner_cb (DBusGProxy *bus_proxy, + DBusGProxyCall *call, void *user_data) { DBusGProxy *proxy; GError *error; char *owner; - GSList *link; proxy = user_data; error = NULL; @@ -737,15 +770,9 @@ got_name_owner_cb (DBusGPendingCall *pending, LOCK_MANAGER (proxy->manager); - link = g_slist_find (proxy->manager->pending_nameowner_calls, pending); - g_assert (link != NULL); - - if (!dbus_g_pending_call_end (DBUS_G_CONNECTION_FROM_CONNECTION (proxy->manager->connection), - NULL, - pending, - &error, - G_TYPE_STRING, &owner, - G_TYPE_INVALID)) + if (!dbus_g_proxy_end_call (bus_proxy, call, &error, + G_TYPE_STRING, &owner, + G_TYPE_INVALID)) { if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_NAME_HAS_NO_OWNER) { @@ -767,7 +794,6 @@ got_name_owner_cb (DBusGPendingCall *pending, out: proxy->name_call = NULL; - proxy->manager->pending_nameowner_calls = g_slist_delete_link (proxy->manager->pending_nameowner_calls, link); UNLOCK_MANAGER (proxy->manager); g_free (owner); } @@ -911,46 +937,14 @@ dbus_g_proxy_manager_register (DBusGProxyManager *manager, if (!dbus_g_proxy_manager_lookup_name_owner (manager, proxy->name, &info, &owner)) { - DBusPendingCall *pending; - DBusGPendingCall *gpending; - DBusMessage *request, *reply; - - g_assert (owner == NULL); - - reply = NULL; - - request = dbus_message_new_method_call (DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetNameOwner"); - if (request == NULL) - g_error ("Out of memory"); - - if (!dbus_message_append_args (request, - DBUS_TYPE_STRING, &(proxy->name), - DBUS_TYPE_INVALID)) - g_error ("Out of memory"); - - if (!dbus_connection_send_with_reply (manager->connection, - request, - &pending, - -1)) - g_error ("Out of memory"); - g_assert (pending != NULL); - - gpending = DBUS_G_PENDING_CALL_FROM_PENDING_CALL (pending); - - /* It's safe to keep a reference to proxy here; - * when the proxy is unreffed we cancel the call - */ - dbus_g_pending_call_set_notify (gpending, - got_name_owner_cb, - proxy, - NULL); + proxy->name_call = manager_begin_bus_call (manager, "GetNameOwner", + got_name_owner_cb, + proxy, NULL, + G_TYPE_STRING, + proxy->name, + G_TYPE_INVALID); proxy->associated = FALSE; - proxy->name_call = gpending; - manager->pending_nameowner_calls = g_slist_prepend (manager->pending_nameowner_calls, gpending); } else { @@ -1003,14 +997,10 @@ dbus_g_proxy_manager_unregister (DBusGProxyManager *manager, { GSList *link; - if (proxy->name_call != NULL) + if (proxy->name_call != 0) { - link = g_slist_find (manager->pending_nameowner_calls, proxy->name_call); - g_assert (link != NULL); - - dbus_g_pending_call_cancel (proxy->name_call); - - manager->pending_nameowner_calls = g_slist_delete_link (manager->pending_nameowner_calls, link); + dbus_g_proxy_cancel_call (manager->bus_proxy, proxy->name_call); + proxy->name_call = 0; } else { @@ -1022,7 +1012,7 @@ dbus_g_proxy_manager_unregister (DBusGProxyManager *manager, } else { - g_assert (proxy->name_call == NULL); + g_assert (proxy->name_call == 0); dbus_g_proxy_manager_unmonitor_name_owner (manager, proxy->name); } @@ -1267,6 +1257,13 @@ marshal_dbus_message_to_g_marshaller (GClosure *closure, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); +enum +{ + PROP_0, + PROP_NAME, + PROP_PATH, + PROP_INTERFACE +}; enum { @@ -1282,6 +1279,31 @@ static void dbus_g_proxy_init (DBusGProxy *proxy) { g_datalist_init (&proxy->signal_signatures); + proxy->pending_calls = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) dbus_pending_call_unref); +} + +static GObject * +dbus_g_proxy_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + DBusGProxy *proxy; + DBusGProxyClass *klass; + GObjectClass *parent_class; + + klass = DBUS_G_PROXY_CLASS (g_type_class_peek (DBUS_TYPE_G_PROXY)); + + parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); + + proxy = DBUS_G_PROXY (parent_class->constructor (type, n_construct_properties, + construct_properties)); + + proxy->for_owner = (proxy->name[0] == ':'); + proxy->name_call = 0; + proxy->associated = FALSE; + + return G_OBJECT (proxy); } static void @@ -1290,9 +1312,37 @@ dbus_g_proxy_class_init (DBusGProxyClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); + + object_class->set_property = dbus_g_proxy_set_property; + object_class->get_property = dbus_g_proxy_get_property; + + g_object_class_install_property (object_class, + PROP_NAME, + g_param_spec_string ("name", + "name", + "name", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_PATH, + g_param_spec_string ("path", + "path", + "path", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_INTERFACE, + g_param_spec_string ("interface", + "interface", + "interface", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); object_class->finalize = dbus_g_proxy_finalize; object_class->dispose = dbus_g_proxy_dispose; + object_class->constructor = dbus_g_proxy_constructor; signals[DESTROY] = g_signal_new ("destroy", @@ -1313,6 +1363,15 @@ dbus_g_proxy_class_init (DBusGProxyClass *klass) G_TYPE_NONE, 2, DBUS_TYPE_MESSAGE, G_TYPE_POINTER); } +static void +cancel_pending_call (gpointer key, gpointer val, gpointer data) +{ + DBusGProxyCall *call = key; + DBusGProxy *proxy = data; + + dbus_g_proxy_cancel_call (proxy, call); +} + static void dbus_g_proxy_dispose (GObject *object) { @@ -1320,12 +1379,16 @@ dbus_g_proxy_dispose (GObject *object) proxy = DBUS_G_PROXY (object); - if (proxy->manager) + /* Cancel outgoing pending calls */ + g_hash_table_foreach (proxy->pending_calls, cancel_pending_call, proxy); + g_hash_table_destroy (proxy->pending_calls); + + if (proxy->manager && proxy != proxy->manager->bus_proxy) { dbus_g_proxy_manager_unregister (proxy->manager, proxy); dbus_g_proxy_manager_unref (proxy->manager); - proxy->manager = NULL; } + proxy->manager = NULL; g_datalist_clear (&proxy->signal_signatures); @@ -1359,6 +1422,56 @@ dbus_g_proxy_destroy (DBusGProxy *proxy) g_object_run_dispose (G_OBJECT (proxy)); } +static void +dbus_g_proxy_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + DBusGProxy *proxy = DBUS_G_PROXY (object); + + switch (prop_id) + { + case PROP_NAME: + proxy->name = g_strdup (g_value_get_string (value)); + break; + case PROP_PATH: + proxy->path = g_strdup (g_value_get_string (value)); + break; + case PROP_INTERFACE: + proxy->interface = g_strdup (g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dbus_g_proxy_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + DBusGProxy *proxy = DBUS_G_PROXY (object); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, proxy->name); + break; + case PROP_PATH: + g_value_set_string (value, proxy->path); + break; + case PROP_INTERFACE: + g_value_set_string (value, proxy->interface); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + /* this is to avoid people using g_signal_connect() directly, * to avoid confusion with local signal names, and because * of the horribly broken current setup (signals are added @@ -1514,6 +1627,91 @@ dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy, goto out; } +typedef struct +{ + DBusGProxy *proxy; + guint call_id; + DBusGProxyCallNotify func; + void *data; + GDestroyNotify free_data_func; +} GPendingNotifyClosure; + +static void +d_pending_call_notify (DBusPendingCall *dcall, + void *data) +{ + GPendingNotifyClosure *closure = data; + + (* closure->func) (closure->proxy, DBUS_G_PROXY_ID_TO_CALL (closure->call_id), closure->data); +} + +static void +d_pending_call_free (void *data) +{ + GPendingNotifyClosure *closure = data; + + if (closure->free_data_func) + (* closure->free_data_func) (closure->data); + + g_free (closure); +} + +#define DBUS_G_VALUE_ARRAY_COLLECT_ALL(VALARRAY, FIRST_ARG_TYPE, ARGS) \ +do { \ + GType valtype; \ + int i = 0; \ + VALARRAY = g_value_array_new (6); \ + valtype = FIRST_ARG_TYPE; \ + while (valtype != G_TYPE_INVALID) \ + { \ + const char *collect_err; \ + GValue *val; \ + g_value_array_append (VALARRAY, NULL); \ + val = g_value_array_get_nth (VALARRAY, i); \ + g_value_init (val, valtype); \ + collect_err = NULL; \ + G_VALUE_COLLECT (val, ARGS, G_VALUE_NOCOPY_CONTENTS, &collect_err); \ + valtype = va_arg (ARGS, GType); \ + i++; \ + } \ +} while (0) + +DBusGProxyCall * +manager_begin_bus_call (DBusGProxyManager *manager, + const char *method, + DBusGProxyCallNotify notify, + gpointer user_data, + GDestroyNotify destroy, + GType first_arg_type, + ...) +{ + DBusGProxyCall *call; + va_list args; + GValueArray *arg_values; + + va_start (args, first_arg_type); + + if (!manager->bus_proxy) + { + manager->bus_proxy = g_object_new (DBUS_TYPE_G_PROXY, + "name", DBUS_SERVICE_DBUS, + "path", DBUS_PATH_DBUS, + "interface", DBUS_INTERFACE_DBUS, + NULL); + manager->bus_proxy->manager = manager; + } + + DBUS_G_VALUE_ARRAY_COLLECT_ALL (arg_values, first_arg_type, args); + + call = DBUS_G_PROXY_ID_TO_CALL (dbus_g_proxy_begin_call_internal (manager->bus_proxy, method, notify, user_data, destroy, arg_values)); + + g_value_array_free (arg_values); + + va_end (args); + + return call; +} + /** @} End of DBusGLibInternals */ /** @addtogroup DBusGLib @@ -1563,21 +1761,13 @@ dbus_g_proxy_new (DBusGConnection *connection, g_assert (connection != NULL); - proxy = g_object_new (DBUS_TYPE_G_PROXY, NULL); + proxy = g_object_new (DBUS_TYPE_G_PROXY, "name", name, "path", path_name, "interface", interface_name, NULL); /* These should all be construct-only mandatory properties, * for now we just don't let people use g_object_new(). */ proxy->manager = dbus_g_proxy_manager_get (DBUS_CONNECTION_FROM_G_CONNECTION (connection)); - - proxy->name = g_strdup (name); - proxy->path = g_strdup (path_name); - proxy->interface = g_strdup (interface_name); - - proxy->for_owner = (proxy->name[0] == ':'); - proxy->name_call = NULL; - proxy->associated = FALSE; dbus_g_proxy_manager_register (proxy->manager, proxy); @@ -1830,33 +2020,18 @@ dbus_g_proxy_marshal_args_to_message (DBusGProxy *proxy, return NULL; } -#define DBUS_G_VALUE_ARRAY_COLLECT_ALL(VALARRAY, FIRST_ARG_TYPE, ARGS) \ -do { \ - GType valtype; \ - int i = 0; \ - VALARRAY = g_value_array_new (6); \ - valtype = FIRST_ARG_TYPE; \ - while (valtype != G_TYPE_INVALID) \ - { \ - const char *collect_err; \ - GValue *val; \ - g_value_array_append (VALARRAY, NULL); \ - val = g_value_array_get_nth (VALARRAY, i); \ - g_value_init (val, valtype); \ - collect_err = NULL; \ - G_VALUE_COLLECT (val, ARGS, G_VALUE_NOCOPY_CONTENTS, &collect_err); \ - valtype = va_arg (ARGS, GType); \ - i++; \ - } \ -} while (0) - -static DBusGPendingCall * -dbus_g_proxy_begin_call_internal (DBusGProxy *proxy, - const char *method, - GValueArray *args) +static guint +dbus_g_proxy_begin_call_internal (DBusGProxy *proxy, + const char *method, + DBusGProxyCallNotify notify, + gpointer user_data, + GDestroyNotify destroy, + GValueArray *args) { DBusMessage *message; DBusPendingCall *pending; + GPendingNotifyClosure *closure; + guint call_id; g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE); g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE); @@ -1874,16 +2049,32 @@ dbus_g_proxy_begin_call_internal (DBusGProxy *proxy, goto oom; g_assert (pending != NULL); - return DBUS_G_PENDING_CALL_FROM_PENDING_CALL (pending); + call_id = ++proxy->call_id_counter; + + if (notify != NULL) + { + closure = g_new (GPendingNotifyClosure, 1); + closure->proxy = proxy; /* No need to ref as the lifecycle is tied to proxy */ + closure->call_id = call_id; + closure->func = notify; + closure->data = user_data; + closure->free_data_func = destroy; + dbus_pending_call_set_notify (pending, d_pending_call_notify, + closure, + d_pending_call_free); + } + + g_hash_table_insert (proxy->pending_calls, GUINT_TO_POINTER (call_id), pending); + + return call_id; oom: g_error ("Out of memory"); - return NULL; + return 0; } static gboolean -dbus_g_pending_call_end_valist (DBusGConnection *connection, - DBusGProxy *proxycon, - DBusGPendingCall *pending, +dbus_g_proxy_end_call_internal (DBusGProxy *proxy, + guint call_id, GError **error, GType first_arg_type, va_list args) @@ -1896,13 +2087,17 @@ dbus_g_pending_call_end_valist (DBusGConnection *connection, int n_retvals_processed; gboolean ret; GType valtype; + DBusPendingCall *pending; reply = NULL; ret = FALSE; n_retvals_processed = 0; over = 0; - dbus_pending_call_block (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (pending)); - reply = dbus_pending_call_steal_reply (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (pending)); + + pending = g_hash_table_lookup (proxy->pending_calls, GUINT_TO_POINTER (call_id)); + + dbus_pending_call_block (pending); + reply = dbus_pending_call_steal_reply (pending); g_assert (reply != NULL); @@ -1921,9 +2116,8 @@ dbus_g_pending_call_end_valist (DBusGConnection *connection, GValue gvalue = { 0, }; DBusGValueMarshalCtx context; - context.gconnection = connection; - context.proxy = proxycon; - + context.gconnection = DBUS_G_CONNECTION_FROM_CONNECTION (proxy->manager->connection); + context.proxy = proxy; arg_type = dbus_message_iter_get_arg_type (&msgiter); if (arg_type == DBUS_TYPE_INVALID) @@ -2039,76 +2233,44 @@ dbus_g_pending_call_end_valist (DBusGConnection *connection, } va_end (args_unwind); - if (pending) - dbus_g_pending_call_unref (pending); + g_hash_table_remove (proxy->pending_calls, GUINT_TO_POINTER (call_id)); + if (reply) dbus_message_unref (reply); return ret; } -static gboolean -dbus_g_pending_call_end (DBusGConnection *connection, - DBusGProxy *proxycon, - DBusGPendingCall *pending, - GError **error, - GType first_arg_type, - ...) -{ - va_list args; - gboolean ret; - - va_start (args, first_arg_type); - - ret = dbus_g_pending_call_end_valist (connection, proxycon, pending, - error, first_arg_type, args); - - va_end (args); - - return ret; -} - -static gboolean -dbus_g_proxy_end_call_internal (DBusGProxy *proxy, - DBusGPendingCall *pending, - GError **error, - GType first_arg_type, - va_list args) -{ - return dbus_g_pending_call_end_valist (DBUS_G_CONNECTION_FROM_CONNECTION (proxy->manager->connection), - proxy, - pending, - error, - first_arg_type, - args); -} - - /** - * Invokes a method on a remote interface. This function does not - * block; instead it returns an opaque #DBusPendingCall object that - * tracks the pending call. The method call will not be sent over the - * wire until the application returns to the main loop, or blocks in - * dbus_connection_flush() to write out pending data. The call will - * be completed after a timeout, or when a reply is received. - * To collect the results of the call (which may be an error, - * or a reply), use dbus_g_proxy_end_call(). + * Asynchronously invokes a method on a remote interface. The method + * call will not be sent over the wire until the application returns + * to the main loop, or blocks in dbus_connection_flush() to write out + * pending data. The call will be completed after a timeout, or when + * a reply is received. When the call returns, the callback specified + * will be invoked; you can then collect the results of the call + * (which may be an error, or a reply), use dbus_g_proxy_end_call(). * * @todo this particular function shouldn't die on out of memory, * since you should be able to do a call with large arguments. * * @param proxy a proxy for a remote interface * @param method the name of the method to invoke + * @param notify callback to be invoked when method returns + * @param user_data user data passed to callback + * @param destroy function called to destroy user_data * @param first_arg_type type of the first argument * - * @returns opaque pending call object + * @returns call identifier * */ -DBusGPendingCall* -dbus_g_proxy_begin_call (DBusGProxy *proxy, - const char *method, - GType first_arg_type, - ...) +DBusGProxyCall * +dbus_g_proxy_begin_call (DBusGProxy *proxy, + const char *method, + DBusGProxyCallNotify notify, + gpointer user_data, + GDestroyNotify destroy, + GType first_arg_type, + ...) { - DBusGPendingCall *pending; + guint call_id; va_list args; GValueArray *arg_values; @@ -2116,21 +2278,21 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy, DBUS_G_VALUE_ARRAY_COLLECT_ALL (arg_values, first_arg_type, args); - pending = dbus_g_proxy_begin_call_internal (proxy, method, arg_values); + call_id = dbus_g_proxy_begin_call_internal (proxy, method, notify, user_data, destroy, arg_values); g_value_array_free (arg_values); va_end (args); - return pending; + return DBUS_G_PROXY_ID_TO_CALL (call_id); } /** * Collects the results of a method call. The method call was normally - * initiated with dbus_g_proxy_end_call(). This function will block if - * the results haven't yet been received; use - * dbus_g_pending_call_set_notify() to be notified asynchronously that a - * pending call has been completed. If it's completed, it will not block. + * initiated with dbus_g_proxy_end_call(). You may use this function + * outside of the callback given to dbus_g_proxy_begin_call; in that + * case this function will block if the results haven't yet been + * received. * * If the call results in an error, the error is set as normal for * GError and the function returns #FALSE. @@ -2139,17 +2301,15 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy, * method are stored in the provided varargs list. * The list should be terminated with G_TYPE_INVALID. * - * This function unrefs the pending call. - * * @param proxy a proxy for a remote interface - * @param pending the pending call from dbus_g_proxy_begin_call() + * @param call_id the pending call ID from dbus_g_proxy_begin_call() * @param error return location for an error * @param first_arg_type type of first "out" argument * @returns #FALSE if an error is set */ gboolean dbus_g_proxy_end_call (DBusGProxy *proxy, - DBusGPendingCall *pending, + DBusGProxyCall *call, GError **error, GType first_arg_type, ...) @@ -2159,7 +2319,7 @@ dbus_g_proxy_end_call (DBusGProxy *proxy, va_start (args, first_arg_type); - ret = dbus_g_proxy_end_call_internal (proxy, pending, error, first_arg_type, args); + ret = dbus_g_proxy_end_call_internal (proxy, GPOINTER_TO_UINT (call), error, first_arg_type, args); va_end (args); @@ -2187,7 +2347,7 @@ dbus_g_proxy_call (DBusGProxy *proxy, ...) { gboolean ret; - DBusGPendingCall *pending; + guint call_id; va_list args; GValueArray *in_args; @@ -2195,12 +2355,12 @@ dbus_g_proxy_call (DBusGProxy *proxy, DBUS_G_VALUE_ARRAY_COLLECT_ALL (in_args, first_arg_type, args); - pending = dbus_g_proxy_begin_call_internal (proxy, method, in_args); + call_id = dbus_g_proxy_begin_call_internal (proxy, method, NULL, NULL, NULL, in_args); g_value_array_free (in_args); first_arg_type = va_arg (args, GType); - ret = dbus_g_proxy_end_call_internal (proxy, pending, error, first_arg_type, args); + ret = dbus_g_proxy_end_call_internal (proxy, call_id, error, first_arg_type, args); va_end (args); @@ -2255,6 +2415,35 @@ dbus_g_proxy_call_no_reply (DBusGProxy *proxy, g_error ("Out of memory"); } +/** + * Cancels a pending method call. The method call was normally + * initiated with dbus_g_proxy_begin_call(). This function + * may not be used on pending calls that have already been + * ended with dbus_g_proxy_end_call. + * + * @param proxy a proxy for a remote interface + * @param call_id the pending call ID from dbus_g_proxy_begin_call() + */ +void +dbus_g_proxy_cancel_call (DBusGProxy *proxy, + DBusGProxyCall *call) +{ + guint call_id; + DBusPendingCall *pending; + + g_return_if_fail (DBUS_IS_G_PROXY (proxy)); + g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); + + call_id = DBUS_G_PROXY_CALL_TO_ID (call); + + pending = g_hash_table_lookup (proxy->pending_calls, GUINT_TO_POINTER (call_id)); + g_return_if_fail (pending != NULL); + + dbus_pending_call_cancel (pending); + + g_hash_table_remove (proxy->pending_calls, GUINT_TO_POINTER (call_id)); +} + /** * Sends a message to the interface we're proxying for. Does not * block or wait for a reply. The message is only actually written out diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c index fd71d743..cac774ce 100644 --- a/test/glib/test-dbus-glib.c +++ b/test/glib/test-dbus-glib.c @@ -23,6 +23,9 @@ static gboolean proxy_destroyed = FALSE; static gboolean proxy_destroy_and_nameowner = FALSE; static gboolean proxy_destroy_and_nameowner_complete = FALSE; +static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); +static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; + static gboolean timed_exit (gpointer loop) { @@ -168,8 +171,59 @@ sig2_signal_handler (DBusGProxy *proxy, g_source_remove (exit_timeout); } -static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); -static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; +static DBusGProxyCall *echo_call; +static guint n_times_echo_cb_entered; +static void +echo_received_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer data) +{ + GError *error; + char *echo_data; + + g_assert (call == echo_call); + g_assert (data == NULL); + + error = NULL; + echo_data = NULL; + n_times_echo_cb_entered++; + + if (!dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_STRING, + &echo_data, + G_TYPE_INVALID)) + lose_gerror ("Failed to complete async Echo", error); + g_assert (echo_data != NULL); + g_print ("Async echo gave \"%s\"", echo_data); + g_main_loop_quit (loop); + g_source_remove (exit_timeout); +} + +static void +increment_received_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer data) +{ + GError *error; + char *echo_data; + guint val; + + g_assert (!strcmp (data, "moo")); + + error = NULL; + echo_data = NULL; + if (!dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_UINT, &val, + G_TYPE_INVALID)) + lose_gerror ("Failed to complete (async) Increment call", error); + + if (val != 43) + lose ("Increment call returned %d, should be 43", val); + + g_print ("Async increment gave \"%d\"", val); + g_main_loop_quit (loop); + g_source_remove (exit_timeout); +} static void lose (const char *str, ...) @@ -215,10 +269,10 @@ main (int argc, char **argv) DBusGProxy *driver; DBusGProxy *proxy; DBusGProxy *proxy2; - DBusGPendingCall *call; char **name_list; guint name_list_len; guint i; + DBusGProxyCall *call; guint32 result; char *v_STRING_2; guint32 v_UINT32_2; @@ -262,12 +316,11 @@ main (int argc, char **argv) NULL); /* Call ListNames method */ - call = dbus_g_proxy_begin_call (driver, "ListNames", G_TYPE_INVALID); - error = NULL; - if (!dbus_g_proxy_end_call (driver, call, &error, - G_TYPE_STRV, &name_list, - G_TYPE_INVALID)) + if (!dbus_g_proxy_call (driver, "ListNames", &error, + G_TYPE_INVALID, + G_TYPE_STRV, &name_list, + G_TYPE_INVALID)) lose_gerror ("Failed to complete ListNames call", error); g_print ("Names on the message bus:\n"); @@ -285,53 +338,42 @@ main (int argc, char **argv) g_print ("calling ThisMethodDoesNotExist\n"); /* Test handling of unknown method */ - call = dbus_g_proxy_begin_call (driver, "ThisMethodDoesNotExist", - G_TYPE_STRING, - "blah blah blah blah blah", - G_TYPE_INT, - 10, - G_TYPE_INVALID); - - error = NULL; - if (dbus_g_proxy_end_call (driver, call, &error, - G_TYPE_INVALID)) + if (dbus_g_proxy_call (driver, "ThisMethodDoesNotExist", &error, + G_TYPE_STRING, + "blah blah blah blah blah", + G_TYPE_INT, + 10, + G_TYPE_INVALID, G_TYPE_INVALID) != FALSE) lose ("Calling nonexistent method succeeded!"); g_print ("Got EXPECTED error from calling unknown method: %s\n", error->message); - g_error_free (error); + g_clear_error (&error); run_mainloop (); /* Activate a service */ g_print ("Activating echo service\n"); - call = dbus_g_proxy_begin_call (driver, "StartServiceByName", - G_TYPE_STRING, - "org.freedesktop.DBus.TestSuiteEchoService", - G_TYPE_UINT, - 0, - G_TYPE_INVALID); - - error = NULL; - if (!dbus_g_proxy_end_call (driver, call, &error, - G_TYPE_UINT, &result, - G_TYPE_INVALID)) + if (!dbus_g_proxy_call (driver, "StartServiceByName", &error, + G_TYPE_STRING, + "org.freedesktop.DBus.TestSuiteEchoService", + G_TYPE_UINT, 0, + G_TYPE_INVALID, + G_TYPE_UINT, &result, + G_TYPE_INVALID)) lose_gerror ("Failed to complete Activate call", error); g_print ("Starting echo service result = 0x%x\n", result); /* Activate a service again */ g_print ("Activating echo service again\n"); - call = dbus_g_proxy_begin_call (driver, "StartServiceByName", - G_TYPE_STRING, - "org.freedesktop.DBus.TestSuiteEchoService", - G_TYPE_UINT, - 0, - DBUS_TYPE_INVALID); - - error = NULL; - if (!dbus_g_proxy_end_call (driver, call, &error, - G_TYPE_UINT, &result, - G_TYPE_INVALID)) + if (!dbus_g_proxy_call (driver, "StartServiceByName", &error, + G_TYPE_STRING, + "org.freedesktop.DBus.TestSuiteEchoService", + G_TYPE_UINT, + 0, + G_TYPE_INVALID, + G_TYPE_UINT, &result, + G_TYPE_INVALID)) lose_gerror ("Failed to complete Activate call", error); g_print ("Duplicate start of echo service = 0x%x\n", result); @@ -351,20 +393,25 @@ main (int argc, char **argv) run_mainloop (); g_print ("Calling Echo\n"); - call = dbus_g_proxy_begin_call (proxy, "Echo", - G_TYPE_STRING, - "my string hello", - G_TYPE_INVALID); - - error = NULL; - if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_STRING, &v_STRING_2, - G_TYPE_INVALID)) + if (!dbus_g_proxy_call (proxy, "Echo", &error, + G_TYPE_STRING, "my string hello", + G_TYPE_INVALID, + G_TYPE_STRING, &v_STRING_2, + G_TYPE_INVALID)) lose_gerror ("Failed to complete Echo call", error); g_print ("String echoed = \"%s\"\n", v_STRING_2); g_free (v_STRING_2); + g_print ("Calling Echo (async)\n"); + echo_call = dbus_g_proxy_begin_call (proxy, "Echo", + echo_received_cb, NULL, NULL, + G_TYPE_STRING, "my string hello", + G_TYPE_INVALID); + dbus_g_connection_flush (connection); + exit_timeout = g_timeout_add (5000, timed_exit, loop); + g_main_loop_run (loop); + /* Test oneway call and signal handling */ g_print ("Testing Foo emission\n"); @@ -417,10 +464,8 @@ main (int argc, char **argv) lose_gerror ("Failed to create proxy for name owner", error); g_print ("Calling DoNothing\n"); - call = dbus_g_proxy_begin_call (proxy, "DoNothing", - G_TYPE_INVALID); - error = NULL; - if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) + if (!dbus_g_proxy_call (proxy, "DoNothing", &error, + G_TYPE_INVALID, G_TYPE_INVALID)) lose_gerror ("Failed to complete DoNothing call", error); g_print ("Calling Increment\n"); @@ -431,15 +476,24 @@ main (int argc, char **argv) G_TYPE_UINT, &v_UINT32_2, G_TYPE_INVALID)) lose_gerror ("Failed to complete Increment call", error); + g_assert (n_times_echo_cb_entered == 1); if (v_UINT32_2 != 43) lose ("Increment call returned %d, should be 43", v_UINT32_2); + call = dbus_g_proxy_begin_call (proxy, "Increment", + increment_received_cb, g_strdup ("moo"), g_free, + G_TYPE_UINT, 42, + G_TYPE_INVALID); + dbus_g_connection_flush (connection); + exit_timeout = g_timeout_add (5000, timed_exit, loop); + g_main_loop_run (loop); + g_print ("Calling ThrowError\n"); - call = dbus_g_proxy_begin_call (proxy, "ThrowError", G_TYPE_INVALID); - error = NULL; - if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID) != FALSE) + if (dbus_g_proxy_call (proxy, "ThrowError", &error, + G_TYPE_INVALID, 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\": %s", dbus_g_error_get_name (error), error->message); @@ -447,14 +501,13 @@ main (int argc, char **argv) g_print ("ThrowError failed (as expected) returned error: %s\n", error->message); g_clear_error (&error); - g_print ("Calling Uppercase\n"); - call = dbus_g_proxy_begin_call (proxy, "Uppercase", - G_TYPE_STRING, "foobar", - G_TYPE_INVALID); error = NULL; - if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_STRING, &v_STRING_2, - G_TYPE_INVALID)) + g_print ("Calling Uppercase\n"); + if (!dbus_g_proxy_call (proxy, "Uppercase", &error, + G_TYPE_STRING, "foobar", + G_TYPE_INVALID, + G_TYPE_STRING, &v_STRING_2, + G_TYPE_INVALID)) lose_gerror ("Failed to complete Uppercase call", error); if (strcmp ("FOOBAR", v_STRING_2) != 0) lose ("Uppercase call returned unexpected string %s", v_STRING_2); @@ -463,16 +516,14 @@ main (int argc, char **argv) run_mainloop (); g_print ("Calling ManyArgs\n"); - call = dbus_g_proxy_begin_call (proxy, "ManyArgs", - G_TYPE_UINT, 26, - G_TYPE_STRING, "bazwhee", - G_TYPE_DOUBLE, G_PI, - G_TYPE_INVALID); - error = NULL; - if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_DOUBLE, &v_DOUBLE_2, - G_TYPE_STRING, &v_STRING_2, - G_TYPE_INVALID)) + if (!dbus_g_proxy_call (proxy, "ManyArgs", &error, + G_TYPE_UINT, 26, + G_TYPE_STRING, "bazwhee", + G_TYPE_DOUBLE, G_PI, + G_TYPE_INVALID, + G_TYPE_DOUBLE, &v_DOUBLE_2, + G_TYPE_STRING, &v_STRING_2, + G_TYPE_INVALID)) lose_gerror ("Failed to complete ManyArgs call", error); if (v_DOUBLE_2 < 55 || v_DOUBLE_2 > 56) lose ("ManyArgs call returned unexpected double value %f", v_DOUBLE_2); @@ -827,9 +878,9 @@ main (int argc, char **argv) DBUS_TYPE_G_OBJECT_PATH, &ret_path, G_TYPE_INVALID)) - lose_gerror ("Failed to complete (wrapped) Objpath call 2", error); + lose_gerror ("Failed to complete Objpath call 2", error); if (strcmp ("/org/freedesktop/DBus/Tests/MyTestObject2", ret_path) != 0) - lose ("(wrapped) objpath call 2 returned unexpected path %s", + lose ("Objpath call 2 returned unexpected path %s", ret_path); ret_proxy = dbus_g_proxy_new_for_name_owner (connection, @@ -837,6 +888,7 @@ main (int argc, char **argv) ret_path, "org.freedesktop.DBus.Tests.FooObject", &error); + g_free (ret_path); val = 0; if (!org_freedesktop_DBus_Tests_FooObject_get_value (ret_proxy, &val, &error)) @@ -982,7 +1034,7 @@ main (int argc, char **argv) lose ("Didn't get proxy_destroyed"); g_print ("Proxy destroyed successfully\n"); - g_object_unref (G_OBJECT (proxy)); + /* Don't need to unref, proxy was destroyed */ run_mainloop (); @@ -1122,12 +1174,10 @@ main (int argc, char **argv) lose_gerror ("Failed to create proxy for name owner", error); g_print ("Testing introspect\n"); - call = dbus_g_proxy_begin_call (proxy, "Introspect", - G_TYPE_INVALID); - error = NULL; - if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_STRING, &v_STRING_2, - G_TYPE_INVALID)) + if (!dbus_g_proxy_call (proxy, "Introspect", &error, + G_TYPE_INVALID, + G_TYPE_STRING, &v_STRING_2, + G_TYPE_INVALID)) lose_gerror ("Failed to complete Introspect call", error); /* Could just do strcmp(), but that seems more fragile */ diff --git a/tools/dbus-monitor.c b/tools/dbus-monitor.c index fa9a9da6..9bd95ea3 100644 --- a/tools/dbus-monitor.c +++ b/tools/dbus-monitor.c @@ -32,7 +32,7 @@ filter_func (DBusConnection *connection, DBusMessage *message, void *user_data) { - print_message (message); + print_message (message, FALSE); if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, diff --git a/tools/dbus-names-model.c b/tools/dbus-names-model.c index b1ea24eb..65faa1b4 100644 --- a/tools/dbus-names-model.c +++ b/tools/dbus-names-model.c @@ -43,7 +43,7 @@ struct NamesModel GtkListStore parent; DBusGConnection *connection; DBusGProxy *driver_proxy; - DBusGPendingCall *pending_list_names; + DBusGProxyCall *pending_list_names; }; struct NamesModelClass @@ -59,7 +59,8 @@ struct NamesModelClass #define NAMES_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_NAMES_MODEL, NamesModelClass)) static void -have_names_notify (DBusGPendingCall *call, +have_names_notify (DBusGProxy *proxy, + DBusGProxyCall *call, void *data) { NamesModel *names_model; @@ -69,7 +70,7 @@ have_names_notify (DBusGPendingCall *call, names_model = NAMES_MODEL (data); - g_assert (names_model->pending_list_names); + g_assert (names_model->pending_list_names == call); g_assert (names_model->driver_proxy); names = NULL; @@ -195,8 +196,8 @@ names_model_reload (NamesModel *names_model) if (names_model->pending_list_names) { - dbus_g_pending_call_cancel (names_model->pending_list_names); - dbus_g_pending_call_unref (names_model->pending_list_names); + dbus_g_proxy_cancel_call (names_model->driver_proxy, + names_model->pending_list_names); names_model->pending_list_names = NULL; } @@ -208,10 +209,8 @@ names_model_reload (NamesModel *names_model) names_model->pending_list_names = dbus_g_proxy_begin_call (names_model->driver_proxy, "ListNames", + have_names_notify, names_model, NULL, G_TYPE_INVALID); - - dbus_g_pending_call_set_notify (names_model->pending_list_names, - have_names_notify, names_model, NULL); } static void diff --git a/tools/dbus-print-message.c b/tools/dbus-print-message.c index bd47666c..e201fda3 100644 --- a/tools/dbus-print-message.c +++ b/tools/dbus-print-message.c @@ -40,7 +40,7 @@ type_to_name (int message_type) } static void -print_iter (DBusMessageIter *iter, int depth) +print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth) { do { @@ -62,7 +62,11 @@ print_iter (DBusMessageIter *iter, int depth) { case DBUS_TYPE_STRING: dbus_message_iter_get_basic (iter, &str); - printf ("string \"%s\"\n", str); + if (!literal) + printf ("string \""); + printf ("%s", str); + if (!literal) + printf ("\"\n"); break; case DBUS_TYPE_INT32: @@ -97,7 +101,7 @@ print_iter (DBusMessageIter *iter, int depth) dbus_message_iter_recurse (iter, &subiter); printf ("variant:"); - print_iter (&subiter, depth); + print_iter (&subiter, literal, depth); break; } case DBUS_TYPE_ARRAY: @@ -110,7 +114,7 @@ print_iter (DBusMessageIter *iter, int depth) printf("["); while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) { - print_iter (&subiter, depth); + print_iter (&subiter, literal, depth); dbus_message_iter_next (&subiter); if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID) printf (","); @@ -125,9 +129,9 @@ print_iter (DBusMessageIter *iter, int depth) dbus_message_iter_recurse (iter, &subiter); printf("{"); - print_iter (&subiter, depth); + print_iter (&subiter, literal, depth); dbus_message_iter_next (&subiter); - print_iter (&subiter, depth); + print_iter (&subiter, literal, depth); printf("}"); break; } @@ -141,7 +145,7 @@ print_iter (DBusMessageIter *iter, int depth) } void -print_message (DBusMessage *message) +print_message (DBusMessage *message, dbus_bool_t literal) { DBusMessageIter iter; const char *sender; @@ -151,37 +155,40 @@ print_message (DBusMessage *message) message_type = dbus_message_get_type (message); sender = dbus_message_get_sender (message); destination = dbus_message_get_destination (message); - - printf ("%s sender=%s -> dest=%s", - type_to_name (message_type), - sender ? sender : "(null sender)", - destination ? destination : "(null destination)"); - - switch (message_type) + + if (!literal) { - case DBUS_MESSAGE_TYPE_METHOD_CALL: - case DBUS_MESSAGE_TYPE_SIGNAL: - printf (" interface=%s; member=%s\n", - dbus_message_get_interface (message), - dbus_message_get_member (message)); - break; + printf ("%s sender=%s -> dest=%s", + type_to_name (message_type), + sender ? sender : "(null sender)", + destination ? destination : "(null destination)"); + + switch (message_type) + { + case DBUS_MESSAGE_TYPE_METHOD_CALL: + case DBUS_MESSAGE_TYPE_SIGNAL: + printf (" interface=%s; member=%s\n", + dbus_message_get_interface (message), + dbus_message_get_member (message)); + break; - case DBUS_MESSAGE_TYPE_METHOD_RETURN: - printf ("\n"); - break; + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + printf ("\n"); + break; - case DBUS_MESSAGE_TYPE_ERROR: - printf (" error_name=%s\n", - dbus_message_get_error_name (message)); - break; + case DBUS_MESSAGE_TYPE_ERROR: + printf (" error_name=%s\n", + dbus_message_get_error_name (message)); + break; - default: - printf ("\n"); - break; + default: + printf ("\n"); + break; + } } dbus_message_iter_init (message, &iter); - print_iter (&iter, 1); + print_iter (&iter, literal, 1); } diff --git a/tools/dbus-print-message.h b/tools/dbus-print-message.h index c40e7667..a999450d 100644 --- a/tools/dbus-print-message.h +++ b/tools/dbus-print-message.h @@ -26,6 +26,6 @@ #include #include -void print_message (DBusMessage *message); +void print_message (DBusMessage *message, dbus_bool_t literal); #endif /* DBUS_PRINT_MESSAGE_H */ diff --git a/tools/dbus-send.c b/tools/dbus-send.c index 37b72067..477a8abd 100644 --- a/tools/dbus-send.c +++ b/tools/dbus-send.c @@ -32,7 +32,7 @@ static const char *appname; static void usage (int ecode) { - fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=NAME] [--type=TYPE] [--print-reply] [--reply-timeout=MSEC] [contents ...]\n", appname); + fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=NAME] [--type=TYPE] [--print-reply=(literal)] [--reply-timeout=MSEC] [contents ...]\n", appname); exit (ecode); } @@ -183,6 +183,7 @@ main (int argc, char *argv[]) DBusError error; DBusMessage *message; int print_reply; + int print_reply_literal; int reply_timeout; DBusMessageIter iter; int i; @@ -199,6 +200,7 @@ main (int argc, char *argv[]) usage (1); print_reply = FALSE; + print_reply_literal = FALSE; reply_timeout = -1; for (i = 1; i < argc && name == NULL; i++) @@ -209,10 +211,12 @@ main (int argc, char *argv[]) type = DBUS_BUS_SYSTEM; else if (strcmp (arg, "--session") == 0) type = DBUS_BUS_SESSION; - else if (strcmp (arg, "--print-reply") == 0) + else if (strncmp (arg, "--print-reply", 13) == 0) { print_reply = TRUE; message_type = DBUS_MESSAGE_TYPE_METHOD_CALL; + if (*(arg + 13) != '\0') + print_reply_literal = TRUE; } else if (strstr (arg, "--reply-timeout=") == arg) { @@ -436,7 +440,7 @@ main (int argc, char *argv[]) if (reply) { - print_message (reply); + print_message (reply, print_reply_literal); dbus_message_unref (reply); } } diff --git a/tools/dbus-viewer.c b/tools/dbus-viewer.c index 95d00c19..ae44075f 100644 --- a/tools/dbus-viewer.c +++ b/tools/dbus-viewer.c @@ -147,14 +147,12 @@ load_child_nodes (const char *service_name, while (tmp != NULL) { DBusGProxy *proxy; - DBusGPendingCall *call; char *data; NodeInfo *child; NodeInfo *complete_child; int save_len; complete_child = NULL; - call = NULL; child = tmp->data; @@ -183,17 +181,11 @@ load_child_nodes (const char *service_name, goto done; } - call = dbus_g_proxy_begin_call (proxy, "Introspect", - G_TYPE_INVALID); - - data = NULL; - if (!dbus_g_proxy_end_call (proxy, call, error, G_TYPE_STRING, &data, - G_TYPE_INVALID)) - { - call = NULL; + if (!dbus_g_proxy_call (proxy, "Introspect", error, + G_TYPE_STRING, &data, + G_TYPE_INVALID, + G_TYPE_INVALID)) goto done; - } - call = NULL; complete_child = description_load_from_string (data, -1, error); g_free (data); @@ -204,8 +196,6 @@ load_child_nodes (const char *service_name, } done: - if (call) - dbus_g_pending_call_unref (call); g_object_unref (proxy); if (complete_child == NULL) @@ -271,7 +261,6 @@ static void* load_from_service_thread_func (void *thread_data) { DBusGProxy *root_proxy; - DBusGPendingCall *call; const char *data; NodeInfo *node; GString *path; @@ -280,7 +269,6 @@ load_from_service_thread_func (void *thread_data) lfsd = thread_data; node = NULL; - call = NULL; path = NULL; #if 1 @@ -304,19 +292,15 @@ load_from_service_thread_func (void *thread_data) } #endif - call = dbus_g_proxy_begin_call (root_proxy, "Introspect", - G_TYPE_INVALID); - - data = NULL; - if (!dbus_g_proxy_end_call (root_proxy, call, &lfsd->error, G_TYPE_STRING, &data, - G_TYPE_INVALID)) + if (!dbus_g_proxy_call (root_proxy, "Introspect", &lfsd->error, + G_TYPE_INVALID, + G_TYPE_STRING, &data, + G_TYPE_INVALID)) { - call = NULL; g_printerr ("Failed to Introspect() %s\n", - dbus_g_proxy_get_bus_name (root_proxy)); + dbus_g_proxy_get_bus_name (root_proxy)); goto out; } - call = NULL; node = description_load_from_string (data, -1, &lfsd->error); @@ -338,9 +322,6 @@ load_from_service_thread_func (void *thread_data) } out: - if (call) - dbus_g_pending_call_unref (call); - g_object_unref (root_proxy); if (path) diff --git a/tools/print-introspect.c b/tools/print-introspect.c index e9fe3ce4..91052cf6 100644 --- a/tools/print-introspect.c +++ b/tools/print-introspect.c @@ -37,7 +37,6 @@ main (int argc, char *argv[]) { DBusGConnection *connection; DBusGProxy *proxy; - DBusGPendingCall *call; GError *error; const char *service; const char *path; @@ -64,9 +63,10 @@ main (int argc, char *argv[]) proxy = dbus_g_proxy_new_for_name (connection, service, path, DBUS_INTERFACE_INTROSPECTABLE); - call = dbus_g_proxy_begin_call (proxy, "Introspect", G_TYPE_INVALID); - if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING, - &introspect_data, G_TYPE_INVALID)) + if (!dbus_g_proxy_call (proxy, "Introspect", &error, + G_TYPE_INVALID, + G_TYPE_STRING, &introspect_data, + G_TYPE_INVALID)) { fprintf (stderr, "Failed to get introspection data: %s\n", error->message); -- cgit