New module API. Port this API to the mempool subsystem and the tests.

Now the modules can define a default function that will be called when the module is loaded and unloaded.

SVN revision: 36207
This commit is contained in:
Jorge Luis Zapata Muga 2008-09-24 12:55:31 +00:00
parent 44fc837b6a
commit c9f08f6124
18 changed files with 485 additions and 940 deletions

View File

@ -23,6 +23,7 @@
typedef struct _Eina_Mempool_Backend Eina_Mempool_Backend;
struct _Eina_Mempool_Backend
{
const char *name;
void *(*init)(const char *context, const char *options, va_list args);
void (*free)(void *data, void *element);
void *(*alloc)(void *data, unsigned int size);
@ -34,7 +35,6 @@ struct _Eina_Mempool_Backend
struct _Eina_Mempool
{
Eina_Module *module;
Eina_Mempool_Backend backend;
void *backend_data;
};
@ -57,4 +57,8 @@ eina_mempool_free(Eina_Mempool *mp, void *element)
mp->backend.free(mp->backend_data, element);
}
/* FIXME Do we actually need to export this functions?? */
Eina_Bool eina_mempool_register(Eina_Mempool_Backend *be);
void eina_mempool_unregister(Eina_Mempool_Backend *be);
#endif

View File

@ -33,7 +33,6 @@ EAPI extern Eina_Error EINA_ERROR_NOT_MEMPOOL_MODULE;
EAPI int eina_mempool_init(void);
EAPI int eina_mempool_shutdown(void);
EAPI Eina_Module_Group * eina_mempool_module_group_get(void);
EAPI Eina_Mempool * eina_mempool_new(const char *module, const char *context, const char *options, ...);
EAPI void eina_mempool_delete(Eina_Mempool *mp);

View File

