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
This commit is contained in:
Carsten Haitzler 2019-08-21 00:32:38 +01:00
parent 5f5e95e336
commit e15d9c86df
10 changed files with 29 additions and 23 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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;

View File

@ -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));
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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));