From e15d9c86df78f673299cde833f85d0b9e5dcef17 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Wed, 21 Aug 2019 00:32:38 +0100 Subject: [PATCH] eina file refs in edje/evas - audit them and plug holes where refs stay in 1 situation at least we delete the eina file (close it) but keep the ptr around (during destruction) which could cause issues with callbaks and events on del and so on.... which may lead to multiple closes where only one should happen ... which would explain my invalid eina file ref problems i'm seeing. i carefully matched eina file handle stores/opens/dups to closes in edje/evas and they seemed to all match up so this audit with comments and fixes seems to have plugged that now. @fix --- src/lib/edje/edje_edit.c | 4 ++-- src/lib/edje/edje_load.c | 10 +++++----- src/lib/efl/interfaces/efl_file.c | 12 ++++++++---- src/lib/elementary/elm_theme.c | 12 ++++++------ src/lib/evas/cache/evas_cache_image.c | 2 +- src/lib/evas/canvas/evas_canvas3d_texture.c | 3 ++- src/lib/evas/canvas/evas_image_legacy.c | 2 +- src/lib/evas/canvas/evas_object_image.c | 4 ++-- src/lib/evas/common/evas_image_load.c | 1 + src/lib/evas/common/evas_image_main.c | 2 +- 10 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/lib/edje/edje_edit.c b/src/lib/edje/edje_edit.c index 1c575174ec..969ef843c6 100644 --- a/src/lib/edje/edje_edit.c +++ b/src/lib/edje/edje_edit.c @@ -499,14 +499,14 @@ _edje_edit_file_import(Edje *ed, const char *path, const char *entry, int compre _edje_edit_eet_close(eetf); eina_file_map_free(f, fdata); - eina_file_close(f); + eina_file_close(f); // close matching open OK return EINA_TRUE; on_error: if (eetf) _edje_edit_eet_close(eetf); eina_file_map_free(f, fdata); - eina_file_close(f); + eina_file_close(f); // close matching open OK return EINA_FALSE; } diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 093fe2bc83..d5f8d43019 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -272,7 +272,7 @@ edje_file_collection_list(const char *file) lst = edje_mmap_collection_list(f); - eina_file_close(f); + eina_file_close(f); // close matching open OK err: free(tmp); return lst; @@ -447,7 +447,7 @@ edje_file_group_exists(const char *file, const char *glob) result = edje_mmap_group_exists(f, glob); - eina_file_close(f); + eina_file_close(f); // close matching open OK err: free(tmp); @@ -484,14 +484,14 @@ edje_file_data_get(const char *file, const char *key) if (!key) return NULL; tmp = eina_vpath_resolve(file); - f = eina_file_open(file, EINA_FALSE); + f = eina_file_open(tmp, EINA_FALSE); if (!f) { ERR("File [%s] can not be opened.", file); goto err; } str = edje_mmap_data_get(f, key); - eina_file_close(f); + eina_file_close(f); // close matching open OK err: free(tmp); @@ -2371,7 +2371,7 @@ _edje_file_free(Edje_File *edf) eina_hash_free(edf->style_hash); _edje_textblock_style_cleanup(edf); if (edf->ef) eet_close(edf->ef); - if (edf->f) eina_file_close(edf->f); + if (edf->f) eina_file_close(edf->f); // close matching open (in _edje_file_open) OK free(edf); } diff --git a/src/lib/efl/interfaces/efl_file.c b/src/lib/efl/interfaces/efl_file.c index 67619039c9..846c88b9db 100644 --- a/src/lib/efl/interfaces/efl_file.c +++ b/src/lib/efl/interfaces/efl_file.c @@ -22,7 +22,8 @@ _efl_file_unload(Eo *obj, Efl_File_Data *pd) if (!pd->file) return; if (!pd->file_opened) return; pd->setting = 1; - eina_file_close(pd->file); + eina_file_close(pd->file); // close matching open (dup in _efl_file_mmap_set) OK + pd->file = NULL; efl_file_mmap_set(obj, NULL); pd->setting = 0; pd->loaded = pd->file_opened = EINA_FALSE; @@ -46,7 +47,7 @@ _efl_file_load(Eo *obj, Efl_File_Data *pd) ret = efl_file_mmap_set(obj, f); pd->setting = 0; if (ret) pd->file_opened = EINA_FALSE; - eina_file_close(f); + eina_file_close(f); // close matching open OK } pd->loaded = !ret; return ret; @@ -64,7 +65,7 @@ _efl_file_mmap_set(Eo *obj, Efl_File_Data *pd, const Eina_File *f) file = eina_file_dup(f); if (!file) return errno; } - if (pd->file) eina_file_close(pd->file); + if (pd->file) eina_file_close(pd->file); // close matching open (dup above) OK pd->file = file; pd->loaded = EINA_FALSE; @@ -138,7 +139,10 @@ _efl_file_efl_object_destructor(Eo *obj, Efl_File_Data *pd) { eina_stringshare_del(pd->vpath); eina_stringshare_del(pd->key); - eina_file_close(pd->file); + eina_file_close(pd->file); // close matching open (dup in _efl_file_mmap_set) OK + pd->vpath = NULL; + pd->key = NULL; + pd->file = NULL; efl_destructor(efl_super(obj, EFL_FILE_MIXIN)); } diff --git a/src/lib/elementary/elm_theme.c b/src/lib/elementary/elm_theme.c index f3326b2f13..13f41e1abc 100644 --- a/src/lib/elementary/elm_theme.c +++ b/src/lib/elementary/elm_theme.c @@ -62,7 +62,7 @@ _elm_theme_item_finalize(Eina_Inlist **files, if (!(version = edje_mmap_data_get(f, "version"))) { - eina_file_close(f); + eina_file_close(f); // close matching open (finalize expected to consume eina file) OK return; } v = atoi(version); @@ -75,7 +75,7 @@ _elm_theme_item_finalize(Eina_Inlist **files, etf = calloc(1, sizeof(Elm_Theme_File)); EINA_SAFETY_ON_NULL_RETURN(etf); etf->item = eina_stringshare_add(item); - etf->handle = f; + etf->handle = f; // now own/consume the file handle if (istheme) { name = edje_mmap_data_get(f, "efl_theme_base"); @@ -156,7 +156,7 @@ _elm_theme_file_item_del(Eina_Inlist **files, const char *str) EINA_INLIST_FOREACH_SAFE(*files, l, item) { if (item->item != str) continue; - eina_file_close(item->handle); + eina_file_close(item->handle); // close matching open (file consumed in finalize by putting it in etf) OK eina_stringshare_del(item->item); *files = eina_inlist_remove(*files, EINA_INLIST_GET(item)); free(item); @@ -174,7 +174,7 @@ _elm_theme_file_mmap_del(Eina_Inlist **files, const Eina_File *file) EINA_INLIST_FOREACH_SAFE(*files, l, item) { if (item->handle != file) continue; - eina_file_close(item->handle); + eina_file_close(item->handle); // close matching open (file consumed in finalize by putting it in etf) OK eina_stringshare_del(item->item); *files = eina_inlist_remove(*files, EINA_INLIST_GET(item)); free(item); @@ -189,7 +189,7 @@ _elm_theme_file_clean(Eina_Inlist **files) Elm_Theme_File *etf = EINA_INLIST_CONTAINER_GET(*files, Elm_Theme_File); eina_stringshare_del(etf->item); - eina_file_close(etf->handle); + eina_file_close(etf->handle); // close matching open (file consumed in finalize by putting it in etf) OK eina_stringshare_del(etf->match_theme); *files = eina_inlist_remove(*files, *files); free(etf); @@ -657,7 +657,7 @@ elm_theme_overlay_mmap_add(Elm_Theme *th, const Eina_File *f) if (!th) th = theme_default; if (!th) { - eina_file_close(file); + eina_file_close(file); // close matching open (finalize expected to consume eina file) OK return; } th->overlay_items = eina_list_free(th->overlay_items); diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c index ae84db4491..8504e1f403 100644 --- a/src/lib/evas/cache/evas_cache_image.c +++ b/src/lib/evas/cache/evas_cache_image.c @@ -183,7 +183,7 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie) FREESTRC(ie->key); if (ie->f && ie->flags.given_mmap) { - eina_file_close(ie->f); + eina_file_close(ie->f); // close matching open (in _evas_cache_image_entry_new) OK ie->f = NULL; } ie->cache = NULL; diff --git a/src/lib/evas/canvas/evas_canvas3d_texture.c b/src/lib/evas/canvas/evas_canvas3d_texture.c index 5533e18373..7154e7e7a1 100644 --- a/src/lib/evas/canvas/evas_canvas3d_texture.c +++ b/src/lib/evas/canvas/evas_canvas3d_texture.c @@ -334,7 +334,8 @@ _evas_canvas3d_texture_efl_object_constructor(Eo *obj, Evas_Canvas3D_Texture_Dat EOLIAN static void _evas_canvas3d_texture_efl_object_destructor(Eo *obj, Evas_Canvas3D_Texture_Data *pd) { - eina_file_close(pd->f); + eina_file_close(pd->f); // close matching open (matches open in _evas_canvas3d_texture_efl_file_load) OK + pd->f = NULL; _texture_fini(obj); efl_destructor(efl_super(obj, MY_CLASS)); } diff --git a/src/lib/evas/canvas/evas_image_legacy.c b/src/lib/evas/canvas/evas_image_legacy.c index 6d466be575..441524e424 100644 --- a/src/lib/evas/canvas/evas_image_legacy.c +++ b/src/lib/evas/canvas/evas_image_legacy.c @@ -50,7 +50,7 @@ evas_object_image_memfile_set(Evas_Object *eo_obj, void *data, int size, char *f f = eina_file_virtualize(NULL, data, size, EINA_TRUE); if (!f) return ; efl_file_simple_mmap_load(eo_obj, f, key); - eina_file_close(f); + eina_file_close(f); // close matching open OK } EAPI void diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index abcfa1729b..16a5dcd69e 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -261,7 +261,7 @@ _evas_image_init_set(const Eina_File *f, const char *key, state_write->f = NULL; if (f) state_write->f = eina_file_dup(f); - eina_file_close(tmp); + eina_file_close(tmp); // close matching open (dup above) OK eina_stringshare_replace(&state_write->key, key); state_write->opaque_valid = 0; @@ -1734,7 +1734,7 @@ evas_object_image_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) } if (o->cur->f) { - eina_file_close(o->cur->f); + eina_file_close(o->cur->f); // close matching open (dup in _evas_image_init_set) OK EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write) state_write->f = NULL; EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c index 611767448e..a969153528 100644 --- a/src/lib/evas/common/evas_image_load.c +++ b/src/lib/evas/common/evas_image_load.c @@ -191,6 +191,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error) if (!ie->f) { ie->f = eina_file_open(ie->file, EINA_FALSE); + ie->flags.given_mmap = EINA_FALSE; file = ie->file; } else file = eina_file_filename_get(ie->f); diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c index 1be23a591e..e06fc9f653 100644 --- a/src/lib/evas/common/evas_image_main.c +++ b/src/lib/evas/common/evas_image_main.c @@ -522,7 +522,7 @@ _evas_common_rgba_image_delete(Image_Entry *ie) } if (ie->f && !ie->flags.given_mmap) { - eina_file_close(ie->f); + eina_file_close(ie->f); // close matching open (dup in _evas_image_file_header) OK ie->f = NULL; } eina_freeq_ptr_add(eina_freeq_main_get(), im, free, sizeof(*im));