@ -26,51 +26,30 @@
* @defgroup Module_Group Module
* @{
*/
typedef struct _Eina_Module Eina_Module;
typedef struct _Eina_Module_Group Eina_Module_Group;
typedef struct _Eina_Module_Export Eina_Module_Export;
typedef Eina_Bool (*Eina_Module_Cb)(Eina_Module *m, void *data);
struct _Eina_Module_Export
{
const char *name;
const char *version;
const char *type;
const void *object;
};
typedef Eina_Bool (*Eina_Module_Init)(void);
typedef void (*Eina_Module_Shutdown)(void);
#define EINA_MODULE_INIT(f) Eina_Module_Init __eina_module_init = &f;
#define EINA_MODULE_SHUTDOWN(f) Eina_Module_Shutdown __eina_module_shutdown = &f;
EAPI int eina_module_init(void);
EAPI int eina_module_shutdown(void);
EAPI void eina_module_root_add(const char *root_path);
EAPI Eina_Module_Group *eina_module_group_new(void);
EAPI void eina_module_group_delete(Eina_Module_Group *group);
EAPI void eina_module_path_register(Eina_Module_Group *modules, const char *path, Eina_Bool recursive);
EAPI void eina_module_app_register(Eina_Module_Group *modules, const char *app, const char *types, const char *version);
EAPI void eina_module_register(Eina_Module_Group *modules, const Eina_Module_Export *static_module);
EAPI Eina_List *eina_module_list_new(Eina_Module_Group *modules, Eina_Module_Cb cb, void *data);
EAPI void eina_module_list_delete(Eina_List *modules);
EAPI Eina_Module *eina_module_new(Eina_Module_Group *modules, const char *name);
EAPI void eina_module_delete(Eina_Module *modules);
EAPI Eina_Module * eina_module_new(const char *file);
EAPI Eina_Bool eina_module_delete(Eina_Module *m);
EAPI Eina_Bool eina_module_load(Eina_Module *module);
EAPI void eina_module_unload(Eina_Module *module);
EAPI void eina_module_list_load(const Eina_List *list);
EAPI void eina_module_list_unload(const Eina_List *list);
EAPI const char *eina_module_path_get(Eina_Module *module);
EAPI Eina_Bool eina_module_unload(Eina_Module *m);
EAPI void *eina_module_symbol_get(Eina_Module *module, const char *symbol);
EAPI const char * eina_module_file_get(Eina_Module *m);
EAPI void *eina_module_export_object_get(Eina_Module *module);
EAPI const char *eina_module_export_type_get(Eina_Module *module);
EAPI const char *eina_module_export_version_get(Eina_Module *module);
EAPI const char *eina_module_export_name_get(Eina_Module *module);
#define EINA_MODULE(Name, Type, Version, Object) EAPI Eina_Module_Export Eina_Export = { Name, Version, Type, Object };
EAPI Eina_List * eina_module_list_get(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data);
EAPI void eina_module_list_load(Eina_List *list);
EAPI void eina_module_list_unload(Eina_List *list);
EAPI void eina_module_list_delete(Eina_List *list);
/** @} */

View File

@ -23,48 +23,78 @@
#include <assert.h>
#include "eina_mempool.h"
#include "eina_list.h"
#include "eina_hash.h"
#include "eina_module.h"
#include "eina_private.h"
/*============================================================================*
* Local *
*============================================================================*/
static Eina_Module_Group *_group;
static Eina_Hash *_backends;
static Eina_List *_modules;
static int _init_count = 0;
static Eina_Mempool *
_new_from_buffer(const char *module, const char *context, const char *options, va_list args)
_new_from_buffer(const char *name, const char *context, const char *options, va_list args)
{
Eina_Mempool_Backend *be;
Eina_Mempool *mp;
Eina_Module *m;
Eina_Error err = EINA_ERROR_NOT_MEMPOOL_MODULE;
eina_error_set(0);
m = eina_module_new(_group, module);
if (!m) return NULL;
if (eina_module_load(m) == EINA_FALSE) goto on_error;
be = eina_hash_find(_backends, name);
if (!be)
goto on_error;
err = EINA_ERROR_OUT_OF_MEMORY;
mp = malloc(sizeof(Eina_Mempool));
if (!mp) goto on_error;
mp->module = m;
mp->backend = *(Eina_Mempool_Backend *)eina_module_export_object_get(m);
/* FIXME why backend is not a pointer? */
mp->backend = *be;
mp->backend_data = mp->backend.init(context, options, args);
return mp;
on_error:
eina_error_set(err);
if (m) eina_module_delete(m);
return NULL;
}
/* Built-in backend's prototypes */
#ifdef EINA_STATIC_BUILD_CHAINED_POOL
Eina_Bool chained_init(void);
void chained_shutdown(void);
#endif
#ifdef EINA_STATIC_BUILD_PASS_THROUGH
Eina_Bool pass_through_init(void);
void pass_through_shutdown(void);
#endif
#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
Eina_Bool ememoa_unknown_init(void);
void ememoa_unknown_shutdown(void);
#endif
#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
Eina_Bool ememoa_fixed_init(void);
void ememoa_fixed_shutdown(void);
#endif
/*============================================================================*
* Global *
*============================================================================*/
Eina_Bool eina_mempool_register(Eina_Mempool_Backend *be)
{
return eina_hash_add(_backends, be->name, be);
}
void eina_mempool_unregister(Eina_Mempool_Backend *be)
{
eina_hash_del(_backends, be->name, be);
}
/*============================================================================*
* API *
*============================================================================*/
@ -79,16 +109,28 @@ eina_mempool_init(void)
{
if (!_init_count)
{
eina_hash_init();
eina_module_init();
_group = eina_module_group_new();
if (!_group) return 0;
eina_module_app_register(_group, "eina", "mp", NULL);
EINA_ERROR_NOT_MEMPOOL_MODULE = eina_error_msg_register("Not a memory pool module.");
_backends = eina_hash_string_superfast_new();
/* dynamic backends */
_modules = eina_module_list_get(PACKAGE_LIB_DIR "/eina/mp/", 0, NULL, NULL);
eina_module_list_load(_modules);
/* builtin backends */
#ifdef EINA_STATIC_BUILD_CHAINED_POOL
chained_init();
#endif
#ifdef EINA_STATIC_BUILD_PASS_THROUGH
pass_through_init();
#endif
#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
ememoa_unknown_init();
#endif
#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
ememoa_fixed_init();
#endif
}
/* get all the modules */
return ++_init_count;
}
@ -101,19 +143,27 @@ eina_mempool_shutdown(void)
_init_count--;
if (_init_count != 0) return _init_count;
/* remove the list of modules */
eina_module_group_delete(_group);
/* builtin backends */
#ifdef EINA_STATIC_BUILD_CHAINED_POOL
chained_shutdown();
#endif
#ifdef EINA_STATIC_BUILD_PASS_THROUGH
pass_through_shutdown();
#endif
#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
ememoa_unknown_shutdown();
#endif
#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
ememoa_fixed_shutdown();
#endif
/* dynamic backends */
eina_module_list_unload(_modules);
eina_module_shutdown();
/* TODO delete the _modules list */
eina_hash_shutdown();
return 0;
}
EAPI Eina_Module_Group *
eina_mempool_module_group_get(void)
{
return _group;
}
/**
*
*/
@ -140,7 +190,6 @@ EAPI void eina_mempool_delete(Eina_Mempool *mp)
if (!mp) return ;
mp->backend.shutdown(mp->backend_data);
eina_module_unload(mp->module);
free(mp);
}

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ AM_CPPFLAGS = \
if !EINA_STATIC_BUILD_CHAINED_POOL
controllerdir = $(libdir)/eina/chained_pool/
controllerdir = $(libdir)/eina/mp/
controller_LTLIBRARIES = eina_chained_mempool.la
eina_chained_mempool_la_SOURCES = \

