e_dbus: better error and reference handling.
authorbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 11 Oct 2008 07:11:42 +0000 (07:11 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 11 Oct 2008 07:11:42 +0000 (07:11 +0000)
This patch does a refactor of e_dbus_methods and e_dbus_interfaces so
these methods return a pending call that can be canceled. It will also
print out possible errors and will unref the message after usage.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/e_dbus@36579 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/dbus/E_DBus.h
src/lib/dbus/e_dbus_interfaces.c
src/lib/dbus/e_dbus_message.c
src/lib/dbus/e_dbus_methods.c

index e08246f..631a057 100644 (file)
@@ -104,48 +104,48 @@ extern "C" {
 
 /* standard dbus method calls */
 
-   EAPI void e_dbus_request_name(E_DBus_Connection *conn, const char *name, 
-                                 unsigned int flags,
-                                 E_DBus_Method_Return_Cb cb_return,
-                                 void *data);
-   EAPI void e_dbus_release_name(E_DBus_Connection *conn, const char *name,
-                                 E_DBus_Method_Return_Cb cb_return,
-                                 void *data);
-
-   EAPI void e_dbus_get_name_owner(E_DBus_Connection *conn, const char *name,
-                                   E_DBus_Method_Return_Cb cb_return,
-                                   void *data);
-   EAPI void e_dbus_list_names(E_DBus_Connection *conn,
-                               E_DBus_Method_Return_Cb cb_return,
-                               void *data);
-   EAPI void e_dbus_list_activatable_names(E_DBus_Connection *conn,
-                                           E_DBus_Method_Return_Cb cb_return,
-                                           void *data);
-   EAPI void e_dbus_name_has_owner(E_DBus_Connection *conn, const char *name,
-                                   E_DBus_Method_Return_Cb cb_return,
-                                   void *data);
-   EAPI void e_dbus_start_service_by_name(E_DBus_Connection *conn, const char *name,
-                                          E_DBus_Method_Return_Cb cb_return,
-                                          void *data);
+   EAPI DBusPendingCall *e_dbus_request_name(E_DBus_Connection *conn, const char *name,
+                                            unsigned int flags,
+                                            E_DBus_Method_Return_Cb cb_return,
+                                            const void *data);
+   EAPI DBusPendingCall *e_dbus_release_name(E_DBus_Connection *conn, const char *name,
+                                            E_DBus_Method_Return_Cb cb_return,
+                                            const void *data);
+
+   EAPI DBusPendingCall *e_dbus_get_name_owner(E_DBus_Connection *conn, const char *name,
+                                              E_DBus_Method_Return_Cb cb_return,
+                                              const void *data);
+   EAPI DBusPendingCall *e_dbus_list_names(E_DBus_Connection *conn,
+                                          E_DBus_Method_Return_Cb cb_return,
+                                          const void *data);
+   EAPI DBusPendingCall *e_dbus_list_activatable_names(E_DBus_Connection *conn,
+                                                      E_DBus_Method_Return_Cb cb_return,
+                                                      const void *data);
+   EAPI DBusPendingCall *e_dbus_name_has_owner(E_DBus_Connection *conn, const char *name,
+                                              E_DBus_Method_Return_Cb cb_return,
+                                              const void *data);
+   EAPI DBusPendingCall *e_dbus_start_service_by_name(E_DBus_Connection *conn, const char *name,
+                                                     E_DBus_Method_Return_Cb cb_return,
+                                                     const void *data);
 
 /* standard methods calls on objects */
-   EAPI void e_dbus_peer_ping(E_DBus_Connection *conn, const char *destination,
-                              const char *path, E_DBus_Method_Return_Cb cb_return,
-                              void *data);
-   EAPI void e_dbus_peer_get_machine_id(E_DBus_Connection *conn,
-                                        const char *destination, const char *path,
-                                        E_DBus_Method_Return_Cb cb_return,
-                                        void *data);
-   EAPI void e_dbus_properties_get(E_DBus_Connection *conn, const char *destination,
-                                   const char *path, const char *interface,
-                                   const char *property,
-                                   E_DBus_Method_Return_Cb cb_return,
-                                   void *data);
-   EAPI void e_dbus_properties_set(E_DBus_Connection *conn, const char *destination,
-                                   const char *path, const char *interface,
-                                   const char *property, int value_type,
-                                   void *value, E_DBus_Method_Return_Cb cb_return,
-                                   void *data);
+   EAPI DBusPendingCall *e_dbus_peer_ping(E_DBus_Connection *conn, const char *destination,
+                                         const char *path, E_DBus_Method_Return_Cb cb_return,
+                                         const void *data);
+   EAPI DBusPendingCall *e_dbus_peer_get_machine_id(E_DBus_Connection *conn,
+                                                   const char *destination, const char *path,
+                                                   E_DBus_Method_Return_Cb cb_return,
+                                                   const void *data);
+   EAPI DBusPendingCall *e_dbus_properties_get(E_DBus_Connection *conn, const char *destination,
+                                              const char *path, const char *interface,
+                                              const char *property,
+                                              E_DBus_Method_Return_Cb cb_return,
+                                              const void *data);
+   EAPI DBusPendingCall *e_dbus_properties_set(E_DBus_Connection *conn, const char *destination,
+                                              const char *path, const char *interface,
+                                              const char *property, int value_type,
+                                              const void *value, E_DBus_Method_Return_Cb cb_return,
+                                              const void *data);
 
 
    EAPI E_DBus_Callback *e_dbus_callback_new(E_DBus_Callback_Func cb_func, E_DBus_Unmarshal_Func unmarshal_func, E_DBus_Free_Func free_func, void *user_data);
index 772543b..df0dffa 100644 (file)
@@ -6,6 +6,33 @@
  * objects on the bus should implement.
  */
 
+static inline DBusPendingCall *
+_dbus_peer_call(E_DBus_Connection *conn, const char *method_name, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, const void *data)
+{
+  DBusMessage *msg;
+  DBusPendingCall *ret;
+
+  msg = dbus_message_new_method_call
+    (destination, path, "org.freedesktop.DBus.Peer", method_name);
+  if (!msg)
+    {
+       fprintf(stderr,
+              "ERROR: failed to create message for method call: %s() at "
+              "\"%s\" at \"%s\"\n",
+              method_name, destination, path);
+       return NULL;
+    }
+
+  ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data);
+  dbus_message_unref(msg);
+
+  if (!ret)
+    fprintf(stderr, "ERROR: could not %s() \"%s\" at \"%s\".\n",
+           method_name, destination, path);
+
+  return ret;
+}
+
 /**
  * Ping the dbus peer
  *
  * @param cb_return a callback for a successful return
  * @param data data to pass to the callbacks
  */
-EAPI void
-e_dbus_peer_ping(E_DBus_Connection*conn, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, void *data)
+EAPI DBusPendingCall *
+e_dbus_peer_ping(E_DBus_Connection *conn, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
-  DBusMessage *msg;
-
-  msg = dbus_message_new_method_call(destination, path, "org.freedesktop.DBus.Peer", "Ping");
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+   return _dbus_peer_call(conn, "Ping", destination, path, cb_return, data);
 }
 
 /**
@@ -33,13 +57,37 @@ e_dbus_peer_ping(E_DBus_Connection*conn, const char *destination, const char *pa
  * @param cb_return a callback for a successful return
  * @param data data to pass to the callbacks
  */
-EAPI void
-e_dbus_peer_get_machine_id(E_DBus_Connection*conn, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, void *data)
+EAPI DBusPendingCall *
+e_dbus_peer_get_machine_id(E_DBus_Connection*conn, const char *destination, const char *path, E_DBus_Method_Return_Cb cb_return, const void *data)
+{
+   return _dbus_peer_call(conn, "GetMachineId", destination, path, cb_return, data);
+}
+
+static inline DBusMessage *
+_dbus_message_property_method_call(E_DBus_Connection *conn, const char *method_name, const char *destination, const char *path, const char *interface, const char *property)
 {
   DBusMessage *msg;
 
-  msg = dbus_message_new_method_call(destination, path, "org.freedesktop.DBus.Peer", "GetMachineId");
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+  if (!conn)
+    {
+       fprintf(stderr, "ERROR: no connection for call of %s\n", method_name);
+       return NULL;
+    }
+
+  msg = dbus_message_new_method_call
+    (destination, path, "org.freedesktop.DBus.Properties", method_name);
+  if (!msg)
+    {
+       fprintf(stderr,
+              "ERROR: failed to create message for method call: %s() at "
+              "\"%s\" at \"%s\"\n",
+              method_name, destination, path);
+       return NULL;
+    }
+
+  dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface,
+                          DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID);
+  return msg;
 }
 
 /**
@@ -53,14 +101,24 @@ e_dbus_peer_get_machine_id(E_DBus_Connection*conn, const char *destination, cons
  * @param cb_return a callback for a successful return
  * @param data data to pass to the callbacks
  */
