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]);
|
free(e->locks.lock.list[i]);
|
||||||
if (e->locks.lock.list) free(e->locks.lock.list);
|
if (e->locks.lock.list) free(e->locks.lock.list);
|
||||||
|
|
||||||
|
if (e->engine.module) evas_module_unref(e->engine.module);
|
||||||
|
|
||||||
e->magic = 0;
|
e->magic = 0;
|
||||||
free(e);
|
free(e);
|
||||||
}
|
}
|
||||||
|
@ -216,6 +218,10 @@ evas_output_method_set(Evas *e, int render_method)
|
||||||
/* set the correct render */
|
/* set the correct render */
|
||||||
e->output.render_method = render_method;
|
e->output.render_method = render_method;
|
||||||
e->engine.func = (em->functions);
|
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 */
|
/* get the engine info struct */
|
||||||
if (e->engine.func->info) e->engine.info = e->engine.func->info(e);
|
if (e->engine.func->info) e->engine.info = e->engine.func->info(e);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -396,6 +396,9 @@ evas_render_updates_internal(Evas *e, unsigned char make_updates)
|
||||||
e->changed = 0;
|
e->changed = 0;
|
||||||
e->viewport.changed = 0;
|
e->viewport.changed = 0;
|
||||||
e->output.changed = 0;
|
e->output.changed = 0;
|
||||||
|
|
||||||
|
evas_module_clean();
|
||||||
|
|
||||||
return updates;
|
return updates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,8 +431,7 @@ evas_render_updates(Evas *e)
|
||||||
return NULL;
|
return NULL;
|
||||||
MAGIC_CHECK_END();
|
MAGIC_CHECK_END();
|
||||||
|
|
||||||
if (!e->changed)
|
if (!e->changed) return NULL;
|
||||||
return NULL;
|
|
||||||
return evas_render_updates_internal(e, 1);
|
return evas_render_updates_internal(e, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +448,6 @@ evas_render(Evas *e)
|
||||||
return;
|
return;
|
||||||
MAGIC_CHECK_END();
|
MAGIC_CHECK_END();
|
||||||
|
|
||||||
if (!e->changed)
|
if (!e->changed) return;
|
||||||
return;
|
evas_render_updates_internal(e, 0);
|
||||||
(void)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;
|
RGBA_Image *im;
|
||||||
char *p;
|
char *p;
|
||||||
char *loader = NULL;
|
char *loader = NULL;
|
||||||
|
Evas_Module *em;
|
||||||
|
|
||||||
if (file == NULL) return NULL;
|
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)
|
if (loader)
|
||||||
{
|
{
|
||||||
Evas_Module *em;
|
|
||||||
|
|
||||||
em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
||||||
if (em)
|
if (em)
|
||||||
{
|
{
|
||||||
if (evas_module_load(em))
|
if (evas_module_load(em))
|
||||||
{
|
{
|
||||||
|
evas_module_use(em);
|
||||||
evas_image_load_func = em->functions;
|
evas_image_load_func = em->functions;
|
||||||
if (evas_image_load_func->file_head(im, file, key))
|
if (evas_image_load_func->file_head(im, file, key))
|
||||||
goto ok;
|
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)
|
for (l = evas_modules; l; l = l->next)
|
||||||
{
|
{
|
||||||
Evas_Module *em;
|
|
||||||
|
|
||||||
em = l->data;
|
em = l->data;
|
||||||
if (em->type != EVAS_MODULE_TYPE_IMAGE_LOADER) continue;
|
if (em->type != EVAS_MODULE_TYPE_IMAGE_LOADER) continue;
|
||||||
if (!evas_module_load(em)) continue;
|
if (!evas_module_load(em)) continue;
|
||||||
evas_image_load_func = em->functions;
|
evas_image_load_func = em->functions;
|
||||||
|
evas_module_use(em);
|
||||||
if (evas_image_load_func->file_head(im, file, key))
|
if (evas_image_load_func->file_head(im, file, key))
|
||||||
{
|
{
|
||||||
if (evas_modules != l)
|
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;
|
return NULL;
|
||||||
ok:
|
ok:
|
||||||
|
|
||||||
|
im->info.module = (void *)em;
|
||||||
im->info.loader = (void *)evas_image_load_func;
|
im->info.loader = (void *)evas_image_load_func;
|
||||||
im->info.file = (char *)evas_stringshare_add(file);
|
im->info.file = (char *)evas_stringshare_add(file);
|
||||||
if (key) im->info.key = (char *)evas_stringshare_add(key);
|
if (key) im->info.key = (char *)evas_stringshare_add(key);
|
||||||
|
evas_module_ref((Evas_Module *)im->info.module);
|
||||||
evas_common_image_ref(im);
|
evas_common_image_ref(im);
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +102,7 @@ evas_common_load_image_data_from_file(RGBA_Image *im)
|
||||||
if (im->image->data) return;
|
if (im->image->data) return;
|
||||||
|
|
||||||
evas_image_load_func = im->info.loader;
|
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))
|
if (!evas_image_load_func->file_data(im, im->info.file, im->info.key))
|
||||||
{
|
{
|
||||||
evas_common_image_surface_alloc(im->image);
|
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;
|
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.real_file) evas_stringshare_del(im->info.real_file);
|
||||||
if (im->info.key) evas_stringshare_del(im->info.key);
|
if (im->info.key) evas_stringshare_del(im->info.key);
|
||||||
// if (im->info.comment) evas_stringshare_del(im->info.comment);
|
// if (im->info.comment) evas_stringshare_del(im->info.comment);
|
||||||
|
if (im->info.module) evas_module_unref((Evas_Module *)im->info.module);
|
||||||
free(im);
|
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);
|
em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_SAVER, saver);
|
||||||
if (em)
|
if (em)
|
||||||
{
|
{
|
||||||
|
evas_module_use(em);
|
||||||
if (evas_module_load(em))
|
if (evas_module_load(em))
|
||||||
{
|
{
|
||||||
evas_image_save_func = em->functions;
|
evas_image_save_func = em->functions;
|
||||||
|
|
|
@ -158,7 +158,7 @@ evas_module_init(void)
|
||||||
{
|
{
|
||||||
Evas_Module *em;
|
Evas_Module *em;
|
||||||
|
|
||||||
em = malloc(sizeof(Evas_Module));
|
em = calloc(1, sizeof(Evas_Module));
|
||||||
if (!em) continue;
|
if (!em) continue;
|
||||||
em->name = strdup(de->d_name);
|
em->name = strdup(de->d_name);
|
||||||
em->path = strdup(mp->path);
|
em->path = strdup(mp->path);
|
||||||
|
@ -223,6 +223,7 @@ evas_module_load(Evas_Module *em)
|
||||||
|
|
||||||
if (em->loaded) return 1;
|
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);
|
snprintf(buf, sizeof(buf), "%s/%s/%s/module.so", em->path, em->name, MODULE_ARCH);
|
||||||
if (!evas_file_path_exists(buf))
|
if (!evas_file_path_exists(buf))
|
||||||
{
|
{
|
||||||
|
@ -282,6 +283,76 @@ evas_module_unload(Evas_Module *em)
|
||||||
em->loaded = 0;
|
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 */
|
/* will dlclose all the modules loaded and free all the structs */
|
||||||
void
|
void
|
||||||
evas_module_shutdown(void)
|
evas_module_shutdown(void)
|
||||||
|
@ -329,6 +400,9 @@ _evas_module_engine_inherit(Evas_Func *funcs, char *name)
|
||||||
{
|
{
|
||||||
if (evas_module_load(em))
|
if (evas_module_load(em))
|
||||||
{
|
{
|
||||||
|
/* FIXME: no way to unref */
|
||||||
|
evas_module_ref(em);
|
||||||
|
evas_module_use(em);
|
||||||
*funcs = *((Evas_Func *)(em->functions));
|
*funcs = *((Evas_Func *)(em->functions));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,6 +249,7 @@ struct _RGBA_Image
|
||||||
RGBA_Image_Flags flags;
|
RGBA_Image_Flags flags;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
void *module;
|
||||||
void *loader;
|
void *loader;
|
||||||
// int format;
|
// int format;
|
||||||
char *file;
|
char *file;
|
||||||
|
|
|
@ -45,10 +45,13 @@ struct _Evas_Module
|
||||||
int (*open)(Evas_Module *);
|
int (*open)(Evas_Module *);
|
||||||
void (*close)(Evas_Module *);
|
void (*close)(Evas_Module *);
|
||||||
} func;
|
} func;
|
||||||
unsigned char loaded : 1;
|
unsigned char loaded : 1;
|
||||||
|
|
||||||
void *functions; /* this are the functions exported by the module */
|
void *functions; /* this are the functions exported by the module */
|
||||||
void *data; /* some internal data for the module i.e the id for engines */
|
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;
|
int events_frozen;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
Evas_Module *module;
|
||||||
Evas_Func *func;
|
Evas_Func *func;
|
||||||
struct {
|
struct {
|
||||||
void *output;
|
void *output;
|
||||||
|
@ -743,7 +747,12 @@ void evas_module_init(void);
|
||||||
Evas_Module * evas_module_find_type(Evas_Module_Type type, const char *name);
|
Evas_Module * evas_module_find_type(Evas_Module_Type type, const char *name);
|
||||||
int evas_module_load(Evas_Module *em);
|
int evas_module_load(Evas_Module *em);
|
||||||
void evas_module_unload(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);
|
void evas_module_shutdown(void);
|
||||||
|
|
||||||
EAPI int _evas_module_engine_inherit(Evas_Func *funcs, char *name);
|
EAPI int _evas_module_engine_inherit(Evas_Func *funcs, char *name);
|
||||||
|
|
||||||
#define EVAS_API_OVERRIDE(func, api, prefix) \
|
#define EVAS_API_OVERRIDE(func, api, prefix) \
|
||||||
|
|
Loading…
Reference in New Issue