try and fix up valgrind+segv issues with ethumb and freed data access

This commit is contained in:
Carsten Haitzler 2013-08-26 12:08:15 +09:00
parent 42fb964592
commit 072c140201
1 changed files with 91 additions and 34 deletions

View File

@ -117,9 +117,11 @@ struct _Ethumb_Client
Eina_Free_Cb free_data; Eina_Free_Cb free_data;
} die; } die;
Eldbus_Proxy *proxy; Eldbus_Proxy *proxy;
Eldbus_Signal_Handler *generated_sig_handler;
EINA_REFCOUNT; EINA_REFCOUNT;
Eina_Bool connected : 1; Eina_Bool connected : 1;
Eina_Bool server_started : 1; Eina_Bool server_started : 1;
Eina_Bool invalid : 1;
}; };
struct _ethumb_pending_add struct _ethumb_pending_add
@ -132,7 +134,7 @@ struct _ethumb_pending_add
Ethumb_Client_Generate_Cb generated_cb; Ethumb_Client_Generate_Cb generated_cb;
void *data; void *data;
Eina_Free_Cb free_data; Eina_Free_Cb free_data;
Eldbus_Pending *pending_call; Eldbus_Pending *pending_call;
Ethumb_Client *client; Ethumb_Client *client;
}; };
@ -142,6 +144,7 @@ struct _ethumb_pending_remove
Ethumb_Client_Generate_Cancel_Cb cancel_cb; Ethumb_Client_Generate_Cancel_Cb cancel_cb;
void *data; void *data;
Eina_Free_Cb free_data; Eina_Free_Cb free_data;
Eldbus_Pending *pending_call;
Ethumb_Client *client; Ethumb_Client *client;
}; };
@ -197,13 +200,16 @@ _ethumb_client_free(Ethumb_Client *client)
void *data; void *data;
Eldbus_Object *obj; Eldbus_Object *obj;
if (!client->connected) if (client->invalid) return;
goto end_connection; client->invalid = EINA_TRUE;
EINA_LIST_FREE(client->pending_add, data) EINA_LIST_FREE(client->pending_add, data)
{ {
struct _ethumb_pending_add *pending = data; struct _ethumb_pending_add *pending = data;
eldbus_pending_cancel(pending->pending_call); pending->client = NULL;
if (pending->pending_call)
eldbus_pending_cancel(pending->pending_call);
else
free(pending);
} }
EINA_LIST_FREE(client->pending_gen, data) EINA_LIST_FREE(client->pending_gen, data)
@ -223,22 +229,47 @@ _ethumb_client_free(Ethumb_Client *client)
struct _ethumb_pending_remove *pending = data; struct _ethumb_pending_remove *pending = data;
if (pending->free_data) if (pending->free_data)
pending->free_data(pending->data); pending->free_data(pending->data);
free(pending); pending->client = NULL;
if (pending->pending_call)
eldbus_pending_cancel(pending->pending_call);
else
free(pending);
} }
end_connection:
if (client->old_ethumb_conf) if (client->old_ethumb_conf)
ethumb_free(client->old_ethumb_conf); {
ethumb_free(client->old_ethumb_conf);
client->old_ethumb_conf = NULL;
}
ethumb_free(client->ethumb); if (client->ethumb)
{
ethumb_free(client->ethumb);
client->ethumb = NULL;
}
eldbus_name_owner_changed_callback_del(client->conn, _ethumb_dbus_bus_name, if (client->conn)
_ethumb_client_name_owner_changed, eldbus_name_owner_changed_callback_del(client->conn,
client); _ethumb_dbus_bus_name,
obj = eldbus_proxy_object_get(client->proxy); _ethumb_client_name_owner_changed,
eldbus_proxy_unref(client->proxy); client);
eldbus_object_unref(obj); if (client->generated_sig_handler)
if (client->conn) eldbus_connection_unref(client->conn); {
eldbus_signal_handler_del(client->generated_sig_handler);
client->generated_sig_handler = NULL;
}
if (client->proxy)
{
obj = eldbus_proxy_object_get(client->proxy);
eldbus_proxy_unref(client->proxy);
client->proxy = NULL;
if (obj) eldbus_object_unref(obj);
}
if (client->conn)
{
eldbus_connection_unref(client->conn);
client->conn = NULL;
}
if (client->connect.free_data) if (client->connect.free_data)
client->connect.free_data(client->connect.data); client->connect.free_data(client->connect.data);
@ -266,6 +297,7 @@ static void
_ethumb_client_name_owner_changed(void *context, const char *bus EINA_UNUSED, const char *old_id, const char *new_id) _ethumb_client_name_owner_changed(void *context, const char *bus EINA_UNUSED, const char *old_id, const char *new_id)
{ {
Ethumb_Client *client = context; Ethumb_Client *client = context;
DBG("NameOwnerChanged from=[%s] to=[%s]", old_id, new_id); DBG("NameOwnerChanged from=[%s] to=[%s]", old_id, new_id);
if (new_id[0]) if (new_id[0])
{ {
@ -278,6 +310,7 @@ _ethumb_client_name_owner_changed(void *context, const char *bus EINA_UNUSED, co
return; return;
} }
INF("Server disconnected"); INF("Server disconnected");
EINA_REFCOUNT_REF(client);
client->connected = EINA_FALSE; client->connected = EINA_FALSE;
if (client->die.cb) if (client->die.cb)
{ {
@ -290,6 +323,7 @@ _ethumb_client_name_owner_changed(void *context, const char *bus EINA_UNUSED, co
client->die.free_data = NULL; client->die.free_data = NULL;
client->die.data = NULL; client->die.data = NULL;
} }
EINA_REFCOUNT_UNREF(client) _ethumb_client_free(client);
} }
static void static void
@ -297,10 +331,11 @@ _ethumb_client_report_connect(Ethumb_Client *client, Eina_Bool success)
{ {
if (!client->connect.cb) if (!client->connect.cb)
{ {
ERR("already called?!"); //ERR("already called?!");
return; return;
} }
EINA_REFCOUNT_REF(client);
if (success) if (success)
INF("Success connecting to Ethumb server."); INF("Success connecting to Ethumb server.");
else else
@ -314,6 +349,7 @@ _ethumb_client_report_connect(Ethumb_Client *client, Eina_Bool success)
} }
client->connect.cb = NULL; client->connect.cb = NULL;
client->connect.data = NULL; client->connect.data = NULL;
EINA_REFCOUNT_UNREF(client) _ethumb_client_free(client);
} }
static void static void
@ -338,10 +374,19 @@ _ethumb_client_new_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pen
return; return;
} }
obj = eldbus_object_get(client->conn, _ethumb_dbus_bus_name, opath); if (client->generated_sig_handler)
client->proxy = eldbus_proxy_get(obj, _ethumb_dbus_objects_interface); {
eldbus_proxy_signal_handler_add(client->proxy, "generated", eldbus_signal_handler_del(client->generated_sig_handler);
_ethumb_client_generated_cb, client); client->generated_sig_handler = NULL;
}
if (!client->proxy)
{
obj = eldbus_object_get(client->conn, _ethumb_dbus_bus_name, opath);
client->proxy = eldbus_proxy_get(obj, _ethumb_dbus_objects_interface);
}
client->generated_sig_handler =
eldbus_proxy_signal_handler_add(client->proxy, "generated",
_ethumb_client_generated_cb, client);
_ethumb_client_report_connect(client, 1); _ethumb_client_report_connect(client, 1);
} }
@ -382,8 +427,7 @@ _ethumb_client_exists_end(void *data, Ecore_Thread *thread EINA_UNUSED)
ethumb_exists(cb->client->ethumb)); ethumb_exists(cb->client->ethumb));
cb->client->ethumb = tmp; cb->client->ethumb = tmp;
EINA_REFCOUNT_UNREF(cb->client) EINA_REFCOUNT_UNREF(cb->client) _ethumb_client_free(cb->client);
_ethumb_client_free(cb->client);
ethumb_free(cb->dup); ethumb_free(cb->dup);
free(cb); free(cb);
} }
@ -580,8 +624,7 @@ ethumb_client_disconnect(Ethumb_Client *client)
{ {
EINA_SAFETY_ON_NULL_RETURN(client); EINA_SAFETY_ON_NULL_RETURN(client);
EINA_REFCOUNT_UNREF(client) EINA_REFCOUNT_UNREF(client) _ethumb_client_free(client);
_ethumb_client_free(client);
} }
/** /**
@ -838,6 +881,7 @@ _ethumb_client_generated_cb(void *data, const Eldbus_Message *msg)
struct _ethumb_pending_gen *pending; struct _ethumb_pending_gen *pending;
Eina_List *l; Eina_List *l;
if (!client) return;
if (!eldbus_message_arguments_get(msg, "iayayb", &id, &thumb_iter, if (!eldbus_message_arguments_get(msg, "iayayb", &id, &thumb_iter,
&thumb_key_iter, &success)) &thumb_key_iter, &success))
{ {
@ -890,6 +934,8 @@ _ethumb_client_queue_add_cb(void *data, const Eldbus_Message *msg, Eldbus_Pendin
struct _ethumb_pending_gen *generating; struct _ethumb_pending_gen *generating;
Ethumb_Client *client = pending->client; Ethumb_Client *client = pending->client;
pending->pending_call = NULL;
if (!client) goto end;
client->pending_add = eina_list_remove(client->pending_add, pending); client->pending_add = eina_list_remove(client->pending_add, pending);
if (eldbus_message_error_get(msg, &errname, &errmsg)) if (eldbus_message_error_get(msg, &errname, &errmsg))
@ -957,8 +1003,8 @@ _ethumb_client_queue_add(Ethumb_Client *client, const char *file, const char *ke
_ethumb_client_dbus_append_bytearray(main_itr, thumb_key); _ethumb_client_dbus_append_bytearray(main_itr, thumb_key);
pending->pending_call = eldbus_proxy_send(client->proxy, msg, pending->pending_call = eldbus_proxy_send(client->proxy, msg,
_ethumb_client_queue_add_cb, _ethumb_client_queue_add_cb,
pending, -1); pending, -1);
client->pending_add = eina_list_append(client->pending_add, pending); client->pending_add = eina_list_append(client->pending_add, pending);
return pending->id; return pending->id;
@ -972,6 +1018,8 @@ _ethumb_client_queue_remove_cb(void *data, const Eldbus_Message *msg, Eldbus_Pen
Ethumb_Client *client = pending->client; Ethumb_Client *client = pending->client;
const char *errname, *errmsg; const char *errname, *errmsg;
pending->pending_call = NULL;
if (!client) goto end;
client->pending_remove = eina_list_remove(client->pending_remove, pending); client->pending_remove = eina_list_remove(client->pending_remove, pending);
if (eldbus_message_error_get(msg, &errname, &errmsg)) if (eldbus_message_error_get(msg, &errname, &errmsg))
@ -1030,8 +1078,10 @@ ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Gener
pending->free_data = free_data; pending->free_data = free_data;
pending->client = client; pending->client = client;
eldbus_proxy_call(client->proxy, "queue_remove", pending->pending_call =
_ethumb_client_queue_remove_cb, pending, -1, "i", pending->id); eldbus_proxy_call(client->proxy, "queue_remove",
_ethumb_client_queue_remove_cb, pending, -1,
"i", pending->id);
client->pending_remove = eina_list_append(client->pending_remove, pending); client->pending_remove = eina_list_append(client->pending_remove, pending);
/* /*
@ -1050,6 +1100,7 @@ ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Gener
continue; continue;
} }
eldbus_pending_cancel(pending_add->pending_call); eldbus_pending_cancel(pending_add->pending_call);
pending_add->pending_call = NULL;
found = 1; found = 1;
break; break;
} }
@ -1096,7 +1147,11 @@ ethumb_client_generate_cancel_all(Ethumb_Client *client)
EINA_LIST_FREE(client->pending_add, data) EINA_LIST_FREE(client->pending_add, data)
{ {
struct _ethumb_pending_add *pending = data; struct _ethumb_pending_add *pending = data;
eldbus_pending_cancel(pending->pending_call); if (pending->pending_call)
eldbus_pending_cancel(pending->pending_call);
pending->pending_call = NULL;
pending->client = NULL;
free(pending);
} }
EINA_LIST_FREE(client->pending_gen, data) EINA_LIST_FREE(client->pending_gen, data)
@ -1938,8 +1993,7 @@ ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists)
ecore_thread_cancel(async->thread); ecore_thread_cancel(async->thread);
ethumb_free(exists->dup); ethumb_free(exists->dup);
EINA_REFCOUNT_UNREF(exists->client) EINA_REFCOUNT_UNREF(exists->client) _ethumb_client_free(exists->client);
_ethumb_client_free(exists->client);
free(exists); free(exists);
} }
@ -2044,10 +2098,13 @@ static Eina_List *idle_tasks[2] = { NULL, NULL };
static void static void
_ethumb_client_async_free(Ethumb_Client_Async *async) _ethumb_client_async_free(Ethumb_Client_Async *async)
{ {
EINA_REFCOUNT_UNREF(async->client) Ethumb_Client *client = async->client;
_ethumb_client_free(async->client);
ethumb_free(async->dup); ethumb_free(async->dup);
free(async); free(async);
if (client)
{
EINA_REFCOUNT_UNREF(client) _ethumb_client_free(client);
}
} }
static void static void