-EAPI void
-e_dbus_properties_get(E_DBus_Connection*conn, const char *destination, const char *path, const char *interface, const char *property, E_DBus_Method_Return_Cb cb_return, void *data)
+EAPI DBusPendingCall *
+e_dbus_properties_get(E_DBus_Connection*conn, const char *destination, const char *path, const char *interface, const char *property, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
   DBusMessage *msg;
+  DBusPendingCall *ret;
+
+  msg = _dbus_message_property_method_call
+    (conn, "Get", destination, path, interface, property);
+  if (!msg)
+    return NULL;
+  ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data);
+  dbus_message_unref(msg);
 
-  msg = dbus_message_new_method_call(destination, path, "org.freedesktop.DBus.Properties", "Get");
-  dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID);
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+  if (!ret)
+    fprintf(stderr, "ERROR: failed to call Get() at \"%s\" at \"%s\"\n",
+           destination, path);
+
+  return ret;
 }
 
 /**
@@ -76,32 +134,42 @@ e_dbus_properties_get(E_DBus_Connection*conn, const char *destination, const cha
  * @param cb_return a callback for a successful return
  * @param data data to pass to the callbacks
  */
-EAPI void
-e_dbus_properties_set(E_DBus_Connection*conn, const char *destination, const char *path, const char *interface, const char *property, int value_type, void *value, E_DBus_Method_Return_Cb cb_return, void *data)
+EAPI DBusPendingCall *
+e_dbus_properties_set(E_DBus_Connection*conn, const char *destination, const char *path, const char *interface, const char *property, int value_type, const void *value, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
   DBusMessage *msg;
   DBusMessageIter iter, sub;
   DBusError err;
+  DBusPendingCall *ret;
 
-  if (!dbus_type_is_basic(value_type)) 
+  if (!dbus_type_is_basic(value_type))
   {
     if (cb_return)
     {
       dbus_error_init(&err);
       dbus_set_error(&err, "org.enlightenment.DBus.InvalidType", "Only basic types may be set using e_dbus_properties_set()");
-      cb_return(data, NULL, &err);
+      cb_return((void *)data, NULL, &err);
 
     }
-    return;
+    return NULL;
   }
 
-  msg = dbus_message_new_method_call(destination, path, "org.freedesktop.DBus.Properties", "Set");
-  dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID);
+  msg = _dbus_message_property_method_call
+    (conn, "Set", destination, path, interface, property);
+  if (!msg)
+    return NULL;
 
   dbus_message_iter_init_append(msg, &iter);
   dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, dbus_message_type_to_string(value_type), &sub);
   dbus_message_iter_append_basic(&sub, value_type, &value);
   dbus_message_iter_close_container(&iter, &sub);
 
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+  ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data);
+  dbus_message_unref(msg);
+
+  if (!ret)
+    fprintf(stderr, "ERROR: failed to call Set() at \"%s\" at \"%s\"\n",
+           destination, path);
+
+  return ret;
 }
