and no more segv's in ecore-con and ecore-ipc. see changelog.

SVN revision: 71400
This commit is contained in:
Carsten Haitzler 2012-05-24 07:49:30 +00:00
parent 51c2d442f5
commit dcf4d1401e
5 changed files with 71 additions and 11 deletions

View File

@ -662,3 +662,13 @@
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.

View 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);
/**

View 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,11 +871,34 @@ 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--;

View 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 */

View 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);