From 96ce64ee0797fe9df4246b13520b49e5fe21a40a Mon Sep 17 00:00:00 2001 From: Jan Vidar Krey Date: Fri, 4 Sep 2009 17:18:38 +0200 Subject: [PATCH] Fix memory issues in ADC client lib. --- src/network/connection.c | 22 +++++++++++++--------- src/network/connection.h | 8 ++++++++ src/tools/adcclient.c | 17 +++++++++++++---- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/network/connection.c b/src/network/connection.c index c54bf02..e292d1c 100644 --- a/src/network/connection.c +++ b/src/network/connection.c @@ -80,6 +80,9 @@ void net_con_set(struct net_connection* con) net_con_flag_set(con, NET_INITIALIZED); } +#define CALLBACK(CON, EVENTS) \ + if (CON->callback) \ + CON->callback(con, EVENTS, CON->ptr); static void net_con_event(int fd, short ev, void *arg) { @@ -92,7 +95,7 @@ static void net_con_event(int fd, short ev, void *arg) if (!con->ssl) { #endif - con->callback(con, events, con->ptr); + CALLBACK(con, events); #ifdef SSL_SUPPORT } else @@ -105,29 +108,29 @@ static void net_con_event(int fd, short ev, void *arg) if (net_con_flag_get(con, NET_WANT_SSL_ACCEPT)) { if (net_con_ssl_accept(con) < 0) - con->callback(con, NET_EVENT_SOCKERROR, con->ptr); + CALLBACK(con, NET_EVENT_SOCKERROR); } else if (net_con_flag_get(con, NET_WANT_SSL_CONNECT)) { if (net_con_ssl_connect(con) < 0) - con->callback(con, NET_EVENT_SOCKERROR, con->ptr); + CALLBACK(con, NET_EVENT_SOCKERROR); } else if (ev == EV_READ && net_con_flag_get(con, NET_WANT_SSL_READ)) { - con->callback(con, NET_EVENT_WRITE, con->ptr); + CALLBACK(con, NET_EVENT_WRITE); } else if (ev == EV_WRITE && net_con_flag_get(con, NET_WANT_SSL_WRITE)) { - con->callback(con, events & NET_EVENT_READ, con->ptr); + CALLBACK(con, events & NET_EVENT_READ); } else { - con->callback(con, events, con->ptr); + CALLBACK((con, events); } } else { - con->callback(con, events, con->ptr); + CALLBACK(con, events); } } #endif @@ -135,8 +138,8 @@ static void net_con_event(int fd, short ev, void *arg) if (net_con_flag_get(con, NET_CLEANUP)) { - printf("SHOULD SCHEDULE SHUTTING DOWN SOCKET."); net_con_flag_unset(con, NET_INITIALIZED); + CALLBACK(con, NET_EVENT_DESTROYED); } else { @@ -214,7 +217,8 @@ void net_con_close(struct net_connection* con) if (net_con_flag_get(con, NET_PROCESSING_BUSY)) { - LOG_INFO("Trying to close socket while processing it, will need to post a message about it..."); + LOG_INFO("Trying to close socket while processing it"); + net_con_flag_set(con, NET_CLEANUP); return; } diff --git a/src/network/connection.h b/src/network/connection.h index 6f85270..40b58f0 100644 --- a/src/network/connection.h +++ b/src/network/connection.h @@ -27,6 +27,7 @@ #define NET_EVENT_WRITE 0x0004 #define NET_EVENT_SOCKERROR 0x1000 /* Socket error, closed */ #define NET_EVENT_CLOSED 0x2000 /* Socket closed */ +#define NET_EVENT_DESTROYED 0x4000 /* Struct is invalid and can be cleaned up */ struct net_connection; struct net_timer; @@ -65,6 +66,13 @@ struct net_connection extern void net_con_initialize(struct net_connection* con, int sd, struct ip_addr_encap*, net_connection_cb callback, const void* ptr, int events); extern void net_con_update(struct net_connection* con, int events); + +/** + * Close the connection. + * This will ensure a connection is closed properly and will generate a NET_EVENT_DESTROYED event which indicates + * that the con can safely be deleted (or set to NULL) + * NOTE: Do not dele + */ extern void net_con_close(struct net_connection* con); /** diff --git a/src/tools/adcclient.c b/src/tools/adcclient.c index af6cb38..b3d5977 100644 --- a/src/tools/adcclient.c +++ b/src/tools/adcclient.c @@ -80,8 +80,18 @@ static void timer_callback(struct net_timer* t, void* arg) static void event_callback(struct net_connection* con, int events, void *arg) { struct ADC_client* client = (struct ADC_client*) arg; + + if (events == NET_EVENT_DESTROYED) + { + printf("NET_EVENT_DESTROYED\n"); + hub_free(client->con); + client->con = 0; + return; + } + if (events == NET_EVENT_SOCKERROR || events == NET_EVENT_CLOSED) { + printf("NET_EVENT_SOCKERROR || NET_EVENT_CLOSED\n"); client->callback(client, ADC_CLIENT_DISCONNECTED, 0); return; } @@ -343,12 +353,13 @@ void ADC_client_destroy(struct ADC_client* client) { ADC_client_disconnect(client); net_timer_shutdown(client->timer); + hub_free(client->timer); + adc_msg_free(client->info); hub_free(client->nick); hub_free(client->desc); hub_free(client->hub_address); } - int ADC_client_connect(struct ADC_client* client, const char* address) { if (!client->hub_address) @@ -391,8 +402,6 @@ static void ADC_client_on_connected(struct ADC_client* client) static void ADC_client_on_disconnected(struct ADC_client* client) { net_con_close(client->con); - hub_free(client->con); - client->con = 0; ADC_client_set_state(client, ps_none); } @@ -404,7 +413,7 @@ static void ADC_client_on_login(struct ADC_client* client) void ADC_client_disconnect(struct ADC_client* client) { - if (client->con->sd != -1) + if (client->con && client->con->sd != -1) { net_con_close(client->con); }