index 68bfc47..b77aa9f 100644 (file)
@@ -5,8 +5,6 @@
 typedef struct E_DBus_Pending_Call_Data E_DBus_Pending_Call_Data;
 struct E_DBus_Pending_Call_Data
 {
-  int                     serial;
-
   E_DBus_Method_Return_Cb cb_return;
   void                   *data;
 };
@@ -70,15 +68,16 @@ e_dbus_message_send(E_DBus_Connection *conn, DBusMessage *msg, E_DBus_Method_Ret
   if (!dbus_connection_send_with_reply(conn->conn, msg, &pending, timeout))
     return NULL;
 
-  if (cb_return)
+  if (cb_return && pending)
   {
     E_DBus_Pending_Call_Data *pdata;
 
-    pdata = calloc(1, sizeof(E_DBus_Pending_Call_Data));
+    pdata = malloc(sizeof(E_DBus_Pending_Call_Data));
     pdata->cb_return = cb_return;
     pdata->data = data;
 
-    dbus_pending_call_set_notify(pending, cb_pending, pdata, free);
+    if (!dbus_pending_call_set_notify(pending, cb_pending, pdata, free))
+      free(pdata);
   }
 
   return pending;
index 1b3b71f..a3f70e2 100644 (file)
 #include "E_DBus.h"
 #include "e_dbus_private.h"
 
-EAPI void
-e_dbus_request_name(E_DBus_Connection *conn, const char *name, unsigned int flags, E_DBus_Method_Return_Cb cb_return, void *data)
+static inline DBusMessage *
+_dbus_message_method_call(const char *method_name)
+{
+   DBusMessage *msg;
+
+   msg = dbus_message_new_method_call
+     ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
+      method_name);
+   if (!msg)
+     fprintf(stderr, "ERROR: failed to create message for method call: %s\n",
+            method_name);
+   return msg;
+}
+
+static inline DBusPendingCall *
+_dbus_call__void(E_DBus_Connection *conn, const const char *method_name, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
   DBusMessage *msg;
-  dbus_uint32_t u_flags;
+  DBusPendingCall *ret;
+
+  if (!conn)
+    {
+       fprintf(stderr, "ERROR: no connection for call of %s\n", method_name);
+       return NULL;
+    }
+
+  msg = _dbus_message_method_call(method_name);
+  if (!msg)
+    return NULL;
+  ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data);
+  dbus_message_unref(msg);
 
