summaryrefslogtreecommitdiff
path: root/src/lib/ethumb_client
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-08-26 12:08:15 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-08-26 12:08:53 +0900
commit072c140201a3000aadd279f33f7529a0da332337 (patch)
treea43e3b0899c33242516cb18354b474b33f115b11 /src/lib/ethumb_client
parent42fb96459295e8825ac1ac68f0d657023ca62dce (diff)
try and fix up valgrind+segv issues with ethumb and freed data access
Diffstat (limited to 'src/lib/ethumb_client')
-rw-r--r--src/lib/ethumb_client/ethumb_client.c125
1 files changed, 91 insertions, 34 deletions
diff --git a/src/lib/ethumb_client/ethumb_client.c b/src/lib/ethumb_client/ethumb_client.c
index e306dfb9cd..b21ddf4faa 100644
--- a/src/lib/ethumb_client/ethumb_client.c
+++ b/src/lib/ethumb_client/ethumb_client.c
@@ -117,9 +117,11 @@ struct _Ethumb_Client
117 Eina_Free_Cb free_data; 117 Eina_Free_Cb free_data;
118 } die; 118 } die;
119 Eldbus_Proxy *proxy; 119 Eldbus_Proxy *proxy;
120 Eldbus_Signal_Handler *generated_sig_handler;
120 EINA_REFCOUNT; 121 EINA_REFCOUNT;
121 Eina_Bool connected : 1; 122 Eina_Bool connected : 1;
122 Eina_Bool server_started : 1; 123 Eina_Bool server_started : 1;
124 Eina_Bool invalid : 1;
123}; 125};
124 126
125struct _ethumb_pending_add 127struct _ethumb_pending_add
@@ -132,7 +134,7 @@ struct _ethumb_pending_add
132 Ethumb_Client_Generate_Cb generated_cb; 134 Ethumb_Client_Generate_Cb generated_cb;
133 void *data; 135 void *data;
134 Eina_Free_Cb free_data; 136 Eina_Free_Cb free_data;
135 Eldbus_Pending *pending_call; 137 Eldbus_Pending *pending_call;
136 Ethumb_Client *client; 138 Ethumb_Client *client;
137}; 139};
138 140
@@ -142,6 +144,7 @@ struct _ethumb_pending_remove
142 Ethumb_Client_Generate_Cancel_Cb cancel_cb; 144 Ethumb_Client_Generate_Cancel_Cb cancel_cb;
143 void *data; 145 void *data;
144 Eina_Free_Cb free_data; 146 Eina_Free_Cb free_data;
147 Eldbus_Pending *pending_call;
145 Ethumb_Client *client; 148 Ethumb_Client *client;
146}; 149};
147 150
@@ -197,13 +200,16 @@ _ethumb_client_free(Ethumb_Client *client)
197 void *data; 200 void *data;
198 Eldbus_Object *obj; 201 Eldbus_Object *obj;
199 202
200 if (!client->connected) 203 if (client->invalid) return;
201 goto end_connection; 204 client->invalid = EINA_TRUE;
202
203 EINA_LIST_FREE(client->pending_add, data) 205 EINA_LIST_FREE(client->pending_add, data)
204 { 206 {
205 struct _ethumb_pending_add *pending = data; 207 struct _ethumb_pending_add *pending = data;
206 eldbus_pending_cancel(pending->pending_call); 208 pending->client = NULL;
209 if (pending->pending_call)
210 eldbus_pending_cancel(pending->pending_call);
211 else
212 free(pending);
207 } 213 }
208 214
209 EINA_LIST_FREE(client->pending_gen, data) 215 EINA_LIST_FREE(client->pending_gen, data)
@@ -223,22 +229,47 @@ _ethumb_client_free(Ethumb_Client *client)
223 struct _ethumb_pending_remove *pending = data; 229 struct _ethumb_pending_remove *pending = data;
224 if (pending->free_data) 230 if (pending->free_data)
225 pending->free_data(pending->data); 231 pending->free_data(pending->data);
226 free(pending); 232 pending->client = NULL;
233 if (pending->pending_call)
234 eldbus_pending_cancel(pending->pending_call);
235 else
236 free(pending);
227 } 237 }
228 238
229end_connection:
230 if (client->old_ethumb_conf) 239 if (client->old_ethumb_conf)
231 ethumb_free(client->old_ethumb_conf); 240 {
241 ethumb_free(client->old_ethumb_conf);
242 client->old_ethumb_conf = NULL;
243 }
232 244
233 ethumb_free(client->ethumb); 245 if (client->ethumb)
246 {
247 ethumb_free(client->ethumb);
248 client->ethumb = NULL;
249 }
234 250
235 eldbus_name_owner_changed_callback_del(client->conn, _ethumb_dbus_bus_name, 251 if (client->conn)
236 _ethumb_client_name_owner_changed, 252 eldbus_name_owner_changed_callback_del(client->conn,
237 client); 253 _ethumb_dbus_bus_name,
238 obj = eldbus_proxy_object_get(client->proxy); 254 _ethumb_client_name_owner_changed,
239 eldbus_proxy_unref(client->proxy); 255 client);
240 eldbus_object_unref(obj); 256 if (client->generated_sig_handler)
241 if (client->conn) eldbus_connection_unref(client->conn); 257 {
258 eldbus_signal_handler_del(client->generated_sig_handler);
259 client->generated_sig_handler = NULL;
260 }
261 if (client->proxy)
262 {
263 obj = eldbus_proxy_object_get(client->proxy);
264 eldbus_proxy_unref(client->proxy);
265 client->proxy = NULL;
266 if (obj) eldbus_object_unref(obj);
267 }
268 if (client->conn)
269 {
270 eldbus_connection_unref(client->conn);
271 client->conn = NULL;
272 }
242 273
243 if (client->connect.free_data) 274 if (client->connect.free_data)
244 client->connect.free_data(client->connect.data); 275 client->connect.free_data(client->connect.data);
@@ -266,6 +297,7 @@ static void
266_ethumb_client_name_owner_changed(void *context, const char *bus EINA_UNUSED, const char *old_id, const char *new_id) 297_ethumb_client_name_owner_changed(void *context, const char *bus EINA_UNUSED, const char *old_id, const char *new_id)
267{ 298{
268 Ethumb_Client *client = context; 299 Ethumb_Client *client = context;
300
269 DBG("NameOwnerChanged from=[%s] to=[%s]", old_id, new_id); 301 DBG("NameOwnerChanged from=[%s] to=[%s]", old_id, new_id);
270 if (new_id[0]) 302 if (new_id[0])
271 { 303 {
@@ -278,6 +310,7 @@ _ethumb_client_name_owner_changed(void *context, const char *bus EINA_UNUSED, co
278 return; 310 return;
279 } 311 }
280 INF("Server disconnected"); 312 INF("Server disconnected");
313 EINA_REFCOUNT_REF(client);
281 client->connected = EINA_FALSE; 314 client->connected = EINA_FALSE;
282 if (client->die.cb) 315 if (client->die.cb)
283 { 316 {
@@ -290,6 +323,7 @@ _ethumb_client_name_owner_changed(void *context, const char *bus EINA_UNUSED, co
290 client->die.free_data = NULL; 323 client->die.free_data = NULL;
291 client->die.data = NULL; 324 client->die.data = NULL;
292 } 325 }
326 EINA_REFCOUNT_UNREF(client) _ethumb_client_free(client);
293} 327}
294 328
295static void 329static void
@@ -297,10 +331,11 @@ _ethumb_client_report_connect(Ethumb_Client *client, Eina_Bool success)
297{ 331{
298 if (!client->connect.cb) 332 if (!client->connect.cb)
299 { 333 {
300 ERR("already called?!"); 334 //ERR("already called?!");
301 return; 335 return;
302 } 336 }
303 337
338 EINA_REFCOUNT_REF(client);
304 if (success) 339 if (success)
305 INF("Success connecting to Ethumb server."); 340 INF("Success connecting to Ethumb server.");
306 else 341 else
@@ -314,6 +349,7 @@ _ethumb_client_report_connect(Ethumb_Client *client, Eina_Bool success)
314 } 349 }
315 client->connect.cb = NULL; 350 client->connect.cb = NULL;
316 client->connect.data = NULL; 351 client->connect.data = NULL;
352 EINA_REFCOUNT_UNREF(client) _ethumb_client_free(client);
317} 353}
318 354
319static void 355static void
@@ -338,10 +374,19 @@ _ethumb_client_new_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pen
338 return; 374 return;
339 } 375 }
340 376
341 obj = eldbus_object_get(client->conn, _ethumb_dbus_bus_name, opath); 377 if (client->generated_sig_handler)
342 client->proxy = eldbus_proxy_get(obj, _ethumb_dbus_objects_interface); 378 {
343 eldbus_proxy_signal_handler_add(client->proxy, "generated", 379 eldbus_signal_handler_del(client->generated_sig_handler);
344 _ethumb_client_generated_cb, client); 380 client->generated_sig_handler = NULL;
381 }
382 if (!client->proxy)
383 {
384 obj = eldbus_object_get(client->conn, _ethumb_dbus_bus_name, opath);
385 client->proxy = eldbus_proxy_get(obj, _ethumb_dbus_objects_interface);
386 }
387 client->generated_sig_handler =
388 eldbus_proxy_signal_handler_add(client->proxy, "generated",
389 _ethumb_client_generated_cb, client);
345 _ethumb_client_report_connect(client, 1); 390 _ethumb_client_report_connect(client, 1);
346} 391}
347 392
@@ -382,8 +427,7 @@ _ethumb_client_exists_end(void *data, Ecore_Thread *thread EINA_UNUSED)
382 ethumb_exists(cb->client->ethumb)); 427 ethumb_exists(cb->client->ethumb));
383 428
384 cb->client->ethumb = tmp; 429 cb->client->ethumb = tmp;
385 EINA_REFCOUNT_UNREF(cb->client) 430 EINA_REFCOUNT_UNREF(cb->client) _ethumb_client_free(cb->client);
386 _ethumb_client_free(cb->client);
387 ethumb_free(cb->dup); 431 ethumb_free(cb->dup);
388 free(cb); 432 free(cb);
389 } 433 }
@@ -580,8 +624,7 @@ ethumb_client_disconnect(Ethumb_Client *client)
580{ 624{
581 EINA_SAFETY_ON_NULL_RETURN(client); 625 EINA_SAFETY_ON_NULL_RETURN(client);
582 626
583 EINA_REFCOUNT_UNREF(client) 627 EINA_REFCOUNT_UNREF(client) _ethumb_client_free(client);
584 _ethumb_client_free(client);
585} 628}
586 629
587/** 630/**
@@ -838,6 +881,7 @@ _ethumb_client_generated_cb(void *data, const Eldbus_Message *msg)
838 struct _ethumb_pending_gen *pending; 881 struct _ethumb_pending_gen *pending;
839 Eina_List *l; 882 Eina_List *l;
840 883
884 if (!client) return;
841 if (!eldbus_message_arguments_get(msg, "iayayb", &id, &thumb_iter, 885 if (!eldbus_message_arguments_get(msg, "iayayb", &id, &thumb_iter,
842 &thumb_key_iter, &success)) 886 &thumb_key_iter, &success))
843 { 887 {
@@ -890,6 +934,8 @@ _ethumb_client_queue_add_cb(void *data, const Eldbus_Message *msg, Eldbus_Pendin
890 struct _ethumb_pending_gen *generating; 934 struct _ethumb_pending_gen *generating;
891 Ethumb_Client *client = pending->client; 935 Ethumb_Client *client = pending->client;
892 936
937 pending->pending_call = NULL;
938 if (!client) goto end;
893 client->pending_add = eina_list_remove(client->pending_add, pending); 939 client->pending_add = eina_list_remove(client->pending_add, pending);
894 940
895 if (eldbus_message_error_get(msg, &errname, &errmsg)) 941 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
957 _ethumb_client_dbus_append_bytearray(main_itr, thumb_key); 1003 _ethumb_client_dbus_append_bytearray(main_itr, thumb_key);
958 1004
959 pending->pending_call = eldbus_proxy_send(client->proxy, msg, 1005 pending->pending_call = eldbus_proxy_send(client->proxy, msg,
960 _ethumb_client_queue_add_cb, 1006 _ethumb_client_queue_add_cb,
961 pending, -1); 1007 pending, -1);
962 client->pending_add = eina_list_append(client->pending_add, pending); 1008 client->pending_add = eina_list_append(client->pending_add, pending);
963 1009
964 return pending->id; 1010 return pending->id;
@@ -972,6 +1018,8 @@ _ethumb_client_queue_remove_cb(void *data, const Eldbus_Message *msg, Eldbus_Pen
972 Ethumb_Client *client = pending->client; 1018 Ethumb_Client *client = pending->client;
973 const char *errname, *errmsg; 1019 const char *errname, *errmsg;
974 1020
1021 pending->pending_call = NULL;
1022 if (!client) goto end;
975 client->pending_remove = eina_list_remove(client->pending_remove, pending); 1023 client->pending_remove = eina_list_remove(client->pending_remove, pending);
976 1024
977 if (eldbus_message_error_get(msg, &errname, &errmsg)) 1025 if (eldbus_message_error_get(msg, &errname, &errmsg))
@@ -1030,8 +1078,10 @@ ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Gener
1030 pending->free_data = free_data; 1078 pending->free_data = free_data;
1031 pending->client = client; 1079 pending->client = client;
1032 1080
1033 eldbus_proxy_call(client->proxy, "queue_remove", 1081 pending->pending_call =
1034 _ethumb_client_queue_remove_cb, pending, -1, "i", pending->id); 1082 eldbus_proxy_call(client->proxy, "queue_remove",
1083 _ethumb_client_queue_remove_cb, pending, -1,
1084 "i", pending->id);
1035 client->pending_remove = eina_list_append(client->pending_remove, pending); 1085 client->pending_remove = eina_list_append(client->pending_remove, pending);
1036 1086
1037 /* 1087 /*
@@ -1050,6 +1100,7 @@ ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Gener
1050 continue; 1100 continue;
1051 } 1101 }
1052 eldbus_pending_cancel(pending_add->pending_call); 1102 eldbus_pending_cancel(pending_add->pending_call);
1103 pending_add->pending_call = NULL;
1053 found = 1; 1104 found = 1;
1054 break; 1105 break;
1055 } 1106 }
@@ -1096,7 +1147,11 @@ ethumb_client_generate_cancel_all(Ethumb_Client *client)
1096 EINA_LIST_FREE(client->pending_add, data) 1147 EINA_LIST_FREE(client->pending_add, data)
1097 { 1148 {
1098 struct _ethumb_pending_add *pending = data; 1149 struct _ethumb_pending_add *pending = data;
1099 eldbus_pending_cancel(pending->pending_call); 1150 if (pending->pending_call)
1151 eldbus_pending_cancel(pending->pending_call);
1152 pending->pending_call = NULL;
1153 pending->client = NULL;
1154 free(pending);
1100 } 1155 }
1101 1156
1102 EINA_LIST_FREE(client->pending_gen, data) 1157 EINA_LIST_FREE(client->pending_gen, data)
@@ -1938,8 +1993,7 @@ ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists)
1938 ecore_thread_cancel(async->thread); 1993 ecore_thread_cancel(async->thread);
1939 1994
1940 ethumb_free(exists->dup); 1995 ethumb_free(exists->dup);
1941 EINA_REFCOUNT_UNREF(exists->client) 1996 EINA_REFCOUNT_UNREF(exists->client) _ethumb_client_free(exists->client);
1942 _ethumb_client_free(exists->client);
1943 free(exists); 1997 free(exists);
1944} 1998}
1945 1999
@@ -2044,10 +2098,13 @@ static Eina_List *idle_tasks[2] = { NULL, NULL };
2044static void 2098static void
2045_ethumb_client_async_free(Ethumb_Client_Async *async) 2099_ethumb_client_async_free(Ethumb_Client_Async *async)
2046{ 2100{
2047 EINA_REFCOUNT_UNREF(async->client) 2101 Ethumb_Client *client = async->client;
2048 _ethumb_client_free(async->client);
2049 ethumb_free(async->dup); 2102 ethumb_free(async->dup);
2050 free(async); 2103 free(async);
2104 if (client)
2105 {
2106 EINA_REFCOUNT_UNREF(client) _ethumb_client_free(client);
2107 }
2051} 2108}
2052 2109
2053static void 2110static void