forked from enlightenment/efl
and i implemented module UNLOADING. given enough cycles of non-use of a
module and no references, it will get.... UNLOADED :) SVN revision: 25954
This commit is contained in:
parent
2b66c36e64
commit
3115a52684
|
@ -146,6 +146,8 @@ evas_free(Evas *e)
|
|||
free(e->locks.lock.list[i]);
|
||||
if (e->locks.lock.list) free(e->locks.lock.list);
|
||||
|
||||
if (e->engine.module) evas_module_unref(e->engine.module);
|
||||
|
||||
e->magic = 0;
|
||||
free(e);
|
||||
}
|
||||
|
@ -216,6 +218,10 @@ evas_output_method_set(Evas *e, int render_method)
|
|||
/* set the correct render */
|
||||
e->output.render_method = render_method;
|
||||
e->engine.func = (em->functions);
|
||||
evas_module_use(em);
|
||||
if (e->engine.module) evas_module_unref(e->engine.module);
|
||||
e->engine.module = em;
|
||||
evas_module_ref(em);
|
||||
/* get the engine info struct */
|
||||
if (e->engine.func->info) e->engine.info = e->engine.func->info(e);
|
||||
return;
|
||||
|
|
|
@ -396,6 +396,9 @@ evas_render_updates_internal(Evas *e, unsigned char make_updates)
|
|||
e->changed = 0;
|
||||
e->viewport.changed = 0;
|
||||
e->output.changed = 0;
|
||||
|
||||
evas_module_clean();
|
||||
|
||||
return updates;
|
||||
}
|
||||
|
||||
|
@ -428,8 +431,7 @@ evas_render_updates(Evas *e)
|
|||
return NULL;
|
||||
MAGIC_CHECK_END();
|
||||
|
||||
if (!e->changed)
|
||||
return NULL;
|
||||
if (!e->changed) return NULL;
|
||||
return evas_render_updates_internal(e, 1);
|
||||
}
|
||||
|
||||
|
@ -446,7 +448,6 @@ evas_render(Evas *e)
|
|||
return;
|
||||
MAGIC_CHECK_END();
|
||||
|
||||
if (!e->changed)
|
||||
return;
|
||||
(void)evas_render_updates_internal(e, 0);
|
||||
if (!e->changed) return;
|
||||
evas_render_updates_internal(e, 0);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_L
|
|||
RGBA_Image *im;
|
||||
char *p;
|
||||
char *loader = NULL;
|
||||
Evas_Module *em;
|
||||
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
|
@ -50,13 +51,12 @@ evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_L
|
|||
}
|
||||
if (loader)
|
||||
{
|
||||
Evas_Module *em;
|
||||
|
||||
em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
||||
if (em)
|
||||
{
|
||||
if (evas_module_load(em))
|
||||
{
|
||||
evas_module_use(em);
|
||||
evas_image_load_func = em->functions;
|
||||
if (evas_image_load_func->file_head(im, file, key))
|
||||
goto ok;
|
||||
|
@ -66,12 +66,11 @@ evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_L
|
|||
|
||||
for (l = evas_modules; l; l = l->next)
|
||||
{
|
||||
Evas_Module *em;
|
||||
|
||||
em = l->data;
|
||||
if (em->type != EVAS_MODULE_TYPE_IMAGE_LOADER) continue;
|
||||
if (!evas_module_load(em)) continue;
|
||||
evas_image_load_func = em->functions;
|
||||
evas_module_use(em);
|
||||
if (evas_image_load_func->file_head(im, file, key))
|
||||
{
|
||||
if (evas_modules != l)
|
||||
|
@ -86,9 +85,11 @@ evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_L
|
|||
return NULL;
|
||||
ok:
|
||||
|
||||
im->info.module = (void *)em;
|
||||
im->info.loader = (void *)evas_image_load_func;
|
||||
im->info.file = (char *)evas_stringshare_add(file);
|
||||
if (key) im->info.key = (char *)evas_stringshare_add(key);
|
||||
evas_module_ref((Evas_Module *)im->info.module);
|
||||
evas_common_image_ref(im);
|
||||
return im;
|
||||
}
|
||||
|
@ -101,6 +102,7 @@ evas_common_load_image_data_from_file(RGBA_Image *im)
|
|||
if (im->image->data) return;
|
||||
|
||||
evas_image_load_func = im->info.loader;
|
||||
evas_module_use((Evas_Module *)im->info.module);
|
||||
if (!evas_image_load_func->file_data(im, im->info.file, im->info.key))
|
||||
{
|
||||
evas_common_image_surface_alloc(im->image);
|
||||
|
@ -114,4 +116,9 @@ evas_common_load_image_data_from_file(RGBA_Image *im)
|
|||
im->image->no_free = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
evas_module_unref((Evas_Module *)im->info.module);
|
||||
im->info.module = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@ evas_common_image_free(RGBA_Image *im)
|
|||
// if (im->info.real_file) evas_stringshare_del(im->info.real_file);
|
||||
if (im->info.key) evas_stringshare_del(im->info.key);
|
||||
// if (im->info.comment) evas_stringshare_del(im->info.comment);
|
||||
if (im->info.module) evas_module_unref((Evas_Module *)im->info.module);
|
||||
free(im);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ evas_common_save_image_to_file(RGBA_Image *im, const char *file, const char *key
|
|||
em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_SAVER, saver);
|
||||
if (em)
|
||||
{
|
||||
evas_module_use(em);
|
||||
if (evas_module_load(em))
|
||||
{
|
||||
evas_image_save_func = em->functions;
|
||||
|
|
|
@ -158,7 +158,7 @@ evas_module_init(void)
|
|||
{
|
||||
Evas_Module *em;
|
||||
|
||||
em = malloc(sizeof(Evas_Module));
|
||||
em = calloc(1, sizeof(Evas_Module));
|
||||
if (!em) continue;
|
||||
em->name = strdup(de->d_name);
|
||||
em->path = strdup(mp->path);
|
||||
|
@ -223,6 +223,7 @@ evas_module_load(Evas_Module *em)
|
|||
|
||||
if (em->loaded) return 1;
|
||||
|
||||
// printf("LOAD %s\n", em->name);
|
||||
snprintf(buf, sizeof(buf), "%s/%s/%s/module.so", em->path, em->name, MODULE_ARCH);
|
||||
if (!evas_file_path_exists(buf))
|
||||
{
|
||||
|
@ -282,6 +283,76 @@ evas_module_unload(Evas_Module *em)
|
|||
em->loaded = 0;
|
||||
}
|
||||
|
||||
void
|
||||
evas_module_ref(Evas_Module *em)
|
||||
{
|
||||
em->ref++;
|
||||
// printf("M: %s ref++ = %i\n", em->name, em->ref);
|
||||
}
|
||||
|
||||
void
|
||||
evas_module_unref(Evas_Module *em)
|
||||
{
|
||||
em->ref--;
|
||||
// printf("M: %s ref-- = %i\n", em->name, em->ref);
|
||||
}
|
||||
|
||||
static int use_count = 0;
|
||||
|
||||
void
|
||||
evas_module_use(Evas_Module *em)
|
||||
{
|
||||
em->last_used = use_count;
|
||||
}
|
||||
|
||||
void
|
||||
evas_module_clean(void)
|
||||
{
|
||||
static int call_count = 0;
|
||||
int ago;
|
||||
int noclean = -1;
|
||||
Evas_List *l;
|
||||
Evas_Module *em;
|
||||
|
||||
/* only clean modules every 32 calls */
|
||||
call_count++;
|
||||
if (call_count <= 32) return;
|
||||
call_count = 0;
|
||||
|
||||
if (noclean == -1)
|
||||
{
|
||||
if (getenv("EVAS_NOCLEAN"))
|
||||
{
|
||||
noclean = 1;
|
||||
}
|
||||
noclean = 0;
|
||||
}
|
||||
if (noclean == 1) return;
|
||||
|
||||
/* incriment use counter = 28bits */
|
||||
use_count++;
|
||||
if (use_count > 0x0fffffff) use_count = 0;
|
||||
|
||||
// printf("CLEAN!\n");
|
||||
/* go through all modules */
|
||||
for (l = evas_modules; l; l = l->next)
|
||||
{
|
||||
em = l->data;
|
||||
// printf("M %s %i %i\n", em->name, em->ref, em->loaded);
|
||||
/* if the module is refernced - skip */
|
||||
if ((em->ref > 0) || (!em->loaded)) continue;
|
||||
/* how many clean cycles ago was this module last used */
|
||||
ago = use_count - em->last_used;
|
||||
if (em->last_used > use_count) ago += 0x10000000;
|
||||
/* if it was used last more than N clean cycles ago - unload */
|
||||
if (ago > 3)
|
||||
{
|
||||
// printf(" UNLOAD %s\n", em->name);
|
||||
evas_module_unload(em);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* will dlclose all the modules loaded and free all the structs */
|
||||
void
|
||||
evas_module_shutdown(void)
|
||||
|
@ -329,6 +400,9 @@ _evas_module_engine_inherit(Evas_Func *funcs, char *name)
|
|||
{
|
||||
if (evas_module_load(em))
|
||||
{
|
||||
/* FIXME: no way to unref */
|
||||
evas_module_ref(em);
|
||||
evas_module_use(em);
|
||||
*funcs = *((Evas_Func *)(em->functions));
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -249,6 +249,7 @@ struct _RGBA_Image
|
|||
RGBA_Image_Flags flags;
|
||||
struct
|
||||
{
|
||||
void *module;
|
||||
void *loader;
|
||||
// int format;
|
||||
char *file;
|
||||
|
|
|
@ -45,10 +45,13 @@ struct _Evas_Module
|
|||
int (*open)(Evas_Module *);
|
||||
void (*close)(Evas_Module *);
|
||||
} func;
|
||||
unsigned char loaded : 1;
|
||||
unsigned char loaded : 1;
|
||||
|
||||
void *functions; /* this are the functions exported by the module */
|
||||
void *data; /* some internal data for the module i.e the id for engines */
|
||||
|
||||
int ref; /* how many refs */
|
||||
int last_used; /* the cycle count when it was last used */
|
||||
};
|
||||
|
||||
|
||||
|
@ -308,6 +311,7 @@ struct _Evas
|
|||
int events_frozen;
|
||||
|
||||
struct {
|
||||
Evas_Module *module;
|
||||
Evas_Func *func;
|
||||
struct {
|
||||
void *output;
|
||||
|
@ -743,7 +747,12 @@ void evas_module_init(void);
|
|||
Evas_Module * evas_module_find_type(Evas_Module_Type type, const char *name);
|
||||
int evas_module_load(Evas_Module *em);
|
||||
void evas_module_unload(Evas_Module *em);
|
||||
void evas_module_ref(Evas_Module *em);
|
||||
void evas_module_unref(Evas_Module *em);
|
||||
void evas_module_use(Evas_Module *em);
|
||||
void evas_module_clean(void);
|
||||
void evas_module_shutdown(void);
|
||||
|
||||
EAPI int _evas_module_engine_inherit(Evas_Func *funcs, char *name);
|
||||
|
||||
#define EVAS_API_OVERRIDE(func, api, prefix) \
|
||||
|
|
Loading…
Reference in New Issue