eldbus: Welcome two new APIs and one connection type
authorEduardo Lima (Etrunko) <eduardo.lima@intel.com>
Thu, 23 May 2013 20:08:16 +0000 (17:08 -0300)
committerJosé Roberto de Souza <jose.souza@intel.com>
Mon, 5 Aug 2013 16:25:25 +0000 (13:25 -0300)
eldbus_address_connection_get() and eldbus_private_address_connection_get()
are similar to the respective _connection_get() counterparts, but enables
users to connect to buses other than system or session.

The new type introduced for those connections is ELDBUS_CONNECTION_TYPE_ADDRESS
and they require an additional address parameter, which will be passed to
dbus_connection_open().

Signed-off-by: Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
src/lib/eldbus_connection.h
src/lib/eldbus_core.c

index 8fd8136..c8a4832 100644 (file)
@@ -13,6 +13,7 @@ typedef enum
    ELDBUS_CONNECTION_TYPE_SESSION,
    ELDBUS_CONNECTION_TYPE_SYSTEM,
    ELDBUS_CONNECTION_TYPE_STARTER,
+   ELDBUS_CONNECTION_TYPE_ADDRESS,
    ELDBUS_CONNECTION_TYPE_LAST       /**< sentinel, not a real type */
 } Eldbus_Connection_Type;
 
@@ -44,6 +45,29 @@ EAPI Eldbus_Connection *eldbus_connection_get(Eldbus_Connection_Type type);
 EAPI Eldbus_Connection *eldbus_private_connection_get(Eldbus_Connection_Type type);
 
 /**
+ * Establish a connection to bus and integrate it with the ecore main
+ * loop. If a connection of given type was already created before, its
+ * reference counter is incremented and the connection is returned.
+ *
+ * @param address the address which will be passed to dbus_connection_open()
+ *
+ * @return connection with bus
+ */
+EAPI Eldbus_Connection *eldbus_address_connection_get(const char *address) EINA_ARG_NONNULL(1);
+
+/**
+ * Always create and establish a new connection to bus and integrate it with
+ * the ecore main loop. Differently from eldbus_connection_get(), this function
+ * guarantees to create a new connection to the D-Bus daemon and the connection
+ * is not shared by any means.
+ *
+ * @param address the address which will be passed to dbus_connection_open_private()
+ *
+ * @return connection with bus
+ */
+EAPI Eldbus_Connection *eldbus_private_address_connection_get(const char *address) EINA_ARG_NONNULL(1);
+
+/**
  * @brief Increment connection reference count.
  *
  * @param conn The given Eldbus_Connection object to reference
index c663309..25bde7e 100644 (file)
@@ -76,11 +76,13 @@ int _eldbus_log_dom = -1;
 
 /* We don't save ELDBUS_CONNECTION_TYPE_UNKNOWN in here so we need room for 
  * last - 1 elements */
-static Eldbus_Connection *shared_connections[ELDBUS_CONNECTION_TYPE_LAST - 1];
+static void *shared_connections[ELDBUS_CONNECTION_TYPE_LAST - 1];
+static Eina_Hash *address_connections = NULL;
 
 static void _eldbus_connection_event_callback_call(Eldbus_Connection *conn, Eldbus_Connection_Event_Type type, const void *event_info);
 static void _eldbus_connection_context_event_cb_del(Eldbus_Connection_Context_Event *ce, Eldbus_Connection_Context_Event_Cb *ctx);
 static void eldbus_dispatch_name_owner_change(Eldbus_Connection_Name *cn, const char *old_id);
+static void _eldbus_connection_free(Eldbus_Connection *conn);
 
 EAPI int
 eldbus_init(void)
@@ -215,6 +217,17 @@ eldbus_shutdown(void)
         CRITICAL("Alive TYPE_STARTER connection");
         print_live_connection(shared_connections[ELDBUS_CONNECTION_TYPE_STARTER - 1]);
      }
+   if (shared_connections[ELDBUS_CONNECTION_TYPE_ADDRESS - 1])
+     {
+        if (eina_hash_population(address_connections))
+          {
+             CRITICAL("Alive TYPE_ADDRESS connection");
+             print_live_connection(shared_connections[ELDBUS_CONNECTION_TYPE_ADDRESS - 1]);
+          }
+
+        eina_hash_free(address_connections);
+        address_connections = shared_connections[ELDBUS_CONNECTION_TYPE_ADDRESS - 1] = NULL;
+     }
 
    eldbus_service_shutdown();
    eldbus_proxy_shutdown();
@@ -946,8 +959,9 @@ _disconnected(void *data, const Eldbus_Message *msg EINA_UNUSED)
       conn, ELDBUS_CONNECTION_EVENT_DISCONNECTED, NULL);
 }
 
