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.
+
* 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);
/**
}
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
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 { \
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)
{
return ECORE_CALLBACK_RENEW;
}
cl->host_server = svr;
+ cl->ref = 1;
client_addr_len = sizeof(client_addr);
memset(&client_addr, 0, client_addr_len);
_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--;
SSL *ssl;
int ssl_err;
#endif
+ int ref;
Ecore_Con_Ssl_State ssl_state;
Eina_Bool handshaking : 1;
Eina_Bool upgrade : 1; /* STARTTLS queued */
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);
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);