2003-09-21 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Mon, 22 Sep 2003 03:11:12 +0000 (03:11 +0000)
committerHavoc Pennington <hp@redhat.com>
Mon, 22 Sep 2003 03:11:12 +0000 (03:11 +0000)
* 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
dbus/dbus-bus.c
dbus/dbus-bus.h
doc/TODO
glib/dbus-glib.h
glib/dbus-gproxy.c
glib/dbus-gproxy.h [deleted file]

index 1431a96..d0c88df 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2003-09-21  Havoc Pennington  <hp@pobox.com>
 
+       * 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  <hp@pobox.com>
+
        * dbus/dbus-bus.c (dbus_bus_get): set exit_on_disconnect to TRUE
        by default for message bus connections.
 
index 6d7cb82..a8b9e45 100644 (file)
@@ -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);
+}
 
 /** @} */
index a62a746..072b0c8 100644 (file)
@@ -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 */
index 8186233..1935ff9 100644 (file)
--- 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?
+
index 63d3448..7fd88e7 100644 (file)
@@ -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,
index b77e7d3..96a2788 100644 (file)
  */
 
 /**
+ * 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
  */
 struct 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 (file)
index 4e8f3f6..0000000
+++ /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 <dbus/dbus-glib.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#include <dbus/dbus.h>
-#include <glib.h>
-#include <glib-object.h> /* 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 */