+/* Param address is only used for ELDBUS_CONNECTION_TYPE_ADDRESS type */
 static Eldbus_Connection *
-_connection_get(Eldbus_Connection_Type type)
+_connection_get(Eldbus_Connection_Type type, const char *address)
 {
    Eldbus_Connection *conn;
    DBusError err;
@@ -955,12 +969,18 @@ _connection_get(Eldbus_Connection_Type type)
 
    EINA_SAFETY_ON_FALSE_RETURN_VAL((type < ELDBUS_CONNECTION_TYPE_LAST) &&
                                    (type > ELDBUS_CONNECTION_TYPE_UNKNOWN), NULL);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL((type == ELDBUS_CONNECTION_TYPE_ADDRESS) &&
+                                  (address == NULL), NULL);
 
    conn = calloc(1, sizeof(Eldbus_Connection));
    EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
 
    dbus_error_init(&err);
-   conn->dbus_conn = dbus_bus_get_private(type - 1, &err);
+   if (type == ELDBUS_CONNECTION_TYPE_ADDRESS)
+      conn->dbus_conn = dbus_connection_open_private(address, &err);
+   else
+      conn->dbus_conn = dbus_bus_get_private(type - 1, &err);
+
    if (dbus_error_is_set(&err))
      {
         free(conn);
@@ -986,7 +1006,8 @@ _connection_get(Eldbus_Connection_Type type)
 EAPI Eldbus_Connection *
 eldbus_private_connection_get(Eldbus_Connection_Type type)
 {
-   return _connection_get(type);
+   DBG("Getting private connection with type %d", type);
+   return _connection_get(type, NULL);
 }
 
 EAPI Eldbus_Connection *
@@ -999,7 +1020,13 @@ eldbus_connection_get(Eldbus_Connection_Type type)
    if (!type)
      return NULL;
 
-   conn = shared_connections[type - 1];
+   if (type == ELDBUS_CONNECTION_TYPE_ADDRESS)
+     {
+        ERR("CONNECTION_TYPE_ADDRESS must be used with appropriate address_connection_get() function");
+        return NULL;
+     }
+
+   conn = (Eldbus_Connection *) shared_connections[type - 1];
    if (conn)
      {
         DBG("Connection with type %d exists at %p; reffing and returning",
@@ -1007,7 +1034,7 @@ eldbus_connection_get(Eldbus_Connection_Type type)
         return eldbus_connection_ref(conn);
      }
 
-   conn = _connection_get(type);
+   conn = _connection_get(type, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
    shared_connections[type - 1] = conn;
 
@@ -1015,6 +1042,44 @@ eldbus_connection_get(Eldbus_Connection_Type type)
 }
 
 EAPI Eldbus_Connection *
+eldbus_address_connection_get(const char *address)
+{
+   Eldbus_Connection *conn = NULL;
+
+   DBG("Getting connection with address %s", address);
+
+   if (address_connections == NULL)
+     {
+        address_connections = eina_hash_string_small_new(NULL);
+        shared_connections[ELDBUS_CONNECTION_TYPE_ADDRESS - 1] = address_connections;
+     }
+   else
+     {
+        conn = (Eldbus_Connection *) eina_hash_find(address_connections, address);
+     }
+
+   if (conn != NULL)
+     {
+        DBG("Connection with address %s exists at %p; reffing and returning",
+            address, conn);
+        return eldbus_connection_ref(conn);
+     }
+
+   conn = _connection_get(ELDBUS_CONNECTION_TYPE_ADDRESS, address);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL);
+   eina_hash_add(address_connections, address, conn);
+
+   return conn;
+}
+
+EAPI Eldbus_Connection *
+eldbus_private_address_connection_get(const char *address)
+{
+   DBG("Getting private connection with address %s", address);
+   return _connection_get(ELDBUS_CONNECTION_TYPE_ADDRESS, address);
+}
+
+EAPI Eldbus_Connection *
 eldbus_connection_ref(Eldbus_Connection *conn)
 {
    ELDBUS_CONNECTION_CHECK_RETVAL(conn, NULL);
@@ -1127,8 +1192,13 @@ _eldbus_connection_free(Eldbus_Connection *conn)
    eldbus_data_del_all(&conn->data);
 
    if (conn->idler) ecore_idler_del(conn->idler);
-   if (conn->type && (shared_connections[conn->type - 1] == conn))
-     shared_connections[conn->type - 1] = NULL;
+   if (conn->type)
+     {
+        if (conn->type == ELDBUS_CONNECTION_TYPE_ADDRESS)
+           eina_hash_del_by_data(address_connections, conn);
+        else if (shared_connections[conn->type - 1] == (void *) conn)
+           shared_connections[conn->type - 1] = NULL;
+     }
 
    free(conn);
 }