From a6c8a71b1bcba04b63812a61f668e87af0922e5e Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Thu, 14 Aug 2003 22:49:13 +0000 Subject: 2003-08-14 Havoc Pennington * dbus/dbus-pending-call.c: start on new object that will replace DBusMessageHandler and ReplyHandlerData for tracking outstanding replies * dbus/dbus-gproxy.c: start on proxy object used to communicate with remote interfaces * dbus/dbus-gidl.c: do the boring boilerplate in here --- glib/dbus-gproxy.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 glib/dbus-gproxy.c (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c new file mode 100644 index 00000000..4326057a --- /dev/null +++ b/glib/dbus-gproxy.c @@ -0,0 +1,170 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-gcall.c convenience routines for calling methods, etc. + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "dbus-gproxy.h" + +/** + * @addtogroup DBusGLibInternals + * + * @{ + */ + +struct DBusGProxy +{ + int refcount; + DBusConnection *connection; + char *service; + char *interface; + DBusObjectID object_id; +}; + +static DBusGProxy* +_dbus_gproxy_new (DBusConnection *connection) +{ + DBusGProxy *proxy; + + proxy = g_new0 (DBusGProxy, 1); + + proxy->refcount = 1; + proxy->connection = connection; + dbus_connection_ref (connection); + + return proxy; +} + +/** @} End of DBusGLibInternals */ + +/** @addtogroup DBusGLib + * @{ + */ + +/** + * Creates a new proxy for a remote interface. Method calls and signal + * connections over this proxy will go to the service owner; the + * service owner is expected to support the given interface name. THE + * SERVICE OWNER MAY CHANGE OVER TIME, for example between two + * different method calls. If you need a fixed owner, you need to + * request the current owner and bind a proxy to that rather than to + * the generic service name; see dbus_gproxy_new_for_service_owner(). + * + * A service-associated proxy only makes sense with a message bus, + * not for app-to-app direct dbus connections. + * + * @param connection the connection to the remote bus or app + * @param service_name name of the service on the message bus + * @param interface_name name of the interface to call methods on + * @returns new proxy object + */ +DBusGProxy* +dbus_gproxy_new_for_service (DBusConnection *connection, + const char *service_name, + const char *interface_name) +{ + DBusGProxy *proxy; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (service_name != NULL, NULL); + g_return_val_if_fail (interface_name != NULL, NULL); + + proxy = _dbus_gproxy_new (connection); + + proxy->service = g_strdup (service_name); + proxy->interface = g_strdup (interface_name); + + return proxy; +} + +/** + * Increment reference count on proxy object. + * + * @param proxy the proxy + */ +void +dbus_gproxy_ref (DBusGProxy *proxy) +{ + g_return_if_fail (proxy != NULL); + + proxy->refcount += 1; +} + +/** + * Decrement reference count on proxy object. + * + * @param proxy the proxy + */ +void +dbus_gproxy_unref (DBusGProxy *proxy) +{ + g_return_if_fail (proxy != NULL); + + proxy->refcount -= 1; + if (proxy->refcount == 0) + { + dbus_connection_unref (proxy->connection); + g_free (proxy->interface); + g_free (proxy->service); + g_free (proxy); + } +} + +/** + * Invokes a method on a remote interface. This function does not + * block; instead it returns an opaque #DBusGPendingCall 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. + * + * @param proxy a proxy for a remote interface + * @param method the name of the method to invoke + * @param first_arg_type type of the first argument + * + * @returns opaque pending call object + * + */ +DBusGPendingCall* +dbus_gproxy_begin_call (DBusGProxy *proxy, + const char *method, + int first_arg_type, + ...) +{ + + +} + +/** @} End of DBusGLib public */ + +#ifdef DBUS_BUILD_TESTS + +/** + * @ingroup DBusGLibInternals + * Unit test for GLib proxy functions + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_gproxy_test (void) +{ + + return TRUE; +} + +#endif /* DBUS_BUILD_TESTS */ -- cgit From 7c3693a53b4eba0db1aebe1edab5ded21eb7757f Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 16 Aug 2003 21:28:47 +0000 Subject: 2003-08-16 Havoc Pennington * dbus/dbus-object-registry.c (add_and_remove_objects): remove broken assertion * glib/dbus-gproxy.c: some hacking --- glib/dbus-gproxy.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 113 insertions(+), 5 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 4326057a..36f9724c 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -30,6 +30,7 @@ struct DBusGProxy { + GStaticMutex lock; int refcount; DBusConnection *connection; char *service; @@ -37,17 +38,22 @@ struct DBusGProxy DBusObjectID object_id; }; +#define LOCK_PROXY(proxy) (g_static_mutex_lock (&(proxy)->lock)) +#define UNLOCK_PROXY(proxy) (g_static_mutex_unlock (&(proxy)->lock)) + static DBusGProxy* _dbus_gproxy_new (DBusConnection *connection) { DBusGProxy *proxy; proxy = g_new0 (DBusGProxy, 1); - + proxy->refcount = 1; proxy->connection = connection; dbus_connection_ref (connection); + g_static_mutex_init (&proxy->lock); + return proxy; } @@ -96,6 +102,8 @@ dbus_gproxy_new_for_service (DBusConnection *connection, /** * Increment reference count on proxy object. * + * @todo use GAtomic to avoid locking + * * @param proxy the proxy */ void @@ -103,11 +111,17 @@ dbus_gproxy_ref (DBusGProxy *proxy) { g_return_if_fail (proxy != NULL); + LOCK_PROXY (proxy); + proxy->refcount += 1; + + UNLOCK_PROXY (proxy); } /** * Decrement reference count on proxy object. + * + * @todo use GAtomic to avoid locking * * @param proxy the proxy */ @@ -116,23 +130,35 @@ dbus_gproxy_unref (DBusGProxy *proxy) { g_return_if_fail (proxy != NULL); - proxy->refcount -= 1; + LOCK_PROXY (proxy); + + proxy->refcount -= 1; + if (proxy->refcount == 0) { + UNLOCK_PROXY (proxy); + dbus_connection_unref (proxy->connection); g_free (proxy->interface); g_free (proxy->service); + g_static_mutex_free (&proxy->lock); g_free (proxy); } + else + { + UNLOCK_PROXY (proxy); + } } /** * Invokes a method on a remote interface. This function does not - * block; instead it returns an opaque #DBusGPendingCall object that + * 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_gproxy_end_call(). * * @param proxy a proxy for a remote interface * @param method the name of the method to invoke @@ -141,14 +167,96 @@ dbus_gproxy_unref (DBusGProxy *proxy) * @returns opaque pending call object * */ -DBusGPendingCall* +DBusPendingCall* dbus_gproxy_begin_call (DBusGProxy *proxy, const char *method, int first_arg_type, ...) { + g_return_val_if_fail (proxy != NULL, NULL); + LOCK_PROXY (proxy); + + UNLOCK_PROXY (proxy); +} + +/** + * Collects the results of a method call. The method call was normally + * initiated with dbus_gproxy_end_call(). This function will block if + * the results haven't yet been received; use + * dbus_pending_call_set_notify() to be notified asynchronously that a + * pending call has been completed. + * + * If the call results in an error, the error is set as normal for + * GError and the function returns #FALSE. + * + * Otherwise, the "out" parameters and return value of the + * method are stored in the provided varargs list. + * The list should be terminated with DBUS_TYPE_INVALID. + * + * @param proxy a proxy for a remote interface + * @param pending the pending call from dbus_gproxy_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_gproxy_end_call (DBusGProxy *proxy, + DBusPendingCall *pending, + GError **error, + int first_arg_type, + ...) +{ + g_return_val_if_fail (proxy != NULL, FALSE); + LOCK_PROXY (proxy); + + UNLOCK_PROXY (proxy); +} + +/** + * 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 + * when you return to the main loop or block in + * dbus_connection_flush(). + * + * The message is modified to be addressed to the target interface. + * That is, a destination service field or whatever is needed + * will be added to the message. + * + * This function adds a reference to the message, so the caller + * still owns its original reference. + * + * @todo fix for sending to interfaces and object IDs + * + * @param proxy a proxy for a remote interface + * @param message the message to address and send + * @param client_serial return location for message's serial, or #NULL + */ +void +dbus_gproxy_send (DBusGProxy *proxy, + DBusMessage *message, + dbus_uint32_t *client_serial) +{ + g_return_if_fail (proxy != NULL); + LOCK_PROXY (proxy); - + if (proxy->service) + { + if (!dbus_message_set_destination (message, proxy->service)) + g_error ("Out of memory\n"); + } + if (proxy->interface) + { + /* FIXME */ + } + if (!dbus_object_id_is_null (&proxy->object_id)) + { + /* FIXME */ + } + + if (!dbus_connection_send (proxy->connection, message, client_serial)) + g_error ("Out of memory\n"); + + UNLOCK_PROXY (proxy); } /** @} End of DBusGLib public */ -- cgit From 8d38a2e2c5dc95de992c4d856ec1b0c0948bca3e Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 29 Aug 2003 01:05:00 +0000 Subject: 2003-08-28 Havoc Pennington purge DBusObjectID * dbus/dbus-connection.c: port to no ObjectID, create a DBusObjectTree, rename ObjectTree to ObjectPath in public API * dbus/dbus-connection.h (struct DBusObjectTreeVTable): delete everything except UnregisterFunction and MessageFunction * dbus/dbus-marshal.c: port away from DBusObjectID, add DBUS_TYPE_OBJECT_PATH * dbus/dbus-object-registry.[hc], dbus/dbus-object.[hc], dbus/dbus-objectid.[hc]: remove these, we are moving to path-based object IDs --- glib/dbus-gproxy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 36f9724c..01a6b4b9 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -35,7 +35,7 @@ struct DBusGProxy DBusConnection *connection; char *service; char *interface; - DBusObjectID object_id; + char *path; }; #define LOCK_PROXY(proxy) (g_static_mutex_lock (&(proxy)->lock)) @@ -248,7 +248,7 @@ dbus_gproxy_send (DBusGProxy *proxy, { /* FIXME */ } - if (!dbus_object_id_is_null (&proxy->object_id)) + if (proxy->path) { /* FIXME */ } -- cgit From 85ab0327d82e4945ad16630e583d8cc68df25a90 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sun, 7 Sep 2003 23:04:54 +0000 Subject: 2003-09-07 Havoc Pennington * Make Doxygen contented. --- glib/dbus-gproxy.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 01a6b4b9..8951707b 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -28,17 +28,22 @@ * @{ */ +/** + * Internals of DBusGProxy + */ struct DBusGProxy { - GStaticMutex lock; - int refcount; - DBusConnection *connection; - char *service; - char *interface; - char *path; + GStaticMutex lock; /**< Thread lock */ + int refcount; /**< Reference count */ + DBusConnection *connection; /**< Connection to communicate over */ + char *service; /**< Service messages go to or NULL */ + char *interface; /**< Interface messages go to or NULL */ + char *path; /**< Path messages go to or NULL */ }; +/** Lock the DBusGProxy */ #define LOCK_PROXY(proxy) (g_static_mutex_lock (&(proxy)->lock)) +/** Unlock the DBusGProxy */ #define UNLOCK_PROXY(proxy) (g_static_mutex_unlock (&(proxy)->lock)) static DBusGProxy* -- cgit From 583994cb3b7f5562fb7b8c37b4cb0d5af78e4ce2 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 17 Sep 2003 03:52:07 +0000 Subject: 2003-09-15 Havoc Pennington * dbus/dbus-pending-call.c: add the get/set object data boilerplate as for DBusConnection, etc. Use generic object data for the notify callback. * glib/dbus-gparser.c (parse_node): parse child nodes * tools/dbus-viewer.c: more hacking on the dbus-viewer * glib/dbus-gutils.c (_dbus_gutils_split_path): add a file to contain functions shared between the convenience lib and the installed lib * glib/Makefile.am (libdbus_glib_1_la_LDFLAGS): add -export-symbols-regex to the GLib library * dbus/dbus-object-tree.c (_dbus_object_tree_dispatch_and_unlock): fix the locking in here, and add a default handler for Introspect() that just returns sub-nodes. 2003-09-14 Havoc Pennington * glib/dbus-gthread.c (dbus_g_thread_init): rename to make g_foo rather than gfoo consistent * glib/dbus-gproxy.h: delete for now, move contents to dbus-glib.h, because the include files don't work right since we aren't in the dbus/ subdir. * glib/dbus-gproxy.c (dbus_gproxy_send): finish implementing (dbus_gproxy_end_call): finish (dbus_gproxy_begin_call): finish * glib/dbus-gmain.c (dbus_set_g_error): new * glib/dbus-gobject.c (handle_introspect): include information about child nodes in the introspection * dbus/dbus-connection.c (dbus_connection_list_registered): new function to help in implementation of introspection * dbus/dbus-object-tree.c (_dbus_object_tree_list_registered_and_unlock): new function 2003-09-12 Havoc Pennington * glib/dbus-gidl.h: add common base class for all the foo_info types * tools/dbus-viewer.c: add GTK-based introspection UI thingy similar to kdcop * test/Makefile.am: try test srcdir -ef . in addition to test srcdir = ., one of them should work (yeah lame) * glib/Makefile.am: build the "idl" parser stuff as a convenience library * glib/dbus-gparser.h: make description_load routines return NodeInfo* not Parser* * Makefile.am (SUBDIRS): build test dir after all library dirs * configure.in: add GTK+ detection --- glib/dbus-gproxy.c | 101 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 16 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 8951707b..59d86a31 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "dbus-gproxy.h" +#include "dbus-glib.h" /** * @addtogroup DBusGLibInternals @@ -165,23 +165,59 @@ dbus_gproxy_unref (DBusGProxy *proxy) * To collect the results of the call (which may be an error, * or a reply), use dbus_gproxy_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 first_arg_type type of the first argument * * @returns opaque pending call object - * - */ + * */ DBusPendingCall* dbus_gproxy_begin_call (DBusGProxy *proxy, const char *method, int first_arg_type, ...) { + DBusPendingCall *pending; + DBusMessage *message; + va_list args; + g_return_val_if_fail (proxy != NULL, NULL); LOCK_PROXY (proxy); + message = dbus_message_new_method_call (proxy->service, + proxy->interface, + proxy->path, + method); + if (message == NULL) + goto oom; + + va_start (args, first_arg_type); + if (!dbus_message_append_args_valist (message, first_arg_type, + args)) + goto oom; + va_end (args); + + if (!dbus_connection_send_with_reply (proxy->connection, + message, + &pending, + -1)) + goto oom; + UNLOCK_PROXY (proxy); + + return pending; + + oom: + /* FIXME we should create a pending call that's + * immediately completed with an error status without + * ever going on the wire. + */ + + g_error ("Out of memory"); + return NULL; } /** @@ -189,7 +225,9 @@ dbus_gproxy_begin_call (DBusGProxy *proxy, * initiated with dbus_gproxy_end_call(). This function will block if * the results haven't yet been received; use * dbus_pending_call_set_notify() to be notified asynchronously that a - * pending call has been completed. + * pending call has been completed. Use + * dbus_pending_call_get_completed() to check whether a call has been + * completed. If it's completed, it will not block. * * If the call results in an error, the error is set as normal for * GError and the function returns #FALSE. @@ -198,12 +236,15 @@ dbus_gproxy_begin_call (DBusGProxy *proxy, * method are stored in the provided varargs list. * The list should be terminated with DBUS_TYPE_INVALID. * + * This function doesn't affect the reference count of the + * #DBusPendingCall, the caller of dbus_gproxy_begin_call() still owns + * a reference. + * * @param proxy a proxy for a remote interface * @param pending the pending call from dbus_gproxy_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 - */ + * @returns #FALSE if an error is set */ gboolean dbus_gproxy_end_call (DBusGProxy *proxy, DBusPendingCall *pending, @@ -211,10 +252,37 @@ dbus_gproxy_end_call (DBusGProxy *proxy, int first_arg_type, ...) { + DBusMessage *message; + va_list args; + DBusError derror; + g_return_val_if_fail (proxy != NULL, FALSE); + g_return_val_if_fail (pending != NULL, FALSE); + LOCK_PROXY (proxy); + dbus_pending_call_block (pending); + message = dbus_pending_call_get_reply (pending); + + g_assert (message != NULL); + + dbus_error_init (&derror); + va_start (args, first_arg_type); + if (!dbus_message_get_args_valist (message, &derror, first_arg_type, args)) + { + va_end (args); + goto error; + } + va_end (args); + UNLOCK_PROXY (proxy); + + return TRUE; + + error: + dbus_set_g_error (error, &derror); + dbus_error_free (&derror); + return FALSE; } /** @@ -224,18 +292,17 @@ dbus_gproxy_end_call (DBusGProxy *proxy, * dbus_connection_flush(). * * The message is modified to be addressed to the target interface. - * That is, a destination service field or whatever is needed - * will be added to the message. + * That is, a destination service field or whatever is needed will be + * added to the message. The basic point of this function is to add + * the necessary header fields, otherwise it's equivalent to + * dbus_connection_send(). * * This function adds a reference to the message, so the caller * still owns its original reference. - * - * @todo fix for sending to interfaces and object IDs * * @param proxy a proxy for a remote interface * @param message the message to address and send - * @param client_serial return location for message's serial, or #NULL - */ + * @param client_serial return location for message's serial, or #NULL */ void dbus_gproxy_send (DBusGProxy *proxy, DBusMessage *message, @@ -247,17 +314,19 @@ dbus_gproxy_send (DBusGProxy *proxy, if (proxy->service) { if (!dbus_message_set_destination (message, proxy->service)) - g_error ("Out of memory\n"); + g_error ("Out of memory"); } if (proxy->interface) { - /* FIXME */ + if (!dbus_message_set_interface (message, proxy->interface)) + g_error ("Out of memory"); } if (proxy->path) { - /* FIXME */ + if (!dbus_message_set_path (message, proxy->path)) + g_error ("Out of memory"); } - + if (!dbus_connection_send (proxy->connection, message, client_serial)) g_error ("Out of memory\n"); -- cgit From a683a80c409cc4f2e57ba6a3e60d52f91b8657d0 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sun, 21 Sep 2003 19:53:56 +0000 Subject: 2003-09-21 Havoc Pennington Get matching rules mostly working in the bus; only actually parsing the rule text remains. However, the client side of "signal connections" hasn't been started, this patch is only the bus side. * dbus/dispatch.c: fix for the matching rules changes * bus/driver.c (bus_driver_handle_remove_match) (bus_driver_handle_add_match): send an ack reply from these method calls * glib/dbus-gproxy.c (dbus_gproxy_begin_call): fix order of arguments, reported by Seth Nickell * bus/config-parser.c (append_rule_from_element): support eavesdrop=true|false attribute on policies so match rules can be prevented from snooping on the system bus. * bus/dbus-daemon-1.1.in: consistently use terminology "sender" and "destination" in attribute names; fix some docs bugs; add eavesdrop=true|false attribute * bus/driver.c (bus_driver_handle_add_match) (bus_driver_handle_remove_match): handle AddMatch, RemoveMatch messages * dbus/dbus-protocol.h (DBUS_SERVICE_ORG_FREEDESKTOP_BROADCAST): get rid of broadcast service concept, signals are just always broadcast * bus/signals.c, bus/dispatch.c, bus/connection.c, bus/bus.c: mostly implement matching rules stuff (currently only exposed as signal connections) --- glib/dbus-gproxy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 59d86a31..b77e7d30 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -188,8 +188,8 @@ dbus_gproxy_begin_call (DBusGProxy *proxy, LOCK_PROXY (proxy); message = dbus_message_new_method_call (proxy->service, - proxy->interface, proxy->path, + proxy->interface, method); if (message == NULL) goto oom; -- cgit From c9332907b035b52103c5569119d0a7c9fbcb76ac Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 22 Sep 2003 03:11:12 +0000 Subject: 2003-09-21 Havoc Pennington * glib/dbus-gproxy.c (dbus_gproxy_manager_new): start implementing the proxy manager, didn't get very far. * dbus/dbus-bus.c (dbus_bus_add_match): new (dbus_bus_remove_match): new * glib/dbus-gproxy.c (dbus_gproxy_new_for_service): add a path_name argument; adjust the other not-yet-implemented gproxy constructors to be what I think they should be. --- glib/dbus-gproxy.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 6 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index b77e7d30..96a27888 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -28,6 +28,83 @@ * @{ */ +/** + * DBusGProxyManager's primary task is to route signals to the proxies + * those signals are emitted on. In order to do this it also has to + * track the owners of the services proxies are bound to. + */ +typedef struct +{ + GStaticMutex lock; /**< Thread lock */ + int refcount; /**< Reference count */ + + + +} DBusGProxyManager; + + +/** Lock the DBusGProxyManager */ +#define LOCK_MANAGER(mgr) (g_static_mutex_lock (&(mgr)->lock)) +/** Unlock the DBusGProxyManager */ +#define UNLOCK_MANAGER(mgr) (g_static_mutex_unlock (&(mgr)->lock)) + +static DBusGProxyManager* +dbus_gproxy_manager_new (void) +{ + DBusGProxyManager *manager; + + manager = g_new0 (DBusGProxyManager, 1); + + manager->refcount = 1; + + g_static_mutex_init (&manager->lock); + + return manager; +} + +static void +dbus_gproxy_manager_ref (DBusGProxyManager *manager) +{ + g_assert (manager != NULL); + g_assert (manager->refcount > 0); + + LOCK_MANAGER (manager); + + manager->refcount += 1; + + UNLOCK_MANAGER (manager); +} + +static void +dbus_gproxy_manager_unref (DBusGProxyManager *manager) +{ + g_assert (manager != NULL); + g_assert (manager->refcount > 0); + + LOCK_MANAGER (manager); + manager->refcount -= 1; + if (manager->refcount == 0) + { + UNLOCK_MANAGER (manager); + + g_static_mutex_free (&manager->lock); + + g_free (manager); + } + else + { + UNLOCK_MANAGER (manager); + } +} + +static DBusGProxyManager* +dbus_gproxy_manager_get_for_connection (DBusConnection *connection) +{ + /* FIXME */ + + return NULL; +} + /** * Internals of DBusGProxy */ @@ -37,8 +114,8 @@ struct DBusGProxy int refcount; /**< Reference count */ DBusConnection *connection; /**< Connection to communicate over */ char *service; /**< Service messages go to or NULL */ - char *interface; /**< Interface messages go to or NULL */ char *path; /**< Path messages go to or NULL */ + char *interface; /**< Interface messages go to or NULL */ }; /** Lock the DBusGProxy */ @@ -82,23 +159,27 @@ _dbus_gproxy_new (DBusConnection *connection) * * @param connection the connection to the remote bus or app * @param service_name name of the service on the message bus + * @param path_name name of the object inside the service to call methods on * @param interface_name name of the interface to call methods on * @returns new proxy object */ DBusGProxy* dbus_gproxy_new_for_service (DBusConnection *connection, const char *service_name, + const char *path_name, const char *interface_name) { DBusGProxy *proxy; g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (service_name != NULL, NULL); + g_return_val_if_fail (path_name != NULL, NULL); g_return_val_if_fail (interface_name != NULL, NULL); proxy = _dbus_gproxy_new (connection); proxy->service = g_strdup (service_name); + proxy->path = g_strdup (path_name); proxy->interface = g_strdup (interface_name); return proxy; @@ -144,8 +225,9 @@ dbus_gproxy_unref (DBusGProxy *proxy) UNLOCK_PROXY (proxy); dbus_connection_unref (proxy->connection); - g_free (proxy->interface); g_free (proxy->service); + g_free (proxy->path); + g_free (proxy->interface); g_static_mutex_free (&proxy->lock); g_free (proxy); } @@ -316,14 +398,14 @@ dbus_gproxy_send (DBusGProxy *proxy, if (!dbus_message_set_destination (message, proxy->service)) g_error ("Out of memory"); } - if (proxy->interface) + if (proxy->path) { - if (!dbus_message_set_interface (message, proxy->interface)) + if (!dbus_message_set_path (message, proxy->path)) g_error ("Out of memory"); } - if (proxy->path) + if (proxy->interface) { - if (!dbus_message_set_path (message, proxy->path)) + if (!dbus_message_set_interface (message, proxy->interface)) g_error ("Out of memory"); } -- cgit From 4be7b14fce835a30b312bfed1492234bf1e0f316 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 22 Sep 2003 23:50:52 +0000 Subject: 2003-09-22 Havoc Pennington * glib/dbus-gproxy.c (dbus_gproxy_manager_get): implement --- glib/dbus-gproxy.c | 69 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 17 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 96a27888..57cdab2f 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -37,28 +37,61 @@ typedef struct { GStaticMutex lock; /**< Thread lock */ int refcount; /**< Reference count */ - + DBusConnection *connection; /**< Connection we're associated with. */ } DBusGProxyManager; - /** Lock the DBusGProxyManager */ #define LOCK_MANAGER(mgr) (g_static_mutex_lock (&(mgr)->lock)) /** Unlock the DBusGProxyManager */ #define UNLOCK_MANAGER(mgr) (g_static_mutex_unlock (&(mgr)->lock)) +static int gproxy_manager_slot = -1; + +/* Lock controlling get/set manager as data on each connection */ +static GStaticMutex connection_gproxy_lock = G_STATIC_MUTEX_INIT; + +static void dbus_gproxy_manager_ref (DBusGProxyManager *manager); + static DBusGProxyManager* -dbus_gproxy_manager_new (void) +dbus_gproxy_manager_get (DBusConnection *connection) { DBusGProxyManager *manager; + dbus_connection_allocate_data_slot (&gproxy_manager_slot); + if (gproxy_manager_slot < 0) + g_error ("out of memory"); + + g_static_mutex_lock (&connection_gproxy_lock); + + manager = dbus_connection_get_data (connection, gproxy_manager_slot); + if (manager != NULL) + { + dbus_connection_free_data_slot (&gproxy_manager_slot); + dbus_gproxy_manager_ref (manager); + g_static_mutex_unlock (&connection_gproxy_lock); + return manager; + } + manager = g_new0 (DBusGProxyManager, 1); manager->refcount = 1; + manager->connection = connection; g_static_mutex_init (&manager->lock); + /* Proxy managers keep the connection alive, which means that + * DBusGProxy indirectly does. To free a connection you have to free + * all the proxies referring to it. + */ + dbus_connection_ref (manager->connection); + + dbus_connection_set_data (connection, gproxy_manager_slot, + manager, NULL); + + g_static_mutex_unlock (&connection_gproxy_lock); + return manager; } @@ -89,7 +122,18 @@ dbus_gproxy_manager_unref (DBusGProxyManager *manager) g_static_mutex_free (&manager->lock); + g_static_mutex_lock (&connection_gproxy_lock); + + dbus_connection_set_data (manager->connection, + gproxy_manager_slot, + NULL, NULL); + + g_static_mutex_unlock (&connection_gproxy_lock); + + dbus_connection_unref (manager->connection); g_free (manager); + + dbus_connection_free_data_slot (&gproxy_manager_slot); } else { @@ -97,14 +141,6 @@ dbus_gproxy_manager_unref (DBusGProxyManager *manager) } } -static DBusGProxyManager* -dbus_gproxy_manager_get_for_connection (DBusConnection *connection) -{ - /* FIXME */ - - return NULL; -} - /** * Internals of DBusGProxy */ @@ -112,7 +148,7 @@ struct DBusGProxy { GStaticMutex lock; /**< Thread lock */ int refcount; /**< Reference count */ - DBusConnection *connection; /**< Connection to communicate over */ + DBusGProxyManager *manager; /**< Proxy manager */ char *service; /**< Service messages go to or NULL */ char *path; /**< Path messages go to or NULL */ char *interface; /**< Interface messages go to or NULL */ @@ -131,8 +167,7 @@ _dbus_gproxy_new (DBusConnection *connection) proxy = g_new0 (DBusGProxy, 1); proxy->refcount = 1; - proxy->connection = connection; - dbus_connection_ref (connection); + proxy->manager = dbus_gproxy_manager_get (connection); g_static_mutex_init (&proxy->lock); @@ -224,7 +259,7 @@ dbus_gproxy_unref (DBusGProxy *proxy) { UNLOCK_PROXY (proxy); - dbus_connection_unref (proxy->connection); + dbus_gproxy_manager_unref (proxy->manager); g_free (proxy->service); g_free (proxy->path); g_free (proxy->interface); @@ -282,7 +317,7 @@ dbus_gproxy_begin_call (DBusGProxy *proxy, goto oom; va_end (args); - if (!dbus_connection_send_with_reply (proxy->connection, + if (!dbus_connection_send_with_reply (proxy->manager->connection, message, &pending, -1)) @@ -409,7 +444,7 @@ dbus_gproxy_send (DBusGProxy *proxy, g_error ("Out of memory"); } - if (!dbus_connection_send (proxy->connection, message, client_serial)) + if (!dbus_connection_send (proxy->manager->connection, message, client_serial)) g_error ("Out of memory\n"); UNLOCK_PROXY (proxy); -- cgit From 0a34a4400619034e2be47f4387edf0204185d38b Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 23 Sep 2003 04:20:06 +0000 Subject: 2003-09-23 Havoc Pennington * glib/dbus-gproxy.c (struct DBusGProxy): convert to a GObject subclass. This means dropping the transparent thread safety of the proxy; you now need a separate proxy per-thread, or your own locking on the proxy. Probably right anyway. (dbus_gproxy_ref, dbus_gproxy_unref): nuke, just use g_object_ref --- glib/dbus-gproxy.c | 160 ++++++++++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 80 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 57cdab2f..05a073bf 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -146,32 +146,55 @@ dbus_gproxy_manager_unref (DBusGProxyManager *manager) */ struct DBusGProxy { - GStaticMutex lock; /**< Thread lock */ - int refcount; /**< Reference count */ + GObject parent; + DBusGProxyManager *manager; /**< Proxy manager */ - char *service; /**< Service messages go to or NULL */ - char *path; /**< Path messages go to or NULL */ - char *interface; /**< Interface messages go to or NULL */ + char *service; /**< Service messages go to or NULL */ + char *path; /**< Path messages go to or NULL */ + char *interface; /**< Interface messages go to or NULL */ }; -/** Lock the DBusGProxy */ -#define LOCK_PROXY(proxy) (g_static_mutex_lock (&(proxy)->lock)) -/** Unlock the DBusGProxy */ -#define UNLOCK_PROXY(proxy) (g_static_mutex_unlock (&(proxy)->lock)) +struct DBusGProxyClass +{ + GObjectClass parent_class; +}; -static DBusGProxy* -_dbus_gproxy_new (DBusConnection *connection) +static void dbus_gproxy_init (DBusGProxy *proxy); +static void dbus_gproxy_class_init (DBusGProxyClass *klass); +static void dbus_gproxy_finalize (GObject *object); + +static void *parent_class; + +static void +dbus_gproxy_init (DBusGProxy *proxy) { - DBusGProxy *proxy; + /* Nothing */ +} - proxy = g_new0 (DBusGProxy, 1); +static void +dbus_gproxy_class_init (DBusGProxyClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); - proxy->refcount = 1; - proxy->manager = dbus_gproxy_manager_get (connection); + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = dbus_gproxy_finalize; +} - g_static_mutex_init (&proxy->lock); +static void +dbus_gproxy_finalize (GObject *object) +{ + DBusGProxy *proxy; + + proxy = DBUS_GPROXY (object); + + if (proxy->manager) + dbus_gproxy_manager_unref (proxy->manager); + g_free (proxy->service); + g_free (proxy->path); + g_free (proxy->interface); - return proxy; + G_OBJECT_CLASS (parent_class)->finalize (object); } /** @} End of DBusGLibInternals */ @@ -180,6 +203,39 @@ _dbus_gproxy_new (DBusConnection *connection) * @{ */ +/** + * Standard GObject get_type() function for DBusGProxy. + * + * @returns type ID for DBusGProxy class + */ +GType +dbus_gproxy_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (DBusGProxyClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) dbus_gproxy_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (DBusGProxy), + 0, /* n_preallocs */ + (GInstanceInitFunc) dbus_gproxy_init, + }; + + object_type = g_type_register_static (G_TYPE_OBJECT, + "DBusGProxy", + &object_info, 0); + } + + return object_type; +} + /** * Creates a new proxy for a remote interface. Method calls and signal * connections over this proxy will go to the service owner; the @@ -211,8 +267,14 @@ dbus_gproxy_new_for_service (DBusConnection *connection, g_return_val_if_fail (path_name != NULL, NULL); g_return_val_if_fail (interface_name != NULL, NULL); - proxy = _dbus_gproxy_new (connection); + proxy = g_object_new (DBUS_TYPE_GPROXY, NULL); + /* These should all be construct-only mandatory properties, + * for now we just don't let people use g_object_new(). + */ + + proxy->manager = dbus_gproxy_manager_get (connection); + proxy->service = g_strdup (service_name); proxy->path = g_strdup (path_name); proxy->interface = g_strdup (interface_name); @@ -220,58 +282,6 @@ dbus_gproxy_new_for_service (DBusConnection *connection, return proxy; } -/** - * Increment reference count on proxy object. - * - * @todo use GAtomic to avoid locking - * - * @param proxy the proxy - */ -void -dbus_gproxy_ref (DBusGProxy *proxy) -{ - g_return_if_fail (proxy != NULL); - - LOCK_PROXY (proxy); - - proxy->refcount += 1; - - UNLOCK_PROXY (proxy); -} - -/** - * Decrement reference count on proxy object. - * - * @todo use GAtomic to avoid locking - * - * @param proxy the proxy - */ -void -dbus_gproxy_unref (DBusGProxy *proxy) -{ - g_return_if_fail (proxy != NULL); - - LOCK_PROXY (proxy); - - proxy->refcount -= 1; - - if (proxy->refcount == 0) - { - UNLOCK_PROXY (proxy); - - dbus_gproxy_manager_unref (proxy->manager); - g_free (proxy->service); - g_free (proxy->path); - g_free (proxy->interface); - g_static_mutex_free (&proxy->lock); - g_free (proxy); - } - else - { - UNLOCK_PROXY (proxy); - } -} - /** * Invokes a method on a remote interface. This function does not * block; instead it returns an opaque #DBusPendingCall object that @@ -302,7 +312,6 @@ dbus_gproxy_begin_call (DBusGProxy *proxy, va_list args; g_return_val_if_fail (proxy != NULL, NULL); - LOCK_PROXY (proxy); message = dbus_message_new_method_call (proxy->service, proxy->path, @@ -322,8 +331,6 @@ dbus_gproxy_begin_call (DBusGProxy *proxy, &pending, -1)) goto oom; - - UNLOCK_PROXY (proxy); return pending; @@ -375,8 +382,6 @@ dbus_gproxy_end_call (DBusGProxy *proxy, g_return_val_if_fail (proxy != NULL, FALSE); g_return_val_if_fail (pending != NULL, FALSE); - - LOCK_PROXY (proxy); dbus_pending_call_block (pending); message = dbus_pending_call_get_reply (pending); @@ -392,8 +397,6 @@ dbus_gproxy_end_call (DBusGProxy *proxy, } va_end (args); - UNLOCK_PROXY (proxy); - return TRUE; error: @@ -426,7 +429,6 @@ dbus_gproxy_send (DBusGProxy *proxy, dbus_uint32_t *client_serial) { g_return_if_fail (proxy != NULL); - LOCK_PROXY (proxy); if (proxy->service) { @@ -446,8 +448,6 @@ dbus_gproxy_send (DBusGProxy *proxy, if (!dbus_connection_send (proxy->manager->connection, message, client_serial)) g_error ("Out of memory\n"); - - UNLOCK_PROXY (proxy); } /** @} End of DBusGLib public */ -- cgit From cefe445bea082f0891142ac4b746893e4ffb7d1f Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 23 Sep 2003 05:04:51 +0000 Subject: trivial header change --- glib/dbus-gproxy.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index 05a073bf..f27eb6d0 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -450,6 +450,29 @@ dbus_gproxy_send (DBusGProxy *proxy, g_error ("Out of memory\n"); } +void +dbus_gproxy_connect_signal (DBusGProxy *proxy, + const char *interface_name, + const char *signal_name, + GCallback callback, + void *data, + GFreeFunc free_data_func) +{ + + +} + +void +dbus_gproxy_disconnect_signal (DBusGProxy *proxy, + const char *interface_name, + const char *signal_name, + GCallback callback, + void *data) +{ + + +} + /** @} End of DBusGLib public */ #ifdef DBUS_BUILD_TESTS -- cgit From 52f275a7f43a78f981d0ccc85d5882ff4c356bdd Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 23 Sep 2003 23:47:09 +0000 Subject: 2003-09-23 Havoc Pennington * glib/dbus-gproxy.c (dbus_gproxy_connect_signal): implement (dbus_gproxy_disconnect_signal): implement (dbus_gproxy_manager_remove_signal_match): implement (dbus_gproxy_manager_add_signal_match): implement (dbus_gproxy_oneway_call): implement --- glib/dbus-gproxy.c | 629 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 581 insertions(+), 48 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index f27eb6d0..ebcbb5d4 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -21,6 +21,7 @@ * */ #include "dbus-glib.h" +#include /** * @addtogroup DBusGLibInternals @@ -28,19 +29,69 @@ * @{ */ +typedef struct DBusGProxyManager DBusGProxyManager; + +/** + * Internals of DBusGProxy + */ +struct DBusGProxy +{ + GObject parent; /**< Parent instance */ + + DBusGProxyManager *manager; /**< Proxy manager */ + char *service; /**< Service messages go to or NULL */ + char *path; /**< Path messages go to or NULL */ + char *interface; /**< Interface messages go to or NULL */ +}; + +struct DBusGProxyClass +{ + GObjectClass parent_class; +}; + +static void dbus_gproxy_init (DBusGProxy *proxy); +static void dbus_gproxy_class_init (DBusGProxyClass *klass); +static void dbus_gproxy_finalize (GObject *object); +static void dbus_gproxy_emit_received (DBusGProxy *proxy, + DBusMessage *message); + + +/** + * A list of proxies with a given service+path+interface, used to route incoming + * signals. + */ +typedef struct +{ + GSList *proxies; + + char name[4]; /**< service (empty string for none), nul byte, + * path, nul byte, + * interface, nul byte + */ + +} DBusGProxyList; + /** * DBusGProxyManager's primary task is to route signals to the proxies * those signals are emitted on. In order to do this it also has to * track the owners of the services proxies are bound to. */ -typedef struct +struct DBusGProxyManager { GStaticMutex lock; /**< Thread lock */ int refcount; /**< Reference count */ DBusConnection *connection; /**< Connection we're associated with. */ - -} DBusGProxyManager; + GHashTable *proxy_lists; /**< Hash used to route incoming signals + * and iterate over proxies + */ + +}; + +static void dbus_gproxy_manager_ref (DBusGProxyManager *manager); +static DBusHandlerResult dbus_gproxy_manager_filter (DBusConnection *connection, + DBusMessage *message, + void *user_data); /** Lock the DBusGProxyManager */ #define LOCK_MANAGER(mgr) (g_static_mutex_lock (&(mgr)->lock)) @@ -52,8 +103,6 @@ static int gproxy_manager_slot = -1; /* Lock controlling get/set manager as data on each connection */ static GStaticMutex connection_gproxy_lock = G_STATIC_MUTEX_INIT; -static void dbus_gproxy_manager_ref (DBusGProxyManager *manager); - static DBusGProxyManager* dbus_gproxy_manager_get (DBusConnection *connection) { @@ -90,6 +139,9 @@ dbus_gproxy_manager_get (DBusConnection *connection) dbus_connection_set_data (connection, gproxy_manager_slot, manager, NULL); + dbus_connection_add_filter (connection, dbus_gproxy_manager_filter, + manager, NULL); + g_static_mutex_unlock (&connection_gproxy_lock); return manager; @@ -119,10 +171,19 @@ dbus_gproxy_manager_unref (DBusGProxyManager *manager) if (manager->refcount == 0) { UNLOCK_MANAGER (manager); + + if (manager->proxy_lists) + { + g_hash_table_destroy (manager->proxy_lists); + manager->proxy_lists = NULL; + } g_static_mutex_free (&manager->lock); g_static_mutex_lock (&connection_gproxy_lock); + + dbus_connection_remove_filter (manager->connection, dbus_gproxy_manager_filter, + manager); dbus_connection_set_data (manager->connection, gproxy_manager_slot, @@ -141,29 +202,340 @@ dbus_gproxy_manager_unref (DBusGProxyManager *manager) } } -/** - * Internals of DBusGProxy - */ -struct DBusGProxy +static guint +tristring_hash (gconstpointer key) { - GObject parent; + const char *p = key; + guint h = *p; + + if (h) + { + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + *p; + } + + /* skip nul and do the next substring */ + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + *p; + + /* skip nul again and another substring */ + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + *p; - DBusGProxyManager *manager; /**< Proxy manager */ - char *service; /**< Service messages go to or NULL */ - char *path; /**< Path messages go to or NULL */ - char *interface; /**< Interface messages go to or NULL */ -}; + return h; +} -struct DBusGProxyClass +static gboolean +strequal_len (const char *a, + const char *b, + size_t *lenp) { - GObjectClass parent_class; -}; + size_t a_len; + size_t b_len; + + a_len = strlen (a); + b_len = strlen (b); + + if (a_len != b_len) + return FALSE; + + if (memcmp (a, b, a_len) != 0) + return FALSE; + + *lenp = a_len; + + return TRUE; +} + +static gboolean +tristring_equal (gconstpointer a, + gconstpointer b) +{ + const char *ap = a; + const char *bp = b; + size_t len; + + if (!strequal_len (ap, bp, &len)) + return FALSE; + + ap += len + 1; + bp += len + 1; + + if (!strequal_len (ap, bp, &len)) + return FALSE; + + ap += len + 1; + bp += len + 1; + + if (strcmp (ap, bp) != 0) + return FALSE; + + return TRUE; +} + +static char* +tristring_alloc_from_strings (size_t padding_before, + const char *service, + const char *path, + const char *interface) +{ + size_t service_len, iface_len, path_len, len; + char *tri; + + if (service) + service_len = strlen (service); + else + service_len = 0; + + path_len = strlen (path); + + iface_len = strlen (interface); + + tri = g_malloc (padding_before + service_len + path_len + iface_len + 3); + + len = padding_before; + + if (service) + memcpy (&tri[len], service, service_len); + + len += service_len; + tri[len] = '\0'; + len += 1; + + g_assert (len == (padding_before + service_len + 1)); + + memcpy (&tri[len], path, path_len); + len += path_len; + tri[len] = '\0'; + len += 1; + + g_assert (len == (padding_before + service_len + path_len + 2)); + + memcpy (&tri[len], interface, iface_len); + len += iface_len; + tri[len] = '\0'; + len += 1; + + g_assert (len == (padding_before + service_len + path_len + iface_len + 3)); + + return tri; +} + +static char* +tristring_from_proxy (DBusGProxy *proxy) +{ + return tristring_alloc_from_strings (0, + proxy->service, + proxy->path, + proxy->interface); +} + +static char* +tristring_from_message (DBusMessage *message) +{ + return tristring_alloc_from_strings (0, + dbus_message_get_sender (message), + dbus_message_get_path (message), + dbus_message_get_interface (message)); +} + +static DBusGProxyList* +gproxy_list_new (DBusGProxy *first_proxy) +{ + DBusGProxyList *list; + + list = (void*) tristring_alloc_from_strings (G_STRUCT_OFFSET (DBusGProxyList, name), + first_proxy->service, + first_proxy->path, + first_proxy->interface); + list->proxies = NULL; + + return list; +} + +static void +gproxy_list_free (DBusGProxyList *list) +{ + /* we don't hold a reference to the proxies in the list, + * as they ref the GProxyManager + */ + g_slist_free (list->proxies); + + g_free (list); +} + +static char* +gproxy_get_match_rule (DBusGProxy *proxy) +{ + /* FIXME Some sort of escaping is required here I think */ + + if (proxy->service) + return g_strdup_printf ("type='signal',service='%s',path='%s',interface='%s'", + proxy->service, proxy->path, proxy->interface); + else + return g_strdup_printf ("type='signal',path='%s',interface='%s'", + proxy->path, proxy->interface); +} + +static void +dbus_gproxy_manager_register (DBusGProxyManager *manager, + DBusGProxy *proxy) +{ + DBusGProxyList *list; + + LOCK_MANAGER (manager); + + if (manager->proxy_lists == NULL) + { + list = NULL; + manager->proxy_lists = g_hash_table_new_full (tristring_hash, + tristring_equal, + NULL, + (GFreeFunc) gproxy_list_free); + } + else + { + char *tri; + + tri = tristring_from_proxy (proxy); + + list = g_hash_table_lookup (manager->proxy_lists, tri); + + g_free (tri); + } + + if (list == NULL) + { + list = gproxy_list_new (proxy); + + g_hash_table_replace (manager->proxy_lists, + list->name, list); + } + + if (list->proxies == NULL) + { + /* We have to add the match rule to the server, + * but FIXME only if the server is a message bus, + * not if it's a peer. + */ + char *rule; + + rule = gproxy_get_match_rule (proxy); + + /* We don't check for errors; it's not like anyone would handle them, + * and we don't want a round trip here. + */ + dbus_bus_add_match (manager->connection, + rule, NULL); + + g_free (rule); + } + + g_assert (g_slist_find (list->proxies, proxy) == NULL); + + list->proxies = g_slist_prepend (list->proxies, proxy); + + UNLOCK_MANAGER (manager); +} + +static void +dbus_gproxy_manager_unregister (DBusGProxyManager *manager, + DBusGProxy *proxy) +{ + DBusGProxyList *list; + char *tri; + + LOCK_MANAGER (manager); + + if (manager->proxy_lists == NULL) + { + g_warning ("Trying to disconnect a signal on a proxy but none are connected\n"); + return; + } + + tri = tristring_from_proxy (proxy); + + list = g_hash_table_lookup (manager->proxy_lists, tri); + + g_free (tri); + + if (list == NULL) + { + g_warning ("Trying to disconnect a signal on a proxy but none are connected\n"); + return; + } + + g_assert (g_slist_find (list->proxies, proxy) != NULL); + + list->proxies = g_slist_remove (list->proxies, proxy); + + g_assert (g_slist_find (list->proxies, proxy) == NULL); + + UNLOCK_MANAGER (manager); +} + +static DBusHandlerResult +dbus_gproxy_manager_filter (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + DBusGProxyManager *manager; + + manager = user_data; + + if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (dbus_message_is_signal (message, + DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, + "Disconnected")) + { + /* FIXME g_object_run_dispose() all the proxies; should proxies have + * a "destroy" signal? + */ + } + else + { + char *tri; + DBusGProxyList *list; + + tri = tristring_from_message (message); -static void dbus_gproxy_init (DBusGProxy *proxy); -static void dbus_gproxy_class_init (DBusGProxyClass *klass); -static void dbus_gproxy_finalize (GObject *object); + if (manager->proxy_lists) + list = g_hash_table_lookup (manager->proxy_lists, tri); + else + list = NULL; + + g_free (tri); + + if (list != NULL) + { + /* FIXME Emit the signal on each proxy in the list */ + + + } + } + + /* "Handling" signals doesn't make sense, they are for everyone + * who cares + */ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + + + +/* ---------- DBusGProxy -------------- */ + + + +enum +{ + RECEIVED, + LAST_SIGNAL +}; static void *parent_class; +static guint signals[LAST_SIGNAL] = { 0 }; static void dbus_gproxy_init (DBusGProxy *proxy) @@ -179,6 +551,16 @@ dbus_gproxy_class_init (DBusGProxyClass *klass) parent_class = g_type_class_peek_parent (klass); object_class->finalize = dbus_gproxy_finalize; + + signals[RECEIVED] = + g_signal_new ("received", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + DBUS_TYPE_MESSAGE); } static void @@ -189,7 +571,11 @@ dbus_gproxy_finalize (GObject *object) proxy = DBUS_GPROXY (object); if (proxy->manager) - dbus_gproxy_manager_unref (proxy->manager); + { + dbus_gproxy_manager_unregister (proxy->manager, proxy); + dbus_gproxy_manager_unref (proxy->manager); + } + g_free (proxy->service); g_free (proxy->path); g_free (proxy->interface); @@ -197,6 +583,53 @@ dbus_gproxy_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static char* +create_signal_detail (const char *interface, + const char *signal) +{ + GString *str; + + str = g_string_new (interface); + + g_string_append (str, "."); + + g_string_append (str, signal); + + return g_string_free (str, FALSE); +} + +static void +dbus_gproxy_emit_received (DBusGProxy *proxy, + DBusMessage *message) +{ + const char *interface; + const char *signal; + char *detail; + GQuark q; + + interface = dbus_message_get_interface (message); + signal = dbus_message_get_member (message); + + g_assert (interface != NULL); + g_assert (signal != NULL); + + detail = create_signal_detail (interface, signal); + + /* If the quark isn't preexisting, there's no way there + * are any handlers connected. We don't want to create + * extra quarks for every possible signal. + */ + q = g_quark_try_string (detail); + + if (q != 0) + g_signal_emit (G_OBJECT (proxy), + signals[RECEIVED], + q, + message); + + g_free (detail); +} + /** @} End of DBusGLibInternals */ /** @addtogroup DBusGLib @@ -236,6 +669,33 @@ dbus_gproxy_get_type (void) return object_type; } +static DBusGProxy* +dbus_gproxy_new (DBusConnection *connection, + const char *service_name, + const char *path_name, + const char *interface_name) +{ + DBusGProxy *proxy; + + g_assert (connection != NULL); + + proxy = g_object_new (DBUS_TYPE_GPROXY, NULL); + + /* These should all be construct-only mandatory properties, + * for now we just don't let people use g_object_new(). + */ + + proxy->manager = dbus_gproxy_manager_get (connection); + + proxy->service = g_strdup (service_name); + proxy->path = g_strdup (path_name); + proxy->interface = g_strdup (interface_name); + + dbus_gproxy_manager_register (proxy->manager, proxy); + + return proxy; +} + /** * Creates a new proxy for a remote interface. Method calls and signal * connections over this proxy will go to the service owner; the @@ -267,17 +727,8 @@ dbus_gproxy_new_for_service (DBusConnection *connection, g_return_val_if_fail (path_name != NULL, NULL); g_return_val_if_fail (interface_name != NULL, NULL); - proxy = g_object_new (DBUS_TYPE_GPROXY, NULL); - - /* These should all be construct-only mandatory properties, - * for now we just don't let people use g_object_new(). - */ - - proxy->manager = dbus_gproxy_manager_get (connection); - - proxy->service = g_strdup (service_name); - proxy->path = g_strdup (path_name); - proxy->interface = g_strdup (interface_name); + proxy = dbus_gproxy_new (connection, service_name, + path_name, interface_name); return proxy; } @@ -311,7 +762,7 @@ dbus_gproxy_begin_call (DBusGProxy *proxy, DBusMessage *message; va_list args; - g_return_val_if_fail (proxy != NULL, NULL); + g_return_val_if_fail (DBUS_IS_GPROXY (proxy), NULL); message = dbus_message_new_method_call (proxy->service, proxy->path, @@ -380,7 +831,7 @@ dbus_gproxy_end_call (DBusGProxy *proxy, va_list args; DBusError derror; - g_return_val_if_fail (proxy != NULL, FALSE); + g_return_val_if_fail (DBUS_IS_GPROXY (proxy), FALSE); g_return_val_if_fail (pending != NULL, FALSE); dbus_pending_call_block (pending); @@ -405,6 +856,52 @@ dbus_gproxy_end_call (DBusGProxy *proxy, return FALSE; } +/** + * Sends a method call message as with dbus_gproxy_begin_call(), but + * does not ask for a reply or allow you to receive one. + * + * @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 first_arg_type type of the first argument + */ +void +dbus_gproxy_oneway_call (DBusGProxy *proxy, + const char *method, + int first_arg_type, + ...) +{ + DBusMessage *message; + va_list args; + + g_return_if_fail (DBUS_IS_GPROXY (proxy)); + + message = dbus_message_new_method_call (proxy->service, + proxy->path, + proxy->interface, + method); + if (message == NULL) + goto oom; + + dbus_message_set_no_reply (message, TRUE); + + va_start (args, first_arg_type); + if (!dbus_message_append_args_valist (message, first_arg_type, + args)) + goto oom; + va_end (args); + + if (!dbus_connection_send (proxy->manager->connection, + message, + NULL)) + goto oom; + + oom: + g_error ("Out of memory"); +} + /** * 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 @@ -428,7 +925,7 @@ dbus_gproxy_send (DBusGProxy *proxy, DBusMessage *message, dbus_uint32_t *client_serial) { - g_return_if_fail (proxy != NULL); + g_return_if_fail (DBUS_IS_GPROXY (proxy)); if (proxy->service) { @@ -451,26 +948,62 @@ dbus_gproxy_send (DBusGProxy *proxy, } void -dbus_gproxy_connect_signal (DBusGProxy *proxy, - const char *interface_name, - const char *signal_name, - GCallback callback, - void *data, - GFreeFunc free_data_func) +dbus_gproxy_connect_signal (DBusGProxy *proxy, + const char *signal_name, + DBusGProxySignalHandler handler, + void *data, + GFreeFunc free_data_func) { + GClosure *closure; + char *detail; + g_return_if_fail (DBUS_IS_GPROXY (proxy)); + g_return_if_fail (signal_name != NULL); + g_return_if_fail (handler != NULL); + + detail = create_signal_detail (proxy->interface, signal_name); + + closure = g_cclosure_new (G_CALLBACK (handler), data, free_data_func); + g_signal_connect_closure_by_id (G_OBJECT (proxy), + signals[RECEIVED], + g_quark_from_string (detail), + closure, FALSE); + g_free (detail); } void -dbus_gproxy_disconnect_signal (DBusGProxy *proxy, - const char *interface_name, - const char *signal_name, - GCallback callback, - void *data) +dbus_gproxy_disconnect_signal (DBusGProxy *proxy, + const char *signal_name, + DBusGProxySignalHandler handler, + void *data) { + char *detail; + GQuark q; - + g_return_if_fail (DBUS_IS_GPROXY (proxy)); + g_return_if_fail (signal_name != NULL); + g_return_if_fail (handler != NULL); + + detail = create_signal_detail (proxy->interface, signal_name); + q = g_quark_try_string (detail); + g_free (detail); + + if (q == 0) + { + g_warning ("%s: No signal handlers for %s found on this DBusGProxy", + G_GNUC_FUNCTION, signal_name); + return; + } + + g_signal_handlers_disconnect_matched (G_OBJECT (proxy), + G_SIGNAL_MATCH_DETAIL | + G_SIGNAL_MATCH_FUNC | + G_SIGNAL_MATCH_DATA, + signals[RECEIVED], + q, + NULL, + G_CALLBACK (handler), data); } /** @} End of DBusGLib public */ -- cgit From 31881de7dafad50446d2b0c8c0c96aa87a70ba61 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 24 Sep 2003 02:58:14 +0000 Subject: 2003-09-23 Havoc Pennington * glib/dbus-gproxy.c (dbus_gproxy_manager_filter): implement --- glib/dbus-gproxy.c | 258 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 241 insertions(+), 17 deletions(-) (limited to 'glib/dbus-gproxy.c') diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index ebcbb5d4..99900e4c 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -44,6 +44,9 @@ struct DBusGProxy char *interface; /**< Interface messages go to or NULL */ }; +/** + * Class struct for DBusGProxy + */ struct DBusGProxyClass { GObjectClass parent_class; @@ -52,6 +55,8 @@ struct DBusGProxyClass static void dbus_gproxy_init (DBusGProxy *proxy); static void dbus_gproxy_class_init (DBusGProxyClass *klass); static void dbus_gproxy_finalize (GObject *object); +static void dbus_gproxy_dispose (GObject *object); +static void dbus_gproxy_destroy (DBusGProxy *proxy); static void dbus_gproxy_emit_received (DBusGProxy *proxy, DBusMessage *message); @@ -174,6 +179,11 @@ dbus_gproxy_manager_unref (DBusGProxyManager *manager) if (manager->proxy_lists) { + /* can't have any proxies left since they hold + * a reference to the proxy manager. + */ + g_assert (g_hash_table_size (manager->proxy_lists) == 0); + g_hash_table_destroy (manager->proxy_lists); manager->proxy_lists = NULL; } @@ -447,11 +457,13 @@ dbus_gproxy_manager_unregister (DBusGProxyManager *manager, LOCK_MANAGER (manager); +#ifndef G_DISABLE_CHECKS if (manager->proxy_lists == NULL) { g_warning ("Trying to disconnect a signal on a proxy but none are connected\n"); return; } +#endif tri = tristring_from_proxy (proxy); @@ -459,21 +471,70 @@ dbus_gproxy_manager_unregister (DBusGProxyManager *manager, g_free (tri); +#ifndef G_DISABLE_CHECKS if (list == NULL) { g_warning ("Trying to disconnect a signal on a proxy but none are connected\n"); return; } +#endif g_assert (g_slist_find (list->proxies, proxy) != NULL); list->proxies = g_slist_remove (list->proxies, proxy); g_assert (g_slist_find (list->proxies, proxy) == NULL); + + if (g_hash_table_size (manager->proxy_lists) == 0) + { + g_hash_table_destroy (manager->proxy_lists); + manager->proxy_lists = NULL; + } UNLOCK_MANAGER (manager); } +static void +list_proxies_foreach (gpointer key, + gpointer value, + gpointer user_data) +{ + DBusGProxyList *list; + GSList **ret; + GSList *tmp; + + list = value; + ret = user_data; + + tmp = list->proxies; + while (tmp != NULL) + { + DBusGProxy *proxy = DBUS_GPROXY (tmp->data); + + g_object_ref (proxy); + *ret = g_slist_prepend (*ret, proxy); + + tmp = tmp->next; + } +} + +static GSList* +dbus_gproxy_manager_list_all (DBusGProxyManager *manager) +{ + GSList *ret; + + ret = NULL; + + if (manager->proxy_lists) + { + g_hash_table_foreach (manager->proxy_lists, + list_proxies_foreach, + &ret); + } + + return ret; +} + static DBusHandlerResult dbus_gproxy_manager_filter (DBusConnection *connection, DBusMessage *message, @@ -481,18 +542,48 @@ dbus_gproxy_manager_filter (DBusConnection *connection, { DBusGProxyManager *manager; - manager = user_data; - if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + manager = user_data; + + dbus_gproxy_manager_ref (manager); + + LOCK_MANAGER (manager); + if (dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected")) { - /* FIXME g_object_run_dispose() all the proxies; should proxies have - * a "destroy" signal? + /* Destroy all the proxies, quite possibly resulting in unreferencing + * the proxy manager and the connection as well. */ + GSList *all; + GSList *tmp; + + all = dbus_gproxy_manager_list_all (manager); + + tmp = all; + while (tmp != NULL) + { + DBusGProxy *proxy; + + proxy = DBUS_GPROXY (tmp->data); + + UNLOCK_MANAGER (manager); + dbus_gproxy_destroy (proxy); + g_object_unref (G_OBJECT (proxy)); + LOCK_MANAGER (manager); + + tmp = tmp->next; + } + + g_slist_free (all); + +#ifndef G_DISABLE_CHECKS + if (manager->proxy_lists != NULL) + g_warning ("Disconnection emitted \"destroy\" on all DBusGProxy, but somehow new proxies were created in response to one of those destroy signals. This will cause a memory leak."); +#endif } else { @@ -507,14 +598,38 @@ dbus_gproxy_manager_filter (DBusConnection *connection, list = NULL; g_free (tri); + + /* Emit the signal */ if (list != NULL) { - /* FIXME Emit the signal on each proxy in the list */ - + GSList *tmp; + GSList *copy; + copy = g_slist_copy (list->proxies); + g_slist_foreach (copy, (GFunc) g_object_ref, NULL); + + tmp = copy; + while (tmp != NULL) + { + DBusGProxy *proxy; + + proxy = DBUS_GPROXY (tmp->data); + + UNLOCK_MANAGER (manager); + dbus_gproxy_emit_received (proxy, message); + g_object_unref (G_OBJECT (proxy)); + LOCK_MANAGER (manager); + + tmp = tmp->next; + } + + g_slist_free (copy); } } + + UNLOCK_MANAGER (manager); + dbus_gproxy_manager_unref (manager); /* "Handling" signals doesn't make sense, they are for everyone * who cares @@ -530,6 +645,7 @@ dbus_gproxy_manager_filter (DBusConnection *connection, enum { + DESTROY, RECEIVED, LAST_SIGNAL }; @@ -551,7 +667,17 @@ dbus_gproxy_class_init (DBusGProxyClass *klass) parent_class = g_type_class_peek_parent (klass); object_class->finalize = dbus_gproxy_finalize; - + object_class->dispose = dbus_gproxy_dispose; + + signals[DESTROY] = + g_signal_new ("destroy", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals[RECEIVED] = g_signal_new ("received", G_OBJECT_CLASS_TYPE (object_class), @@ -563,6 +689,19 @@ dbus_gproxy_class_init (DBusGProxyClass *klass) DBUS_TYPE_MESSAGE); } + +static void +dbus_gproxy_dispose (GObject *object) +{ + DBusGProxy *proxy; + + proxy = DBUS_GPROXY (object); + + g_signal_emit (object, signals[DESTROY], 0); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + static void dbus_gproxy_finalize (GObject *object) { @@ -583,6 +722,15 @@ dbus_gproxy_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +dbus_gproxy_destroy (DBusGProxy *proxy) +{ + /* FIXME do we need the GTK_IN_DESTRUCTION style flag + * from GtkObject? + */ + g_object_run_dispose (G_OBJECT (proxy)); +} + static char* create_signal_detail (const char *interface, const char *signal) @@ -697,18 +845,22 @@ dbus_gproxy_new (DBusConnection *connection, } /** - * Creates a new proxy for a remote interface. Method calls and signal - * connections over this proxy will go to the service owner; the - * service owner is expected to support the given interface name. THE - * SERVICE OWNER MAY CHANGE OVER TIME, for example between two - * different method calls. If you need a fixed owner, you need to - * request the current owner and bind a proxy to that rather than to - * the generic service name; see dbus_gproxy_new_for_service_owner(). + * Creates a new proxy for a remote interface exported by a service on + * a message bus. Method calls and signal connections over this proxy + * will go to the service owner; the service owner is expected to + * support the given interface name. THE SERVICE OWNER MAY CHANGE OVER + * TIME, for example between two different method calls. If you need a + * fixed owner, you need to request the current owner and bind a proxy + * to that rather than to the generic service name; see + * dbus_gproxy_new_for_service_owner(). * * A service-associated proxy only makes sense with a message bus, * not for app-to-app direct dbus connections. * - * @param connection the connection to the remote bus or app + * This proxy will only emit the "destroy" signal if the #DBusConnection + * is disconnected or the proxy is has no remaining references. + * + * @param connection the connection to the remote bus * @param service_name name of the service on the message bus * @param path_name name of the object inside the service to call methods on * @param interface_name name of the interface to call methods on @@ -733,6 +885,75 @@ dbus_gproxy_new_for_service (DBusConnection *connection, return proxy; } +/** + * Similar to dbus_gproxy_new_for_service(), but makes a round-trip + * request to the message bus to get the current service owner, then + * binds the proxy specifically to the current owner. As a result, the + * service owner will not change over time, and the proxy will emit + * the "destroy" signal when the owner disappears from the message + * bus. + * + * An example of the difference between dbus_gproxy_new_for_service() + * and dbus_gproxy_new_for_service_owner(): if you pass the service name + * "org.freedesktop.Database" dbus_gproxy_new_for_service() remains bound + * to that name as it changes owner. dbus_gproxy_new_for_service_owner() + * will fail if the service has no owner. If the service has an owner, + * dbus_gproxy_new_for_service_owner() will bind to the unique name + * of that owner rather than the generic service name. + * + * @param connection the connection to the remote bus + * @param service_name name of the service on the message bus + * @param path_name name of the object inside the service to call methods on + * @param interface_name name of the interface to call methods on + * @param error return location for an error + * @returns new proxy object, or #NULL on error + */ +DBusGProxy* +dbus_gproxy_new_for_service_owner (DBusConnection *connection, + const char *service_name, + const char *path_name, + const char *interface_name, + GError **error) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (service_name != NULL, NULL); + g_return_val_if_fail (path_name != NULL, NULL); + g_return_val_if_fail (interface_name != NULL, NULL); + + +} + +/** + * Creates a proxy for an object in peer application (one + * we're directly connected to). That is, this function is + * intended for use when there's no message bus involved, + * we're doing a simple 1-to-1 communication between two + * applications. + * + * + * @param connection the connection to the peer + * @param path_name name of the object inside the peer to call methods on + * @param interface_name name of the interface to call methods on + * @returns new proxy object + * + */ +DBusGProxy* +dbus_gproxy_new_for_peer (DBusConnection *connection, + const char *path_name, + const char *interface_name) +{ + DBusGProxy *proxy; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path_name != NULL, NULL); + g_return_val_if_fail (interface_name != NULL, NULL); + + proxy = dbus_gproxy_new (connection, NULL, + path_name, interface_name); + + return proxy; +} + /** * Invokes a method on a remote interface. This function does not * block; instead it returns an opaque #DBusPendingCall object that @@ -952,7 +1173,7 @@ dbus_gproxy_connect_signal (DBusGProxy *proxy, const char *signal_name, DBusGProxySignalHandler handler, void *data, - GFreeFunc free_data_func) + GClosureNotify free_data_func) { GClosure *closure; char *detail; @@ -989,12 +1210,14 @@ dbus_gproxy_disconnect_signal (DBusGProxy *proxy, q = g_quark_try_string (detail); g_free (detail); +#ifndef G_DISABLE_CHECKS if (q == 0) { g_warning ("%s: No signal handlers for %s found on this DBusGProxy", G_GNUC_FUNCTION, signal_name); return; } +#endif g_signal_handlers_disconnect_matched (G_OBJECT (proxy), G_SIGNAL_MATCH_DETAIL | @@ -1018,7 +1241,8 @@ dbus_gproxy_disconnect_signal (DBusGProxy *proxy, dbus_bool_t _dbus_gproxy_test (void) { - + + return TRUE; } -- cgit