summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-08-22 11:00:59 +0100
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-08-22 19:53:03 +0100
commit456419f468e8bba03bc0fcfd9ef2abb2eb61e52e (patch)
treedf844018fb456fc7ddfdca9a83c7895c200a47d0 /src
parentebb685aae1fbf44d9600acc7b5b8be099f4bdea7 (diff)
edje - signal callback matches/patterns try fix number 2
so i think there was also another bug as i saw this again now. this should hopefully plug the signal/mtach memory bugs now by removing and adding back to hash as the hash key relies on the memory addresses of signal/src in the matches array which change on realloc. a bit brute-forceey but... better than crashes. @fix
Diffstat (limited to '')
-rw-r--r--src/lib/edje/edje_signal.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/src/lib/edje/edje_signal.c b/src/lib/edje/edje_signal.c
index 34cca962c4..57de4719bd 100644
--- a/src/lib/edje/edje_signal.c
+++ b/src/lib/edje/edje_signal.c
@@ -68,12 +68,10 @@ _edje_signal_callback_matches_dup(const Edje_Signal_Callback_Matches *src)
68 result = calloc(1, sizeof (Edje_Signal_Callback_Matches)); 68 result = calloc(1, sizeof (Edje_Signal_Callback_Matches));
69 if (!result) return NULL; 69 if (!result) return NULL;
70 70
71 result->hashed = EINA_FALSE;
72 result->matches = malloc 71 result->matches = malloc
73 (sizeof(Edje_Signal_Callback_Match) * src->matches_count); 72 (sizeof(Edje_Signal_Callback_Match) * src->matches_count);
74 if (!result->matches) goto err; 73 if (!result->matches) goto err;
75 result->matches_count = src->matches_count; 74 result->matches_count = src->matches_count;
76 result->patterns = NULL;
77 EINA_REFCOUNT_REF(result); 75 EINA_REFCOUNT_REF(result);
78 76
79 if (src->free_cb) 77 if (src->free_cb)
@@ -107,7 +105,6 @@ _edje_callbacks_patterns_clean(Edje_Signal_Callback_Group *gp)
107 Edje_Signal_Callback_Matches *tmp = (Edje_Signal_Callback_Matches *)gp->matches; 105 Edje_Signal_Callback_Matches *tmp = (Edje_Signal_Callback_Matches *)gp->matches;
108 106
109 if (!tmp) return; 107 if (!tmp) return;
110 assert(EINA_REFCOUNT_GET(tmp) == 1);
111 _edje_signal_callback_patterns_unref(tmp->patterns); 108 _edje_signal_callback_patterns_unref(tmp->patterns);
112 tmp->patterns = NULL; 109 tmp->patterns = NULL;
113} 110}
@@ -220,6 +217,7 @@ _edje_signal_callback_grow(Edje_Signal_Callback_Group *gp)
220 m = realloc(tmp->matches, sizeof(Edje_Signal_Callback_Match) * tmp->matches_count); 217 m = realloc(tmp->matches, sizeof(Edje_Signal_Callback_Match) * tmp->matches_count);
221 if (!m) goto err; 218 if (!m) goto err;
222 tmp->matches = m; 219 tmp->matches = m;
220 memset(&(tmp->matches[tmp->matches_count - 1]), 0, sizeof(Edje_Signal_Callback_Match));
223 if (tmp->free_cb) 221 if (tmp->free_cb)
224 { 222 {
225 f = realloc(tmp->free_cb, sizeof(Eina_Free_Cb) * tmp->matches_count); 223 f = realloc(tmp->free_cb, sizeof(Eina_Free_Cb) * tmp->matches_count);
@@ -230,9 +228,11 @@ _edje_signal_callback_grow(Edje_Signal_Callback_Group *gp)
230 cd = realloc(gp->custom_data, sizeof(void *) * tmp->matches_count); 228 cd = realloc(gp->custom_data, sizeof(void *) * tmp->matches_count);
231 if (!cd) goto err; 229 if (!cd) goto err;
232 gp->custom_data = cd; 230 gp->custom_data = cd;
231 gp->custom_data[tmp->matches_count - 1] = NULL;
233 fl = realloc(gp->flags, sizeof(Edje_Signal_Callback_Flags) * tmp->matches_count); 232 fl = realloc(gp->flags, sizeof(Edje_Signal_Callback_Flags) * tmp->matches_count);
234 if (!fl) goto err; 233 if (!fl) goto err;
235 gp->flags = fl; 234 gp->flags = fl;
235 memset(&(gp->flags[tmp->matches_count - 1]), 0, sizeof(Edje_Signal_Callback_Flags));
236 return gp; 236 return gp;
237err: 237err:
238 ERR("Allocation error in rowing signal callback group"); 238 ERR("Allocation error in rowing signal callback group");
@@ -285,7 +285,6 @@ _edje_signal_callback_push(Edje_Signal_Callback_Group *gp,
285 } 285 }
286 gp->matches = tmp = tmp_dup; 286 gp->matches = tmp = tmp_dup;
287 } 287 }
288 assert(tmp->hashed == EINA_FALSE);
289 } 288 }
290 289
291 // search an empty spot now 290 // search an empty spot now
@@ -300,6 +299,8 @@ _edje_signal_callback_push(Edje_Signal_Callback_Group *gp,
300 } 299 }
301 300
302 m = tmp->matches; 301 m = tmp->matches;
302 if (tmp->hashed)
303 eina_hash_del(signal_match, tmp, tmp);
303 if (_edje_signal_callback_grow(gp)) 304 if (_edje_signal_callback_grow(gp))
304 { 305 {
305 // Set propagate and just_added flags 306 // Set propagate and just_added flags
@@ -310,8 +311,15 @@ _edje_signal_callback_push(Edje_Signal_Callback_Group *gp,
310 _edje_callbacks_patterns_clean(gp); 311 _edje_callbacks_patterns_clean(gp);
311 _edje_callbacks_patterns_init(gp); 312 _edje_callbacks_patterns_init(gp);
312 } 313 }
314 if (tmp->hashed)
315 eina_hash_add(signal_match, tmp, tmp);
316 }
317 else
318 {
319 if (tmp->hashed)
320 eina_hash_add(signal_match, tmp, tmp);
321 goto err;
313 } 322 }
314 else goto err;
315 return EINA_TRUE; 323 return EINA_TRUE;
316err: 324err:
317 ERR("Allocation error in pushing callback"); 325 ERR("Allocation error in pushing callback");
@@ -355,19 +363,22 @@ _edje_signal_callback_matches_unref(Edje_Signal_Callback_Matches *m,
355 363
356 EINA_REFCOUNT_UNREF(m) 364 EINA_REFCOUNT_UNREF(m)
357 { 365 {
358 _edje_signal_callback_patterns_unref(m->patterns);
359 if (m->hashed) 366 if (m->hashed)
360 eina_hash_del(signal_match, m, m); 367 eina_hash_del(signal_match, m, m);
361 for (i = 0; i < m->matches_count; ++i) 368 for (i = 0; i < m->matches_count; ++i)
362 { 369 {
363 eina_stringshare_del(m->matches[i].signal); 370 eina_stringshare_del(m->matches[i].signal);
364 eina_stringshare_del(m->matches[i].source); 371 eina_stringshare_del(m->matches[i].source);
372 m->matches[i].signal = NULL;
373 m->matches[i].source = NULL;
365 } 374 }
375 _edje_signal_callback_patterns_unref(m->patterns);
366 free(m->matches); 376 free(m->matches);
367 free(m->free_cb); 377 free(m->free_cb);
368 m->hashed = EINA_FALSE; 378 m->patterns = NULL;
369 m->matches = NULL; 379 m->matches = NULL;
370 m->free_cb = NULL; 380 m->free_cb = NULL;
381 m->hashed = EINA_FALSE;
371 free(m); 382 free(m);
372 } 383 }
373} 384}
@@ -458,7 +469,7 @@ _edje_signal_callback_patterns_ref(const Edje_Signal_Callback_Group *gp)
458 tmp = (Edje_Signal_Callback_Matches *)gp->matches; 469 tmp = (Edje_Signal_Callback_Matches *)gp->matches;
459 if (!tmp) return NULL; 470 if (!tmp) return NULL;
460 if (tmp->hashed) goto got_it; 471 if (tmp->hashed) goto got_it;
461 m = eina_hash_find(signal_match, gp->matches); 472 m = eina_hash_find(signal_match, tmp);
462 if (!m) 473 if (!m)
463 { 474 {
464 if (!(tmp->patterns && (EINA_REFCOUNT_GET(tmp->patterns) > 1))) 475 if (!(tmp->patterns && (EINA_REFCOUNT_GET(tmp->patterns) > 1)))