and no more segv's in ecore-con and ecore-ipc. see changelog.
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 24 May 2012 07:49:30 +0000 (07:49 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 24 May 2012 07:49:30 +0000 (07:49 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@71400 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
src/lib/ecore_con/Ecore_Con.h
src/lib/ecore_con/ecore_con.c
src/lib/ecore_con/ecore_con_private.h
src/lib/ecore_ipc/ecore_ipc.c

index 6be42be..e997a78 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 2012-05-24 Doyoun Kang
 
         * Add Ecore_X_Error_Code enumeration in ecore_x
+
+2012-05-24 Carsten Haitzler (The Rasterman)
+
+        * Add ecore_con_client_ref() and ecore_con_client_unref()
+        * Fix ecore_con to obey reference counting for con clients
+        * Fix lurking bug in ecore_ipc that had it be able to crash in
+        accessind already deleted ecore-con clients. use client
+        ref/unref to fix it. No backport of this fix as it requires a
+        new feature.
+
index 9784adf..7fe8495 100644 (file)
@@ -1240,7 +1240,27 @@ EAPI Eina_Bool         ecore_con_client_connected_get(Ecore_Con_Client *cl);
  * Use this function to return the port on which a given client has connected.
  */
 EAPI int               ecore_con_client_port_get(Ecore_Con_Client *cl);
-
+/**
+ * @brief increment the references on a connection client
+ *
+ * @param cl The client
+ * This increases the references on the given client to keep it alive in
+ * memory for longer until all references are release by
+ * ecore_con_client_unref().
+ * @since 1.3
+ */
+EAPI void              ecore_con_client_ref(Ecore_Con_Client *cl);
+/**
+ * @brief decrement the references on a connection client
+ *
+ * @param cl The client
+ * This decrements the references on the given client and once references hit
+ * 0, the client is deleted. ecore_con_client_del() does the same thing as
+ * ecore_con_client_unref(). All con clients start with a reference count of
+ * 1.
+ * @since 1.3
+ */
+EAPI void              ecore_con_client_unref(Ecore_Con_Client *cl);
 
 
 /**
index 33f8342..5ba6624 100644 (file)
@@ -116,9 +116,12 @@ _ecore_con_client_kill(Ecore_Con_Client *cl)
      }
    INF("Lost client %s", (cl->ip) ? cl->ip : "");
    if (cl->fd_handler)
-     ecore_main_fd_handler_del(cl->fd_handler);
-
-   cl->fd_handler = NULL;
+     {
+        ecore_main_fd_handler_del(cl->fd_handler);
+        cl->fd_handler = NULL;
+     }
+   if (cl->ref <= 0)
+     _ecore_con_client_free(cl);
 }
 
 void
@@ -130,9 +133,10 @@ _ecore_con_server_kill(Ecore_Con_Server *svr)
      ecore_con_event_server_del(svr);
 
    if (svr->fd_handler)
-     ecore_main_fd_handler_del(svr->fd_handler);
-
-   svr->fd_handler = NULL;
+     {
+        ecore_main_fd_handler_del(svr->fd_handler);
+        svr->fd_handler = NULL;
+     }
 }
 
 #define _ecore_con_server_kill(svr) do { \
@@ -867,12 +871,35 @@ ecore_con_client_del(Ecore_Con_Client *cl)
         ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del");
         return NULL;
      }
-
-   _ecore_con_client_kill(cl);
+   ecore_con_client_unref(cl);
    return cl->data;
 }
 
 EAPI void
+ecore_con_client_ref(Ecore_Con_Client *cl)
+{
+   if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+     {
+        ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_ref");
+        return;
+     }
+   cl->ref++;
+}
+
+EAPI void
+ecore_con_client_unref(Ecore_Con_Client *cl)
+{
+   if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+     {
+        ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_unref");
+        return;
+     }
+   cl->ref--;
+   if (cl->ref <= 0)
+     _ecore_con_client_kill(cl);
+}
+
+EAPI void
 ecore_con_client_data_set(Ecore_Con_Client *cl,
                           const void       *data)
 {
@@ -1834,6 +1861,7 @@ _ecore_con_svr_tcp_handler(void                        *data,
         return ECORE_CALLBACK_RENEW;
      }
    cl->host_server = svr;
+   cl->ref = 1;
 
    client_addr_len = sizeof(client_addr);
    memset(&client_addr, 0, client_addr_len);
@@ -2383,7 +2411,7 @@ _ecore_con_event_client_del_free(Ecore_Con_Server *svr,
                _ecore_con_server_free(svr);
           }
         if (!e->client->event_count)
-          _ecore_con_client_free(e->client);
+          ecore_con_client_del(e->client);
      }
    ecore_con_event_client_del_free(e);
    _ecore_con_event_count--;
index 4f8f792..e3b9adb 100644 (file)
@@ -119,6 +119,7 @@ struct _Ecore_Con_Client
    SSL *ssl;
    int ssl_err;
 #endif
+   int ref;
    Ecore_Con_Ssl_State ssl_state;
    Eina_Bool handshaking : 1;
    Eina_Bool upgrade : 1; /* STARTTLS queued */
index 3518be2..54ee3ad 100644 (file)
@@ -881,7 +881,7 @@ ecore_ipc_client_del(Ecore_Ipc_Client *cl)
    if (cl->event_count == 0)
      {
         svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client));
-        ecore_con_client_del(cl->client);
+        ecore_con_client_unref(cl->client);
         svr->clients = eina_list_remove(svr->clients, cl);
         if (cl->buf) free(cl->buf);
         ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
@@ -1034,6 +1034,7 @@ _ecore_ipc_event_client_add(void *data __UNUSED__, int ev_type __UNUSED__, void
         svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client));
         ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT);
         cl->client = e->client;
+        ecore_con_client_ref(cl->client);
         cl->max_buf_size = 32 * 1024;
         ecore_con_client_data_set(cl->client, (void *)cl);
         svr->clients = eina_list_append(svr->clients, cl);