View File

@ -205,9 +205,8 @@ eina_chained_mempool_shutdown(void *data)
free(mp);
}
#ifndef EINA_STATIC_BUILD_CHAINED_POOL
static Eina_Mempool_Backend mp_backend = {
.name ="chained_mempool",
.init = &eina_chained_mempool_init,
.shutdown = &eina_chained_mempool_shutdown,
.realloc = &eina_chained_mempool_realloc,
@ -215,6 +214,19 @@ static Eina_Mempool_Backend mp_backend = {
.free = &eina_chained_mempool_free
};
EINA_MODULE("chained_mempool", "mp", NULL, &mp_backend);
Eina_Bool chained_init(void)
{
return eina_mempool_register(&mp_backend);
}
void chained_shutdown(void)
{
eina_mempool_unregister(&mp_backend);
}
#ifndef EINA_STATIC_BUILD_CHAINED_POOL
EINA_MODULE_INIT(chained_init);
EINA_MODULE_SHUTDOWN(chained_shutdown);
#endif /* ! EINA_STATIC_BUILD_CHAINED_POOL */

View File

@ -11,7 +11,7 @@ if EINA_ENABLE_EMEMOA
if !EINA_STATIC_BUILD_EMEMOA_FIXED
controllerdir = $(libdir)/eina/chained_pool/
controllerdir = $(libdir)/eina/mp/
controller_LTLIBRARIES = eina_ememoa_fixed.la
eina_ememoa_fixed_la_SOURCES = \

View File

@ -132,9 +132,8 @@ eina_ememoa_fixed_shutdown(void *data)
free(efm);
}
#ifndef EINA_STATIC_BUILD_EMEMOA_FIXED
static Eina_Mempool_Backend mp_backend = {
.name = "ememoa_fixed",
.init = &eina_ememoa_fixed_init,
.shutdown = &eina_ememoa_fixed_shutdown,
.realloc = &eina_ememoa_fixed_realloc,
@ -144,6 +143,20 @@ static Eina_Mempool_Backend mp_backend = {
.statistics = &eina_ememoa_fixed_statistics
};
EINA_MODULE("ememoa_fixed", "mp", NULL, &mp_backend);
Eina_Bool ememoa_fixed_init(void)
{
return eina_mempool_register(&mp_backend);
}
void ememoa_fixed_shutdown(void)
{
eina_mempool_unregister(&mp_backend);
}
#ifndef EINA_STATIC_BUILD_EMEMOA_FIXED
EINA_MODULE_INIT(ememoa_fixed_init);
EINA_MODULE_SHUTDOWN(ememoa_fixed_shutdown);
#endif /* ! EINA_STATIC_BUILD_EMEMOA_FIXED */

View File

@ -11,7 +11,7 @@ if EINA_ENABLE_EMEMOA
if !EINA_STATIC_BUILD_EMEMOA_UNKNOWN
controllerdir = $(libdir)/eina/chained_pool/
controllerdir = $(libdir)/eina/mp/
controller_LTLIBRARIES = eina_ememoa_unknown.la
eina_ememoa_unknown_la_SOURCES = \

View File

@ -138,9 +138,8 @@ eina_ememoa_unknown_size_shutdown(void *data)
free(efm);
}
#ifndef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
static Eina_Mempool_Backend mp_backend = {
.name = "ememoa_unknown",
.init = &eina_ememoa_unknown_size_init,
.shutdown = &eina_ememoa_unknown_size_shutdown,
.realloc = &eina_ememoa_unknown_size_realloc,
@ -150,6 +149,19 @@ static Eina_Mempool_Backend mp_backend = {
.statistics = &eina_ememoa_unknown_size_statistics
};
EINA_MODULE("ememoa_unknown", "mp", NULL, &mp_backend);
Eina_Bool ememoa_unknown_init(void)
{
return eina_mempool_register(&mp_backend);
}
void ememoa_unknown_shutdown(void)
{
eina_mempool_unregister(&mp_backend);
}
#ifndef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
EINA_MODULE_INIT(ememoa_unknown_init);
EINA_MODULE_SHUTDOWN(ememoa_unknown_shutdown);
#endif /* ! EINA_STATIC_BUILD_EMEMOA_UNKNOWN */

View File

@ -9,7 +9,7 @@ AM_CPPFLAGS = \
if !EINA_STATIC_BUILD_PASS_THROUGH
controllerdir = $(libdir)/eina/pass_through/
controllerdir = $(libdir)/eina/mp/
controller_LTLIBRARIES = pass_through.la
pass_through_la_SOURCES = \

View File

@ -59,9 +59,9 @@ eina_pass_through_shutdown(__UNUSED__ void *data)
{
}
#ifndef EINA_STATIC_BUILD_PASS_THROUGH
static Eina_Mempool_Backend mp_backend = {
.name = "pass_through",
.init = &eina_pass_through_init,
.shutdown = &eina_pass_through_shutdown,
.realloc = &eina_pass_through_realloc,
@ -71,7 +71,20 @@ static Eina_Mempool_Backend mp_backend = {
.statistics = NULL
};
EINA_MODULE("pass_through", "mp", NULL, &mp_backend);
Eina_Bool pass_through_init(void)
{
return eina_mempool_register(&mp_backend);
}
void pass_through_shutdown(void)
{
eina_mempool_unregister(&mp_backend);
}
#ifndef EINA_STATIC_BUILD_PASS_THROUGH
EINA_MODULE_INIT(pass_through_init);
EINA_MODULE_SHUTDOWN(pass_through_shutdown);
#endif /* ! EINA_STATIC_BUILD_PASS_THROUGH */

View File

@ -65,6 +65,17 @@ eina_test_list.c
eina_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeina.la
module_dummydir = $(libdir)/eina/test
module_dummy_LTLIBRARIES = module_dummy.la
module_dummy_la_SOURCES = \
eina_test_module_dummy.c
module_dummy_la_LIBADD = $(top_builddir)/src/lib/libeina.la @COVERAGE_LIBS@
module_dummy_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
module_dummy_la_LIBTOOLFLAGS = --tag=disable-static
module_dummy_la_DEPENDENCIES = $(top_builddir)/src/lib/libeina.la
endif
if EINA_ENABLE_BENCH

View File

@ -69,10 +69,29 @@ eina_build_suite(void)
return s;
}
/* FIXME this is a copy from eina_test_mempool
* we should remove the duplication
*/
static Eina_List *_modules;
static void _mempool_init(void)
{
eina_mempool_init();
/* force modules to be loaded in case they are not installed */
_modules = eina_module_list_get(PACKAGE_BUILD_DIR"/src/modules", 1, NULL, NULL);
eina_module_list_load(_modules);
}
static void _mempool_shutdown(void)
{
eina_module_list_delete(_modules);
/* TODO delete the list */
eina_mempool_shutdown();
}
int
main(void)
{
Eina_Module_Group *gp;
//Eina_Module_Group *gp;
Suite *s;
SRunner *sr;
int failed_count;
@ -81,17 +100,13 @@ main(void)
s = eina_build_suite();
sr = srunner_create(s);
eina_mempool_init();
eina_module_root_add(PACKAGE_BUILD_DIR"/src/tests");
gp = eina_mempool_module_group_get();
eina_module_path_register(gp, PACKAGE_BUILD_DIR"/src/modules", EINA_TRUE);
_mempool_init();
srunner_run_all(sr, CK_NORMAL);
failed_count = srunner_ntests_failed(sr);
srunner_free(sr);
eina_mempool_shutdown();
_mempool_shutdown();
return (failed_count == 0) ? 0 : 255;
}

View File

@ -23,16 +23,33 @@
#include "eina_suite.h"
#include "eina_mempool.h"
static Eina_List *_modules;
static void _mempool_init(void)
{
eina_mempool_init();
/* force modules to be loaded in case they are not installed */
_modules = eina_module_list_get(PACKAGE_BUILD_DIR"/src/modules", 1, NULL, NULL);
eina_module_list_load(_modules);
}
static void _mempool_shutdown(void)
{
eina_module_list_delete(_modules);
/* TODO delete the list */
eina_mempool_shutdown();
}
START_TEST(eina_mempool_init_shutdown)
{
Eina_Mempool *mp;
eina_mempool_init();
_mempool_init();
mp = eina_mempool_new("test", "test", NULL);
fail_if(mp != NULL);
eina_mempool_shutdown();
_mempool_shutdown();
}
END_TEST
@ -42,7 +59,7 @@ START_TEST(eina_mempool_chained_mempool)
int *tbl[512];
int i;
eina_mempool_init();
_mempool_init();
mp = eina_mempool_new("chained_mempool", "test", NULL, sizeof (int), 256);
fail_if(!mp);
@ -64,7 +81,7 @@ START_TEST(eina_mempool_chained_mempool)
eina_mempool_delete(mp);
eina_mempool_shutdown();
_mempool_shutdown();
}
END_TEST
@ -74,7 +91,7 @@ START_TEST(eina_mempool_pass_through)
int *tbl[512];
int i;
eina_mempool_init();
_mempool_init();
mp = eina_mempool_new("pass_through", "test", NULL, sizeof (int), 8, 0);
fail_if(!mp);
@ -96,7 +113,7 @@ START_TEST(eina_mempool_pass_through)
eina_mempool_delete(mp);
eina_mempool_shutdown();
_mempool_shutdown();
}
END_TEST
@ -107,7 +124,7 @@ START_TEST(eina_mempool_ememoa_fixed)
int *tbl[512];
int i;
eina_mempool_init();
_mempool_init();
mp = eina_mempool_new("ememoa_fixed", "test", NULL, sizeof (int), 8, 0);
fail_if(!mp);
@ -132,7 +149,7 @@ START_TEST(eina_mempool_ememoa_fixed)
eina_mempool_delete(mp);
eina_mempool_shutdown();
_mempool_shutdown();
}
END_TEST
@ -142,7 +159,7 @@ START_TEST(eina_mempool_ememoa_unknown)
int *tbl[512];
int i;
eina_mempool_init();
_mempool_init();
mp = eina_mempool_new("ememoa_unknown", "test", NULL, 0, 2, sizeof (int), 8, sizeof (int) * 2, 8);
fail_if(!mp);
@ -168,7 +185,7 @@ START_TEST(eina_mempool_ememoa_unknown)
eina_mempool_delete(mp);
eina_mempool_shutdown();
_mempool_shutdown();
}
END_TEST
#endif

