fix ecore-con client double-free case
authorCarsten Haitzler <raster@rasterman.com>
Thu, 3 Jan 2013 06:56:42 +0000 (06:56 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Thu, 3 Jan 2013 06:56:42 +0000 (06:56 +0000)
SVN revision: 82042

ChangeLog
NEWS
src/lib/ecore_con/ecore_con.c

index 0e3b0ac..49ab13b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-01-03  Carsten Haitzler (The Rasterman)
+
+        * Fixed ecore_con case where freeing server double-frees clients
+
 2013-01-03  Jérémy Zurcher
 
        * Add eio_eet_sync symbols.
diff --git a/NEWS b/NEWS
index ecaa318..595292b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -98,3 +98,4 @@ Fixes:
     * eio functions no longer crash when passed NULL and throw errors accordingly
     * Fix eina_xattr_value_ls() and eina_xattr_value_fd_ls()
     * Fix mask write lines to not choose too small segments
+    * Fix ecore_con case where freeing server double-frees clients
index c7e47bb..aaa880e 100644 (file)
@@ -2364,15 +2364,23 @@ _ecore_con_event_client_add_free(Ecore_Con_Server *svr,
    e = ev;
    if (e->client)
      {
+        Eina_Bool svrfreed = EINA_FALSE;
+        
         e->client->event_count = eina_list_remove(e->client->event_count, e);
         if (e->client->host_server)
           {
              e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev);
              if ((!svr->event_count) && (svr->delete_me))
-               _ecore_con_server_free(svr);
+               {
+                  _ecore_con_server_free(svr);
+                  svrfreed = EINA_TRUE;
+               }
+          }
+        if (!svrfreed)
+          {
+             if ((!e->client->event_count) && (e->client->delete_me))
+               ecore_con_client_del(e->client);
           }
-        if ((!e->client->event_count) && (e->client->delete_me))
-          ecore_con_client_del(e->client);
      }
 
    ecore_con_event_client_add_free(e);
@@ -2390,15 +2398,23 @@ _ecore_con_event_client_del_free(Ecore_Con_Server *svr,
    e = ev;
    if (e->client)
      {
+        Eina_Bool svrfreed = EINA_FALSE;
+        
         e->client->event_count = eina_list_remove(e->client->event_count, e);
         if (e->client->host_server)
           {
              e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev);
              if ((!svr->event_count) && (svr->delete_me))
-               _ecore_con_server_free(svr);
+               {
+                  _ecore_con_server_free(svr);
+                  svrfreed = EINA_TRUE;
+               }
+          }
+        if (!svrfreed)
+          {
+             if (!e->client->event_count)
+               _ecore_con_client_free(e->client);
           }
-        if (!e->client->event_count)
-          _ecore_con_client_free(e->client);
      }
    ecore_con_event_client_del_free(e);
    _ecore_con_event_count--;
@@ -2412,18 +2428,26 @@ _ecore_con_event_client_write_free(Ecore_Con_Server *svr,
 {
    if (e->client)
      {
+        Eina_Bool svrfreed = EINA_FALSE;
+        
         e->client->event_count = eina_list_remove(e->client->event_count, e);
         if (e->client->host_server)
           {
              e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e);
              if ((!svr->event_count) && (svr->delete_me))
-               _ecore_con_server_free(svr);
+               {
+                  _ecore_con_server_free(svr);
+                  svrfreed = EINA_TRUE;
+               }
+          }
+        if (!svrfreed)
+          {
+             if (((!e->client->event_count) && (e->client->delete_me)) ||
+                 ((e->client->host_server &&
+                   ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
+                       (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
+               ecore_con_client_del(e->client);
           }
-        if (((!e->client->event_count) && (e->client->delete_me)) ||
-            ((e->client->host_server &&
-              ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
-               (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
-          ecore_con_client_del(e->client);
      }
    ecore_con_event_client_write_free(e);
    _ecore_con_event_count--;
@@ -2440,18 +2464,26 @@ _ecore_con_event_client_data_free(Ecore_Con_Server *svr,
    e = ev;
    if (e->client)
      {
+        Eina_Bool svrfreed = EINA_FALSE;
+        
         e->client->event_count = eina_list_remove(e->client->event_count, e);
         if (e->client->host_server)
           {
              e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev);
           }
         if ((!svr->event_count) && (svr->delete_me))
-          _ecore_con_server_free(svr);
-        if (((!e->client->event_count) && (e->client->delete_me)) ||
-            ((e->client->host_server &&
-              ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
-               (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
-          ecore_con_client_del(e->client);
+          {
+             _ecore_con_server_free(svr);
+             svrfreed = EINA_TRUE;
+          }
+        if (!svrfreed)
+          {
+             if (((!e->client->event_count) && (e->client->delete_me)) ||
+                 ((e->client->host_server &&
+                   ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP ||
+                       (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST))))
+               ecore_con_client_del(e->client);
+          }
      }
    free(e->data);
    ecore_con_event_client_data_free(e);
@@ -2558,15 +2590,23 @@ _ecore_con_event_client_error_free(Ecore_Con_Server *svr, Ecore_Con_Event_Client
 {
    if (e->client)
      {
+        Eina_Bool svrfreed = EINA_FALSE;
+        
         if (eina_list_data_find(svr->clients, e->client))
           {
              e->client->event_count = eina_list_remove(e->client->event_count, e);
              if ((!e->client->event_count) && (e->client->delete_me))
-               _ecore_con_client_free(e->client);
+               {
+                  _ecore_con_client_free(e->client);
+                  svrfreed = EINA_TRUE;
+               }
           }
         svr->event_count = eina_list_remove(svr->event_count, e);
-        if ((!svr->event_count) && (svr->delete_me))
-          _ecore_con_server_free(svr);
+        if (!svrfreed)
+          {
+             if ((!svr->event_count) && (svr->delete_me))
+               _ecore_con_server_free(svr);
+          }
      }
    free(e->error);
    ecore_con_event_client_error_free(e);