-  u_flags = flags;
+  if (!ret)
+    fprintf(stderr, "ERROR: failed to call %s()\n", method_name);
 
-  msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RequestName");
-  dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &u_flags, DBUS_TYPE_INVALID);
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+  return ret;
 }
 
-EAPI void
-e_dbus_release_name(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, void *data)
+static inline DBusPendingCall *
+_dbus_call__str(E_DBus_Connection *conn, const const char *method_name, const char *str, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
   DBusMessage *msg;
+  DBusPendingCall *ret;
 
-  msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ReleaseName");
-  dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
-}
+  if (!conn)
+    {
+       fprintf(stderr, "ERROR: no connection for call of %s\n", method_name);
+       return NULL;
+    }
 
+  msg = _dbus_message_method_call(method_name);
+  if (!msg)
+    return NULL;
+  dbus_message_append_args(msg, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID);
+  ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data);
+  dbus_message_unref(msg);
 
-EAPI void
-e_dbus_get_name_owner(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, void *data)
-{
-  DBusMessage *msg;
+  if (!ret)
+    fprintf(stderr, "ERROR: failed to call %s(\"%s\")\n", method_name, str);
 
-  msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetNameOwner");
-  dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+  return ret;
 }
 
-EAPI void
-e_dbus_list_names(E_DBus_Connection *conn, E_DBus_Method_Return_Cb cb_return, void *data)
+EAPI DBusPendingCall *
+e_dbus_request_name(E_DBus_Connection *conn, const char *name, unsigned int flags, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
-  DBusMessage *msg;
+   DBusPendingCall *ret;
+   DBusMessage *msg;
+   dbus_uint32_t u_flags;
+
+  if (!conn)
+    {
+       fputs("ERROR: no connection for call of RequestName\n", stderr);
+       return NULL;
+    }
+
+   u_flags = flags;
+
+   msg = _dbus_message_method_call("RequestName");
+   if (!msg)
+     return NULL;
+   dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &u_flags, DBUS_TYPE_INVALID);
+   ret = e_dbus_message_send(conn, msg, cb_return, -1, (void *)data);
+   dbus_message_unref(msg);
+   return ret;
+}
 
-  msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+EAPI DBusPendingCall *
+e_dbus_release_name(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, const void *data)
+{
+   return _dbus_call__str(conn, "ReleaseName", name, cb_return, data);
 }
 
 
-EAPI void
-e_dbus_list_activatable_names(E_DBus_Connection *conn, E_DBus_Method_Return_Cb cb_return, void *data)
+EAPI DBusPendingCall *
+e_dbus_get_name_owner(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
-  DBusMessage *msg;
+   return _dbus_call__str(conn, "GetNameOwner", name, cb_return, data);
+}
 
-  msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListActivatableNames");
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+EAPI DBusPendingCall *
+e_dbus_list_names(E_DBus_Connection *conn, E_DBus_Method_Return_Cb cb_return, const void *data)
+{
+   return _dbus_call__void(conn, "ListNames", cb_return, data);
 }
 
-EAPI void
-e_dbus_name_has_owner(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, void *data)
+
+EAPI DBusPendingCall *
+e_dbus_list_activatable_names(E_DBus_Connection *conn, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
-  DBusMessage *msg;
+   return _dbus_call__void(conn, "ListActivatableNames", cb_return, data);
+}
 
-  msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameHasOwner");
-  dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+EAPI DBusPendingCall *
+e_dbus_name_has_owner(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, const void *data)
+{
+   return _dbus_call__str(conn, "NameHasOwner", name, cb_return, data);
 }
 
 
-EAPI void
-e_dbus_start_service_by_name(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, void *data)
+EAPI DBusPendingCall *
+e_dbus_start_service_by_name(E_DBus_Connection *conn, const char *name, E_DBus_Method_Return_Cb cb_return, const void *data)
 {
-  DBusMessage *msg;
-
-  msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "StartServiceByName");
-  dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
-  e_dbus_message_send(conn, msg, cb_return, -1, data);
+   return _dbus_call__str(conn, "StartServiceByName", name, cb_return, data);
 }