diff --git a/ChangeLog b/ChangeLog index 0e3b0ac932..49ab13b003 100644 --- 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 ecaa318386..595292b8f6 100644 --- 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 diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c index c7e47bbef3..aaa880e32f 100644 --- a/src/lib/ecore_con/ecore_con.c +++ b/src/lib/ecore_con/ecore_con.c @@ -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);