aboutsummaryrefslogtreecommitdiffstats
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
parentlayout: Implement missing edje APIs (diff)
downloadefl-d5ad85abaed3170b86c7915e9ba2ef2e6dae643b.tar.gz
eo: Fix memory leak with overrides
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);
static inline void
_vtable_chain_merge(Dich_Chain1 *dst, const Dich_Chain1 *src)
{
- Eina_Bool writeable = EINA_FALSE;
size_t j;
const op_type_funcs *sf = src->chain2->funcs;
op_type_funcs *df = dst->chain2->funcs;
@@ -131,12 +130,8 @@ _vtable_chain_merge(Dich_Chain1 *dst, const Dich_Chain1 *src)
{
if (sf->func && memcmp(df, sf, sizeof(*df)))
{
- if (!writeable)
- {
- _vtable_chain_write_prepare(dst);
- df = dst->chain2->funcs + j;
- }
-
+ _vtable_chain_write_prepare(dst);
+ df = dst->chain2->funcs + j;
memcpy(df, sf, sizeof(*df));
}
}
@@ -1141,6 +1136,14 @@ _vtable_init(Eo_Vtable *vtable, size_t size)
vtable->chain = calloc(vtable->size, sizeof(*vtable->chain));
}
+static void
+_vtable_free(Eo_Vtable *vtable)
+{
+ if (!vtable) return;
+ eina_freeq_ptr_main_add(vtable, EINA_FREE_CB(_vtable_func_clean_all), 0);
+ eina_freeq_ptr_main_add(vtable, free, sizeof(*vtable));
+}
+
static Eina_Bool
_eo_class_mro_has(const _Efl_Class *klass, const _Efl_Class *find)
{
@@ -1640,11 +1643,12 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
if (!_eo_class_funcs_set(vtable, ops, obj->klass, klass, 0, EINA_TRUE))
{
- // FIXME: Maybe leaking some chain stuff from copy above?
- ERR("Failed to override functions for %p", eo_id);
+ ERR("Failed to override functions for %s@%p. All previous "
+ "overrides have been reset.", obj->klass->desc->name, eo_id);
if (obj->opt->vtable == vtable)
EO_OPTIONAL_COW_SET(obj, vtable, NULL);
- free(vtable);
+ else
+ _vtable_free(vtable);
goto err;
}
@@ -1654,7 +1658,7 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
{
if (obj->opt->vtable)
{
- eina_freeq_ptr_main_add(obj->opt->vtable, free, 0);
+ _vtable_free(obj->opt->vtable);
EO_OPTIONAL_COW_SET(obj, vtable, NULL);
}
}