summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2018-06-10 16:30:07 +0200
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2018-06-10 17:01:33 +0200
commitd1e1adf0bc4fadb401c778f98110c9ee49540a2c (patch)
treee32888121f62eea63effe8eb071f7fdcc4219e07
parent03e0310a82b440602c85424b36e1955e84c9ffab (diff)
edje: fix edje_part_helpers refcounting
Summary: the reference from efl_reuse was forgotten & the parent relation was not correctlty setted, which led to the fact that NOREF was never emitted. This caused that thte object never really was destructed probebly, and thus the del_interceptor_cb was not executed, and the object simply leaked. The test checks that those properties are correctly set, additionally a error is printed in the efl code when a part has not the expected reference properties. This also enforces errors when users are doing wrong things with objects returned by efl_part. Reviewers: ManMower, zmike Reviewed By: zmike Subscribers: cedric, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D6254
Diffstat (limited to '')
-rw-r--r--src/lib/edje/edje_part_helper.h2
-rw-r--r--src/lib/efl/interfaces/efl_interfaces_main.c6
-rw-r--r--src/tests/edje/edje_test_edje.c30
3 files changed, 38 insertions, 0 deletions
diff --git a/src/lib/edje/edje_part_helper.h b/src/lib/edje/edje_part_helper.h
index dbed9b1772..a1c5596c6f 100644
--- a/src/lib/edje/edje_part_helper.h
+++ b/src/lib/edje/edje_part_helper.h
@@ -91,6 +91,8 @@ _edje_ ## type ## _internal_proxy_get(Edje_Object *obj EINA_UNUSED, Edje *ed, Ed
91 else \ 91 else \
92 { \ 92 { \
93 PROXY_STATIC_VAR(type) = NULL; \ 93 PROXY_STATIC_VAR(type) = NULL; \
94 efl_parent_set(proxy, ed->obj); \
95 efl_unref(proxy); /* efl_reuse gives us one additional reference, give this one up as we gave ownerwhip back to ed->obj */\
94 _edje_real_part_set(proxy, ed, rp, part); \ 96 _edje_real_part_set(proxy, ed, rp, part); \
95 } \ 97 } \
96 __VA_ARGS__; \ 98 __VA_ARGS__; \
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c
index d9b10e89d2..f5b8634d68 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -96,6 +96,12 @@ efl_part(const Eo *obj, const char *name)
96 if (!r) return NULL; 96 if (!r) return NULL;
97 97
98 efl_event_callback_add(r, EFL_EVENT_NOREF, _noref_death, NULL); 98 efl_event_callback_add(r, EFL_EVENT_NOREF, _noref_death, NULL);
99
100 //ensure that the parts that we have here are never leaked
101 //by checking theire references and ownership details
102 EINA_SAFETY_ON_NULL_RETURN_VAL(efl_parent_get(r), r);
103 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_ref_count(r) == 1, r);
104
99 ___efl_auto_unref_set(r, EINA_TRUE); 105 ___efl_auto_unref_set(r, EINA_TRUE);
100 106
101 return efl_ref(r); 107 return efl_ref(r);
diff --git a/src/tests/edje/edje_test_edje.c b/src/tests/edje/edje_test_edje.c
index 103910d4d3..3a39becdb1 100644
--- a/src/tests/edje/edje_test_edje.c
+++ b/src/tests/edje/edje_test_edje.c
@@ -1043,6 +1043,35 @@ EFL_START_TEST(edje_test_text_cursor)
1043} 1043}
1044EFL_END_TEST 1044EFL_END_TEST
1045 1045
1046EFL_START_TEST(edje_test_part_caching)
1047{
1048 Evas *evas = EDJE_TEST_INIT_EVAS();
1049 Evas_Object *ly, *o1, *global_p = NULL;
1050
1051 ly = efl_add(EFL_CANVAS_LAYOUT_CLASS, evas,
1052 efl_file_set(efl_added, test_layout_get("test_swallows.edj"), "test_group")
1053 );
1054
1055 for (int i = 0; i < 10; ++i)
1056 {
1057 Evas_Object *p;
1058
1059 p = efl_part(ly, "swallow");
1060 o1 = efl_content_get(p);
1061
1062 if (global_p)
1063 ck_assert_ptr_eq(global_p, p);
1064 global_p = p;
1065
1066 ck_assert_int_eq(efl_ref_count(p), 1);
1067 ck_assert_ptr_eq(efl_parent_get(p), NULL);
1068
1069 }
1070
1071 EDJE_TEST_FREE_EVAS();
1072}
1073EFL_END_TEST
1074
1046void edje_test_edje(TCase *tc) 1075void edje_test_edje(TCase *tc)
1047{ 1076{
1048 tcase_add_test(tc, edje_test_edje_init); 1077 tcase_add_test(tc, edje_test_edje_init);
@@ -1070,4 +1099,5 @@ void edje_test_edje(TCase *tc)
1070 tcase_add_test(tc, edje_test_signals); 1099 tcase_add_test(tc, edje_test_signals);
1071 tcase_add_test(tc, edje_test_signal_callback_del_full); 1100 tcase_add_test(tc, edje_test_signal_callback_del_full);
1072 tcase_add_test(tc, edje_test_text_cursor); 1101 tcase_add_test(tc, edje_test_text_cursor);
1102 tcase_add_test(tc, edje_test_part_caching);
1073} 1103}