vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Sun Jun 18 14:47:28 2017 +0300| [8f779d1a8f7ba2b65b05e2d227c05f583fe396a4] | committer: Rémi Denis-Courmont
modules: build search tree of module capabilities This incrementally builds a search tree of all module capabilities. Each node contains a table of all modules with the capability. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8f779d1a8f7ba2b65b05e2d227c05f583fe396a4 --- src/modules/bank.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 6 deletions(-) diff --git a/src/modules/bank.c b/src/modules/bank.c index 3fff2bb389..e496bd9172 100644 --- a/src/modules/bank.c +++ b/src/modules/bank.c @@ -36,6 +36,9 @@ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#ifdef HAVE_SEARCH_H +# include <search.h> +#endif #include <vlc_common.h> #include <vlc_plugin.h> @@ -46,20 +49,90 @@ #include "config/configuration.h" #include "modules/modules.h" +typedef struct vlc_modcap +{ + char *name; + module_t **modv; + size_t modc; +} vlc_modcap_t; + +static int vlc_modcap_cmp(const void *a, const void *b) +{ + const vlc_modcap_t *capa = a, *capb = b; + return strcmp(capa->name, capb->name); +} + +static void vlc_modcap_free(void *data) +{ + vlc_modcap_t *cap = data; + + free(cap->modv); + free(cap->name); + free(cap); +} + static struct { vlc_mutex_t lock; block_t *caches; + void *caps_tree; unsigned usage; -} modules = { VLC_STATIC_MUTEX, NULL, 0 }; +} modules = { VLC_STATIC_MUTEX, NULL, NULL, 0 }; vlc_plugin_t *vlc_plugins = NULL; -static void module_StoreBank(vlc_plugin_t *lib) +/** + * Adds a module to the bank + */ +static int vlc_module_store(module_t *mod) +{ + const char *name = module_get_capability(mod); + vlc_modcap_t *cap = malloc(sizeof (*cap)); + if (unlikely(cap == NULL)) + return -1; + + cap->name = strdup(name); + cap->modv = NULL; + cap->modc = 0; + + if (unlikely(cap->name == NULL)) + goto error; + + vlc_modcap_t **cp = tsearch(cap, &modules.caps_tree, vlc_modcap_cmp); + if (unlikely(cp == NULL)) + goto error; + + if (*cp != cap) + { + vlc_modcap_free(cap); + cap = *cp; + } + + module_t **modv = realloc(cap->modv, sizeof (*modv) * (cap->modc + 1)); + if (unlikely(modv == NULL)) + return -1; + + cap->modv = modv; + cap->modv[cap->modc] = mod; + cap->modc++; + return 0; +error: + vlc_modcap_free(cap); + return -1; +} + +/** + * Adds a plugin (and all its modules) to the bank + */ +static void vlc_plugin_store(vlc_plugin_t *lib) { /*vlc_assert_locked (&modules.lock);*/ + lib->next = vlc_plugins; vlc_plugins = lib; + + for (module_t *m = lib->module; m != NULL; m = m->next) + vlc_module_store(m); } /** @@ -96,7 +169,7 @@ static void module_InitStaticModules(void) { vlc_plugin_t *lib = module_InitStatic(vlc_static_modules[i]); if (likely(lib != NULL)) - module_StoreBank(lib); + vlc_plugin_store(lib); } } #else @@ -207,7 +280,7 @@ static int AllocatePluginFile (module_bank_t *bank, const char *abspath, if (plugin == NULL) return -1; - module_StoreBank(plugin); + vlc_plugin_store(plugin); if (bank->mode & CACHE_WRITE_FILE) /* Add entry to to-be-saved cache */ { @@ -334,7 +407,7 @@ static void AllocatePluginPath(vlc_object_t *obj, const char *path, if (mode & CACHE_SCAN_DIR) vlc_plugin_destroy(plugin); else - module_StoreBank(plugin); + vlc_plugin_store(plugin); } if (mode & CACHE_WRITE_FILE) @@ -495,7 +568,7 @@ void module_InitBank (void) * as for every other module. */ vlc_plugin_t *plugin = module_InitStatic(vlc_entry__core); if (likely(plugin != NULL)) - module_StoreBank(plugin); + vlc_plugin_store(plugin); config_SortConfig (); } modules.usage++; @@ -518,6 +591,7 @@ void module_EndBank (bool b_plugins) { vlc_plugin_t *libs = NULL; block_t *caches = NULL; + void *caps_tree = NULL; /* If plugins were _not_ loaded, then the caller still has the bank lock * from module_InitBank(). */ @@ -532,11 +606,15 @@ void module_EndBank (bool b_plugins) config_UnsortConfig (); libs = vlc_plugins; caches = modules.caches; + caps_tree = modules.caps_tree; vlc_plugins = NULL; modules.caches = NULL; + modules.caps_tree = NULL; } vlc_mutex_unlock (&modules.lock); + tdestroy(caps_tree, vlc_modcap_free); + while (libs != NULL) { vlc_plugin_t *lib = libs; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
