summaryrefslogtreecommitdiff
path: root/src/lib/eo
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-08-08 11:01:25 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-08-08 11:28:59 +0900
commitd5ad85abaed3170b86c7915e9ba2ef2e6dae643b (patch)
tree383ec2bfdf0ffee1cf461e5d378dad2ce47833d4 /src/lib/eo
parentf79960839d222c9f7b2eef846fe75e39a60c1709 (diff)
eo: Fix memory leak with overrides
See 0834511067a99faafc2c59f0aabcd58dab1cbc0b And b7840d9177b32f480087bd7f062cc66ab2583485 Ref T5580
Diffstat (limited to 'src/lib/eo')
-rw-r--r--src/lib/eo/eo.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index cd73df811a..20ed40b525 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -116,7 +116,6 @@ static inline void _vtable_chain_write_prepare(Dich_Chain1 *dst);
116static inline void 116static inline void
117_vtable_chain_merge(Dich_Chain1 *dst, const Dich_Chain1 *src) 117_vtable_chain_merge(Dich_Chain1 *dst, const Dich_Chain1 *src)
118{ 118{
119 Eina_Bool writeable = EINA_FALSE;
120 size_t j; 119 size_t j;
121 const op_type_funcs *sf = src->chain2->funcs; 120 const op_type_funcs *sf = src->chain2->funcs;
122 op_type_funcs *df = dst->chain2->funcs; 121 op_type_funcs *df = dst->chain2->funcs;
@@ -131,12 +130,8 @@ _vtable_chain_merge(Dich_Chain1 *dst, const Dich_Chain1 *src)
131 { 130 {
132 if (sf->func && memcmp(df, sf, sizeof(*df))) 131 if (sf->func && memcmp(df, sf, sizeof(*df)))
133 { 132 {
134 if (!writeable) 133 _vtable_chain_write_prepare(dst);
135 { 134 df = dst->chain2->funcs + j;
136 _vtable_chain_write_prepare(dst);
137 df = dst->chain2->funcs + j;
138 }
139
140 memcpy(df, sf, sizeof(*df)); 135 memcpy(df, sf, sizeof(*df));
141 } 136 }
142 } 137 }
@@ -1141,6 +1136,14 @@ _vtable_init(Eo_Vtable *vtable, size_t size)
1141 vtable->chain = calloc(vtable->size, sizeof(*vtable->chain)); 1136 vtable->chain = calloc(vtable->size, sizeof(*vtable->chain));
1142} 1137}
1143 1138
1139static void
1140_vtable_free(Eo_Vtable *vtable)
1141{
1142 if (!vtable) return;
1143 eina_freeq_ptr_main_add(vtable, EINA_FREE_CB(_vtable_func_clean_all), 0);
1144 eina_freeq_ptr_main_add(vtable, free, sizeof(*vtable));
1145}
1146
1144static Eina_Bool 1147static Eina_Bool
1145_eo_class_mro_has(const _Efl_Class *klass, const _Efl_Class *find) 1148_eo_class_mro_has(const _Efl_Class *klass, const _Efl_Class *find)
1146{ 1149{
@@ -1640,11 +1643,12 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
1640 1643
1641 if (!_eo_class_funcs_set(vtable, ops, obj->klass, klass, 0, EINA_TRUE)) 1644 if (!_eo_class_funcs_set(vtable, ops, obj->klass, klass, 0, EINA_TRUE))
1642 { 1645 {
1643 // FIXME: Maybe leaking some chain stuff from copy above? 1646 ERR("Failed to override functions for %s@%p. All previous "
1644 ERR("Failed to override functions for %p", eo_id); 1647 "overrides have been reset.", obj->klass->desc->name, eo_id);
1645 if (obj->opt->vtable == vtable) 1648 if (obj->opt->vtable == vtable)
1646 EO_OPTIONAL_COW_SET(obj, vtable, NULL); 1649 EO_OPTIONAL_COW_SET(obj, vtable, NULL);
1647 free(vtable); 1650 else
1651 _vtable_free(vtable);
1648 goto err; 1652 goto err;
1649 } 1653 }
1650 1654
@@ -1654,7 +1658,7 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
1654 { 1658 {
1655 if (obj->opt->vtable) 1659 if (obj->opt->vtable)
1656 { 1660 {
1657 eina_freeq_ptr_main_add(obj->opt->vtable, free, 0); 1661 _vtable_free(obj->opt->vtable);
1658 EO_OPTIONAL_COW_SET(obj, vtable, NULL); 1662 EO_OPTIONAL_COW_SET(obj, vtable, NULL);
1659 } 1663 }
1660 } 1664 }