View File

@ -35,7 +35,6 @@ START_TEST(eina_module_init_shutdown)
eina_module_shutdown();
eina_module_init();
eina_module_init();
eina_module_root_add(PACKAGE_BUILD_DIR);
eina_module_shutdown();
eina_module_shutdown();
eina_module_shutdown();
@ -43,65 +42,36 @@ START_TEST(eina_module_init_shutdown)
}
END_TEST
static int i42 = 42;
static Eina_Module_Export static_test = { "simple", NULL, "test", &i42 };
EAPI int stupid_test = 7;
static Eina_Bool
_eina_module_test_cb(__UNUSED__ Eina_Module *m, __UNUSED__ void *data)
static Eina_Bool list_cb(Eina_Module *m, void *data)
{
int *sym;
const char *file;
/* the reference count */
eina_module_load(m);
/* get */
sym = eina_module_symbol_get(m, "dummy_symbol");
fail_if(!sym);
fail_if(*sym != 0xbad);
file = eina_module_file_get(m);
fail_if(!file);
eina_module_unload(m);
return EINA_TRUE;
}
START_TEST(eina_module_simple)
START_TEST(eina_module_load_unload)
{
Eina_Module_Group *gp;
Eina_Module *m;
Eina_List *list;
Eina_List *_modules;
eina_module_init();
eina_module_root_add(PACKAGE_BUILD_DIR"/src/tests");
gp = eina_module_group_new();
fail_if(!gp);
eina_module_path_register(gp, PACKAGE_BUILD_DIR"/src/modules", EINA_TRUE);
eina_module_path_register(gp, PACKAGE_BUILD_DIR"/src/lib", EINA_FALSE);
eina_module_path_register(gp, PACKAGE_BUILD_DIR"/src/lib", EINA_FALSE);
eina_module_app_register(gp, "eina", "test", NULL);
eina_module_app_register(gp, "eina", "bench", "1.0.0");
eina_module_register(gp, &static_test);
m = eina_module_new(gp, "unknown");
fail_if(m);
m = eina_module_new(gp, "simple");
fail_if(!m);
fail_if(eina_module_load(m) != EINA_TRUE);
fprintf(stderr, "path: %s\n", eina_module_path_get(m));
fail_if(strcmp("test", eina_module_export_type_get(m)));
fail_if(eina_module_export_version_get(m) != NULL);
fail_if(strcmp("simple", eina_module_export_name_get(m)));
fail_if(eina_module_export_object_get(m) != &i42);
fail_if(eina_module_symbol_get(m, "eina_list_init") != &eina_list_init);
eina_module_unload(m);
eina_module_delete(m);
list = eina_module_list_new(gp, _eina_module_test_cb, NULL);
eina_module_list_load(list);
eina_module_list_unload(list);
eina_module_list_delete(list);
m = eina_module_new(gp, "simple");
eina_module_group_delete(gp);
_modules = eina_module_list_get(PACKAGE_BUILD_DIR"/src/tests/", 1, &list_cb, NULL);
fail_if(!_modules);
eina_module_list_load(_modules);
eina_module_list_unload(_modules);
eina_module_list_delete(_modules);
/* TODO delete the list */
eina_module_shutdown();
}
END_TEST
@ -110,5 +80,5 @@ void
eina_test_module(TCase *tc)
{
tcase_add_test(tc, eina_module_init_shutdown);
tcase_add_test(tc, eina_module_simple);
tcase_add_test(tc, eina_module_load_unload);
}

View File

@ -0,0 +1,17 @@
#include "Eina.h"
#include <stdio.h>
Eina_Bool dummy_module_init(void)
{
return EINA_TRUE;
}
void dummy_module_shutdown(void)
{
}
int dummy_symbol = 0xbad;
EINA_MODULE_INIT(dummy_module_init);
EINA_MODULE_SHUTDOWN(dummy_module_shutdown);