diff options
author | Marcel Hollerbach <mail@marcel-hollerbach.de> | 2018-06-10 16:30:07 +0200 |
---|---|---|
committer | Marcel Hollerbach <mail@marcel-hollerbach.de> | 2018-06-10 17:01:33 +0200 |
commit | d1e1adf0bc4fadb401c778f98110c9ee49540a2c (patch) | |
tree | e32888121f62eea63effe8eb071f7fdcc4219e07 | |
parent | 03e0310a82b440602c85424b36e1955e84c9ffab (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.h | 2 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_interfaces_main.c | 6 | ||||
-rw-r--r-- | src/tests/edje/edje_test_edje.c | 30 |
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 | } |
1044 | EFL_END_TEST | 1044 | EFL_END_TEST |
1045 | 1045 | ||
1046 | EFL_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 | } | ||
1073 | EFL_END_TEST | ||
1074 | |||
1046 | void edje_test_edje(TCase *tc) | 1075 | void 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 | } |