From bcd7736914b5a7f78a5dc19330b738dc8e94f518 Mon Sep 17 00:00:00 2001 From: Daniel Zaoui Date: Fri, 5 Dec 2014 03:19:47 +0200 Subject: [PATCH] Eo: fix error handling when too many deletions invocations occur. Before this fix, when a deletion was invoked twice on an object, a wrong message ("...You wrongly call eo_unref() within a destructor...") was printed. This was caused by the del_triggered flag that was not resetted when the destruction finished. This patch fixes this behavior by printing the right message on a double deletion. --- src/lib/eo/eo_private.h | 11 +++---- .../eo/suite/eo_test_class_behaviour_errors.c | 34 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h index 7ea5014..a238618 100644 --- a/src/lib/eo/eo_private.h +++ b/src/lib/eo/eo_private.h @@ -279,21 +279,22 @@ _eo_unref(_Eo_Object *obj) --(obj->refcount); if (obj->refcount == 0) { - if (obj->del_triggered) + if (obj->destructed) { - ERR("Object %p deletion already triggered. You wrongly call eo_unref() within a destructor.", obj); + ERR("Object %p already destructed.", _eo_id_get(obj)); return; } - obj->del_triggered = EINA_TRUE; - if (obj->destructed) + if (obj->del_triggered) { - ERR("Object %p already destructed.", obj); + ERR("Object %p deletion already triggered. You wrongly call eo_unref() within a destructor.", _eo_id_get(obj)); return; } + obj->del_triggered = EINA_TRUE; _eo_del_internal(__FILE__, __LINE__, obj); + obj->del_triggered = EINA_FALSE; #ifdef EO_DEBUG /* If for some reason it's not empty, clear it. */ while (obj->xrefs) diff --git a/src/tests/eo/suite/eo_test_class_behaviour_errors.c b/src/tests/eo/suite/eo_test_class_behaviour_errors.c index 300f3fa..a54a2f2 100644 --- a/src/tests/eo/suite/eo_test_class_behaviour_errors.c +++ b/src/tests/eo/suite/eo_test_class_behaviour_errors.c @@ -57,7 +57,41 @@ START_TEST(eo_destructor_unref) } END_TEST +START_TEST(eo_destructor_double_del) +{ + eo_init(); + eina_log_print_cb_set(eo_test_print_cb, &ctx); + + static Eo_Class_Description class_desc = { + EO_VERSION, + "Simple", + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_NOOPS(), + NULL, + 0, + NULL, + NULL + }; + + klass = eo_class_new(&class_desc, SIMPLE_CLASS, NULL); + fail_if(!klass); + + Eo *obj = eo_add(klass, NULL); + eo_manual_free_set(obj, EINA_TRUE); + fail_if(!obj); + + TEST_EO_ERROR("_eo_unref", "Object %p already destructed."); + eo_del(obj); + eo_del(obj); + + eina_log_print_cb_set(eina_log_print_cb_stderr, NULL); + + eo_shutdown(); +} +END_TEST + void eo_test_class_behaviour_errors(TCase *tc) { tcase_add_test(tc, eo_destructor_unref); + tcase_add_test(tc, eo_destructor_double_del); } -- 2.7.4