rewrote server+client deletion code to (hopefully) be failproof.

I've also set it to abort() with a big error if it gets to the old fallthrough spot, so make sure to send me a backtrace if this is reached (though it should be impossible)


SVN revision: 66068
This commit is contained in:
Mike Blumenkrantz 2011-12-10 05:42:32 +00:00
parent 498904e260
commit 387732c836
1 changed files with 36 additions and 75 deletions

View File

@ -53,7 +53,7 @@
static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl); static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl);
static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl); static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl);
static void _ecore_con_client_kill(Ecore_Con_Client *cl);
static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr); static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr);
static void _ecore_con_server_timer_update(Ecore_Con_Server *svr); static void _ecore_con_server_timer_update(Ecore_Con_Server *svr);
@ -526,8 +526,6 @@ ecore_con_server_timeout_get(Ecore_Con_Server *svr)
EAPI void * EAPI void *
ecore_con_server_del(Ecore_Con_Server *svr) ecore_con_server_del(Ecore_Con_Server *svr)
{ {
void *data;
if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
{ {
ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del"); ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del");
@ -537,20 +535,8 @@ ecore_con_server_del(Ecore_Con_Server *svr)
if (svr->delete_me) if (svr->delete_me)
return NULL; return NULL;
data = svr->data; _ecore_con_server_kill(svr);
svr->delete_me = EINA_TRUE; return svr->data;
if (svr->event_count)
{
if (svr->fd_handler)
{
ecore_main_fd_handler_del(svr->fd_handler);
svr->fd_handler = NULL;
}
}
else
_ecore_con_server_free(svr);
return data;
} }
EAPI void * EAPI void *
@ -829,36 +815,14 @@ ecore_con_client_timeout_get(Ecore_Con_Client *cl)
EAPI void * EAPI void *
ecore_con_client_del(Ecore_Con_Client *cl) ecore_con_client_del(Ecore_Con_Client *cl)
{ {
void *data = NULL;
if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
{ {
ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del");
return NULL; return NULL;
} }
data = cl->data; _ecore_con_client_kill(cl);
cl->delete_me = EINA_TRUE; return cl->data;
if (cl->event_count)
{
if (cl->fd_handler)
{
ecore_main_fd_handler_del(cl->fd_handler);
cl->fd_handler = NULL;
}
}
else
{
if (cl->host_server)
{
cl->host_server->clients = eina_list_remove(cl->host_server->clients, cl);
--cl->host_server->client_count;
}
_ecore_con_client_free(cl);
}
return data;
} }
EAPI void EAPI void
@ -1226,10 +1190,14 @@ _ecore_con_server_free(Ecore_Con_Server *svr)
if ((!svr->buf) && svr->delete_me && (!svr->dead) && (!svr->event_count)) if ((!svr->buf) && svr->delete_me && (!svr->dead) && (!svr->event_count))
{ {
/* this is a catch-all for cases when a server is not properly killed. */ /* this is a catch-all for cases when a server is not properly killed. */
CRIT("THIS SHOULD NOT BE REACHED! PLEASE SEND A FULL BT!");
abort();
/*
svr->dead = EINA_TRUE; svr->dead = EINA_TRUE;
INF("svr %p is dead", svr); INF("svr %p is dead", svr);
ecore_con_event_server_del(svr); ecore_con_event_server_del(svr);
return; return;
*/
} }
t_start = ecore_time_get(); t_start = ecore_time_get();
@ -1295,6 +1263,20 @@ _ecore_con_server_free(Ecore_Con_Server *svr)
free(svr); free(svr);
} }
static void
_ecore_con_client_kill(Ecore_Con_Client *cl)
{
if (!cl->delete_me)
ecore_con_event_client_del(cl);
INF("Lost client %s", (cl->ip) ? cl->ip : "");
cl->dead = EINA_TRUE;
INF("cl %p is dead", cl);
if (cl->fd_handler)
ecore_main_fd_handler_del(cl->fd_handler);
cl->fd_handler = NULL;
}
static void static void
_ecore_con_client_free(Ecore_Con_Client *cl) _ecore_con_client_free(Ecore_Con_Client *cl)
{ {
@ -1305,10 +1287,14 @@ _ecore_con_client_free(Ecore_Con_Client *cl)
if (cl->delete_me && (!cl->dead) && (!cl->event_count)) if (cl->delete_me && (!cl->dead) && (!cl->event_count))
{ {
/* this is a catch-all for cases when a client is not properly killed. */ /* this is a catch-all for cases when a client is not properly killed. */
cl->dead = EINA_TRUE; CRIT("THIS SHOULD NOT BE REACHED! PLEASE SEND A FULL BT!");
INF("cl %p is dead", cl); abort();
ecore_con_event_client_del(cl); /*
return; cl->dead = EINA_TRUE;
INF("cl %p is dead", cl);
ecore_con_event_client_del(cl);
return;
*/
} }
@ -2149,10 +2135,7 @@ _ecore_con_svr_udp_handler(void *data,
ecore_con_event_server_error(svr, strerror(errno)); ecore_con_event_server_error(svr, strerror(errno));
if (!svr->delete_me) if (!svr->delete_me)
ecore_con_event_client_del(NULL); ecore_con_event_client_del(NULL);
_ecore_con_server_kill(svr);
svr->dead = EINA_TRUE;
INF("svr %p is dead", svr);
svr->fd_handler = NULL;
return ECORE_CALLBACK_CANCEL; return ECORE_CALLBACK_CANCEL;
} }
@ -2221,19 +2204,7 @@ _ecore_con_svr_cl_read(Ecore_Con_Client *cl)
if ((!cl->delete_me) && (num > 0)) if ((!cl->delete_me) && (num > 0))
ecore_con_event_client_data(cl, buf, num, EINA_TRUE); ecore_con_event_client_data(cl, buf, num, EINA_TRUE);
if (lost_client) if (lost_client) _ecore_con_client_kill(cl);
{
if (!cl->delete_me)
ecore_con_event_client_del(cl);
INF("Lost client %s", (cl->ip) ? cl->ip : "");
cl->dead = EINA_TRUE;
INF("cl %p is dead", cl);
if (cl->fd_handler)
ecore_main_fd_handler_del(cl->fd_handler);
cl->fd_handler = NULL;
return;
}
} }
static Eina_Bool static Eina_Bool
@ -2254,11 +2225,8 @@ _ecore_con_svr_cl_handler(void *data,
if (ecore_con_ssl_client_init(cl)) if (ecore_con_ssl_client_init(cl))
{ {
ERR("ssl handshaking failed!"); ERR("ssl handshaking failed!");
cl->handshaking = EINA_FALSE; _ecore_con_client_kill(cl);
cl->dead = EINA_TRUE; return ECORE_CALLBACK_RENEW;
INF("cl %p is dead", cl);
INF("Lost client %s", (cl->ip) ? cl->ip : "");
ecore_con_event_client_del(cl);
} }
else if (!cl->ssl_state) else if (!cl->ssl_state)
ecore_con_event_client_add(cl); ecore_con_event_client_add(cl);
@ -2397,14 +2365,7 @@ _ecore_con_client_flush(Ecore_Con_Client *cl)
if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me)) if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me))
{ {
ecore_con_event_client_error(cl, strerror(errno)); ecore_con_event_client_error(cl, strerror(errno));
ecore_con_event_client_del(cl); _ecore_con_client_kill(cl);
cl->dead = EINA_TRUE;
INF("cl %p is dead", 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;
} }
return; return;