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. --- ChangeLog | 12 ++++++ dbus/dbus-bus.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++- dbus/dbus-bus.h | 7 +++ doc/TODO | 3 ++ glib/dbus-glib.h | 25 +++++------ glib/dbus-gproxy.c | 94 ++++++++++++++++++++++++++++++++++++++--- glib/dbus-gproxy.h | 78 ---------------------------------- 7 files changed, 244 insertions(+), 97 deletions(-) delete mode 100644 glib/dbus-gproxy.h diff --git a/ChangeLog b/ChangeLog index 1431a96c..d0c88df3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +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. + 2003-09-21 Havoc Pennington * dbus/dbus-bus.c (dbus_bus_get): set exit_on_disconnect to TRUE diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index 6d7cb82c..a8b9e452 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -681,7 +681,7 @@ dbus_bus_activate_service (DBusConnection *connection, } reply = dbus_connection_send_with_reply_and_block (connection, msg, - -1, error); + -1, error); dbus_message_unref (msg); if (reply == NULL) @@ -710,5 +710,125 @@ dbus_bus_activate_service (DBusConnection *connection, return TRUE; } +static void +send_no_return_values (DBusConnection *connection, + DBusMessage *msg, + DBusError *error) +{ + if (error) + { + /* Block to check success codepath */ + DBusMessage *reply; + + reply = dbus_connection_send_with_reply_and_block (connection, msg, + -1, error); + + if (reply == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + return; + } + + if (dbus_set_error_from_message (error, reply)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + dbus_message_unref (reply); + return; + } + + dbus_message_unref (reply); + } + else + { + /* Silently-fail nonblocking codepath */ + if (!dbus_connection_send (connection, msg, NULL)) + return; + } +} + +/** + * Adds a match rule to match messages going through the message bus. + * The "rule" argument is the string form of a match rule. + * + * If you pass #NULL for the error, this function will not + * block; the match thus won't be added until you flush the + * connection, and if there's an error adding the match + * (only possible error is lack of resources in the bus), + * you won't find out about it. + * + * If you pass non-#NULL for the error this function will + * block until it gets a reply. + * + * Normal API conventions would have the function return + * a boolean value indicating whether the error was set, + * but that would require blocking always to determine + * the return value. + * + * @param connection connection to the message bus + * @param rule textual form of match rule + * @param error location to store any errors + */ +void +dbus_bus_add_match (DBusConnection *connection, + const char *rule, + DBusError *error) +{ + DBusMessage *msg; + + msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, + DBUS_PATH_ORG_FREEDESKTOP_DBUS, + DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, + "AddMatch"); + + if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, rule, + DBUS_TYPE_INVALID)) + { + dbus_message_unref (msg); + _DBUS_SET_OOM (error); + return; + } + + send_no_return_values (connection, msg, error); + + dbus_message_unref (msg); +} + +/** + * Removes a previously-added match rule "by value" (the most + * recently-added identical rule gets removed). The "rule" argument + * is the string form of a match rule. + * + * If you pass #NULL for the error, this function will not + * block; otherwise it will. See detailed explanation in + * docs for dbus_bus_add_match(). + * + * @param connection connection to the message bus + * @param rule textual form of match rule + * @param error location to store any errors + */ +void +dbus_bus_remove_match (DBusConnection *connection, + const char *rule, + DBusError *error) +{ + DBusMessage *msg; + + msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, + DBUS_PATH_ORG_FREEDESKTOP_DBUS, + DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, + "RemoveMatch"); + + if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, rule, + DBUS_TYPE_INVALID)) + { + dbus_message_unref (msg); + _DBUS_SET_OOM (error); + return; + } + + send_no_return_values (connection, msg, error); + + dbus_message_unref (msg); +} /** @} */ diff --git a/dbus/dbus-bus.h b/dbus/dbus-bus.h index a62a746b..072b0c8e 100644 --- a/dbus/dbus-bus.h +++ b/dbus/dbus-bus.h @@ -59,6 +59,13 @@ dbus_bool_t dbus_bus_activate_service (DBusConnection *connection, dbus_uint32_t *reply, DBusError *error); +void dbus_bus_add_match (DBusConnection *connection, + const char *rule, + DBusError *error); +void dbus_bus_remove_match (DBusConnection *connection, + const char *rule, + DBusError *error); + DBUS_END_DECLS; #endif /* DBUS_BUS_H */ diff --git a/doc/TODO b/doc/TODO index 81862331..1935ff9f 100644 --- a/doc/TODO +++ b/doc/TODO @@ -92,3 +92,6 @@ - Header fields names are required to be aligned on a 4 byte boundary at the moment. No alignment should be neccessary. + + - dbus_gproxy or dbus_g_proxy? + diff --git a/glib/dbus-glib.h b/glib/dbus-glib.h index 63d34485..7fd88e71 100644 --- a/glib/dbus-glib.h +++ b/glib/dbus-glib.h @@ -88,18 +88,19 @@ void dbus_connection_register_g_object (DBusConnection *connection, typedef struct DBusGProxy DBusGProxy; -DBusGProxy* dbus_gproxy_new_for_service (DBusConnection *connection, - const char *service_name, - const char *interface_name); -DBusGProxy* dbus_gproxy_new_for_service_owner (DBusConnection *connection, - const char *service_name, - const char *interface_name, - GError **error); -DBusGProxy* dbus_gproxy_new_for_object_path (DBusConnection *connection, - const char *path, - const char *interface_name); -DBusGProxy* dbus_gproxy_new_for_interface (DBusConnection *connection, - const char *interface_name); +DBusGProxy* dbus_gproxy_new_for_service (DBusConnection *connection, + const char *service_name, + const char *path_name, + const char *interface_name); +DBusGProxy* dbus_gproxy_new_for_service_owner (DBusConnection *connection, + const char *service_name, + const char *path_name, + const char *interface_name, + GError **error); +DBusGProxy* dbus_gproxy_new_for_peer (DBusConnection *connection, + const char *path_name, + const char *interface_name); + void dbus_gproxy_ref (DBusGProxy *proxy); void dbus_gproxy_unref (DBusGProxy *proxy); gboolean dbus_gproxy_connect_signal (DBusGProxy *proxy, 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"); } diff --git a/glib/dbus-gproxy.h b/glib/dbus-gproxy.h deleted file mode 100644 index 4e8f3f60..00000000 --- a/glib/dbus-gproxy.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gproxy.h 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 - * - */ -#ifndef DBUS_GPROXY_H -#define DBUS_GPROXY_H - -#if !defined (DBUS_INSIDE_DBUS_GLIB_H) && !defined (DBUS_COMPILATION) -#error "Only can be included directly, this file may disappear or change contents." -#endif - -#include -#include -#include /* for GCallback at the moment, we don't link to it */ - -G_BEGIN_DECLS - -typedef struct DBusGProxy DBusGProxy; - -DBusGProxy* dbus_gproxy_new_for_service (DBusConnection *connection, - const char *service_name, - const char *interface_name); -DBusGProxy* dbus_gproxy_new_for_service_owner (DBusConnection *connection, - const char *service_name, - const char *interface_name, - GError **error); -DBusGProxy* dbus_gproxy_new_for_object_path (DBusConnection *connection, - const char *path, - const char *interface_name); -DBusGProxy* dbus_gproxy_new_for_interface (DBusConnection *connection, - const char *interface_name); -void dbus_gproxy_ref (DBusGProxy *proxy); -void dbus_gproxy_unref (DBusGProxy *proxy); -gboolean dbus_gproxy_connect_signal (DBusGProxy *proxy, - const char *signal_name, - GCallback callback, - void *data, - GFreeFunc free_data_func, - GError **error); -DBusPendingCall* dbus_gproxy_begin_call (DBusGProxy *proxy, - const char *method, - int first_arg_type, - ...); -gboolean dbus_gproxy_end_call (DBusGProxy *proxy, - DBusPendingCall *pending, - GError **error, - int first_arg_type, - ...); -void dbus_gproxy_oneway_call (DBusGProxy *proxy, - const char *method, - int first_arg_type, - ...); -void dbus_gproxy_send (DBusGProxy *proxy, - DBusMessage *message, - dbus_uint32_t *client_serial); - - -G_END_DECLS - -#endif /* DBUS_GPROXY_H */ -- cgit v1.2.1