summaryrefslogtreecommitdiff
path: root/src/lib/edje
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-08-05 13:10:33 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-08-05 13:10:33 +0900
commit7b59a4851e23bb9b5b523bd50030182e1b765faa (patch)
tree4c0a68a6ab6dea5e2f030dca5757d4325a26c464 /src/lib/edje
parentfb153fc57a03b1e0235ee73cc179080994542559 (diff)
edje crash with run program references - fix
i found a crash today where a heme could cause a crash if it just did the right things. the run program was freed while still being accessed. so add some ref counting to keep it alive until references go to 0. and add soem refs while we store it in lists. @fix
Diffstat (limited to 'src/lib/edje')
-rw-r--r--src/lib/edje/edje_callbacks.c26
-rw-r--r--src/lib/edje/edje_private.h1
-rw-r--r--src/lib/edje/edje_program.c41
3 files changed, 56 insertions, 12 deletions
diff --git a/src/lib/edje/edje_callbacks.c b/src/lib/edje/edje_callbacks.c
index ac6f52c9eb..06ed0f81a7 100644
--- a/src/lib/edje/edje_callbacks.c
+++ b/src/lib/edje/edje_callbacks.c
@@ -387,35 +387,51 @@ _edje_timer_cb(void *data, const Efl_Event *event EINA_UNUSED)
387 _edje_util_freeze(ed); 387 _edje_util_freeze(ed);
388 if ((!ed->paused) && (!ed->delete_me)) 388 if ((!ed->paused) && (!ed->delete_me))
389 { 389 {
390 const void *tmp; 390 Edje_Running_Program *tmp;
391 391
392 ed->walking_actions = EINA_TRUE; 392 ed->walking_actions = EINA_TRUE;
393 EINA_LIST_FOREACH(ed->actions, l, tmp) 393 EINA_LIST_FOREACH(ed->actions, l, tmp)
394 newl = eina_list_append(newl, tmp); 394 {
395 tmp->ref++;
396 newl = eina_list_append(newl, tmp);
397 }
395 while (newl) 398 while (newl)
396 { 399 {
397 Edje_Running_Program *runp; 400 Edje_Running_Program *runp;
398 401
399 runp = eina_list_data_get(newl); 402 runp = eina_list_data_get(newl);
400 newl = eina_list_remove(newl, eina_list_data_get(newl)); 403 newl = eina_list_remove(newl, eina_list_data_get(newl));
404 runp->ref--;
401 if (!runp->delete_me) 405 if (!runp->delete_me)
402 _edje_program_run_iterate(runp, t); 406 _edje_program_run_iterate(runp, t);
403 if (_edje_block_break(ed)) 407 if (_edje_block_break(ed))
404 { 408 {
405 eina_list_free(newl); 409 EINA_LIST_FREE(newl, tmp)
410 {
411 tmp->ref--;
412 if ((tmp->delete_me) && (tmp->ref == 0))
413 {
414 _edje_program_run_cleanup(ed, tmp);
415 free(tmp);
416 }
417 }
406 newl = NULL; 418 newl = NULL;
407 goto break_prog; 419 goto break_prog;
408 } 420 }
409 } 421 }
410 EINA_LIST_FOREACH(ed->actions, l, tmp) 422 EINA_LIST_FOREACH(ed->actions, l, tmp)
411 newl = eina_list_append(newl, tmp); 423 {
424 tmp->ref++;
425 newl = eina_list_append(newl, tmp);
426 }
412 while (newl) 427 while (newl)
413 { 428 {
414 Edje_Running_Program *runp; 429 Edje_Running_Program *runp;
415 430
416 runp = eina_list_data_get(newl); 431 runp = eina_list_data_get(newl);
417 newl = eina_list_remove(newl, eina_list_data_get(newl)); 432 newl = eina_list_remove(newl, eina_list_data_get(newl));
418 if (runp->delete_me) 433 runp->ref--;
434 if ((runp->delete_me) && (runp->ref == 0))
419 { 435 {
420 _edje_program_run_cleanup(ed, runp); 436 _edje_program_run_cleanup(ed, runp);
421 free(runp); 437 free(runp);
diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h
index 139272066e..a4a334ccc0 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -2059,6 +2059,7 @@ struct _Edje_Running_Program
2059 Edje *edje; 2059 Edje *edje;
2060 Edje_Program *program; 2060 Edje_Program *program;
2061 double start_time; 2061 double start_time;
2062 unsigned short ref;
2062 Eina_Bool delete_me : 1; 2063 Eina_Bool delete_me : 1;
2063}; 2064};
2064 2065
diff --git a/src/lib/edje/edje_program.c b/src/lib/edje/edje_program.c
index 6c90f46650..4dd5fb7816 100644
--- a/src/lib/edje/edje_program.c
+++ b/src/lib/edje/edje_program.c
@@ -299,20 +299,32 @@ _edje_object_animation_set(Eo *obj, Edje *ed, Eina_Bool on)
299 if (!on) 299 if (!on)
300 { 300 {
301 Eina_List *newl = NULL; 301 Eina_List *newl = NULL;
302 const void *data; 302 Edje_Running_Program *data;
303 303
304 EINA_LIST_FOREACH(ed->actions, l, data) 304 EINA_LIST_FOREACH(ed->actions, l, data)
305 newl = eina_list_append(newl, data); 305 {
306 data->ref++;
307 newl = eina_list_append(newl, data);
308 }
306 while (newl) 309 while (newl)
307 { 310 {
308 Edje_Running_Program *runp; 311 Edje_Running_Program *runp;
309 312
310 runp = eina_list_data_get(newl); 313 runp = eina_list_data_get(newl);
311 newl = eina_list_remove(newl, eina_list_data_get(newl)); 314 newl = eina_list_remove(newl, eina_list_data_get(newl));
315 runp->ref--;
312 _edje_program_run_iterate(runp, runp->start_time + TO_DOUBLE(runp->program->tween.time)); 316 _edje_program_run_iterate(runp, runp->start_time + TO_DOUBLE(runp->program->tween.time));
313 if (_edje_block_break(ed)) 317 if (_edje_block_break(ed))
314 { 318 {
315 eina_list_free(newl); 319 EINA_LIST_FREE(newl, data)
320 {
321 data->ref--;
322 if ((data->delete_me) && (data->ref == 0))
323 {
324 _edje_program_run_cleanup(ed, data);
325 free(data);
326 }
327 }
316 goto break_prog; 328 goto break_prog;
317 } 329 }
318 } 330 }
@@ -434,7 +446,14 @@ _edje_program_run_iterate(Edje_Running_Program *runp, double tim)
434 // _edje_emit(ed, "program,stop", runp->program->name); 446 // _edje_emit(ed, "program,stop", runp->program->name);
435 if (_edje_block_break(ed)) 447 if (_edje_block_break(ed))
436 { 448 {
437 if (!ed->walking_actions) free(runp); 449 if (!ed->walking_actions)
450 {
451 if (runp->ref == 0)
452 {
453 _edje_program_run_cleanup(ed, runp);
454 free(runp);
455 }
456 }
438 goto break_prog; 457 goto break_prog;
439 } 458 }
440 EINA_LIST_FOREACH(runp->program->after, l, pa) 459 EINA_LIST_FOREACH(runp->program->after, l, pa)
@@ -447,14 +466,22 @@ _edje_program_run_iterate(Edje_Running_Program *runp, double tim)
447 if (pr) _edje_program_run(ed, pr, 0, "", ""); 466 if (pr) _edje_program_run(ed, pr, 0, "", "");
448 if (_edje_block_break(ed)) 467 if (_edje_block_break(ed))
449 { 468 {
450 if (!ed->walking_actions) free(runp); 469 if ((!ed->walking_actions) && (runp->ref == 0))
470 {
471 _edje_program_run_cleanup(ed, runp);
472 free(runp);
473 }
451 goto break_prog; 474 goto break_prog;
452 } 475 }
453 } 476 }
454 } 477 }
455 _edje_util_thaw(ed); 478 _edje_util_thaw(ed);
456 _edje_unref(ed); 479 _edje_unref(ed);
457 if (!ed->walking_actions) free(runp); 480 if ((!ed->walking_actions) && (runp->ref == 0))
481 {
482 _edje_program_run_cleanup(ed, runp);
483 free(runp);
484 }
458 _edje_unblock(ed); 485 _edje_unblock(ed);
459 return EINA_FALSE; 486 return EINA_FALSE;
460 } 487 }
@@ -513,7 +540,7 @@ _edje_program_end(Edje *ed, Edje_Running_Program *runp)
513 // _edje_emit(ed, "program,stop", pname); 540 // _edje_emit(ed, "program,stop", pname);
514 _edje_util_thaw(ed); 541 _edje_util_thaw(ed);
515 _edje_unref(ed); 542 _edje_unref(ed);
516 if (free_runp) free(runp); 543 if ((free_runp) && (runp->ref == 0)) free(runp);
517} 544}
518 545
519#ifdef HAVE_EPHYSICS 546#ifdef HAVE_EPHYSICS