Commit 03cf0f14 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Create primary module from plug-in descriptor and factor code

This should ease later implementation of proper error handling.
parent eccbdf8f
...@@ -36,7 +36,7 @@ VLC_API int vlc_plugin_set(module_t *, module_config_t *, int, ...); ...@@ -36,7 +36,7 @@ VLC_API int vlc_plugin_set(module_t *, module_config_t *, int, ...);
enum vlc_module_properties enum vlc_module_properties
{ {
VLC_SUBMODULE_CREATE, VLC_MODULE_CREATE,
VLC_CONFIG_CREATE, VLC_CONFIG_CREATE,
/* DO NOT EVER REMOVE, INSERT OR REPLACE ANY ITEM! It would break the ABI! /* DO NOT EVER REMOVE, INSERT OR REPLACE ANY ITEM! It would break the ABI!
...@@ -110,8 +110,8 @@ enum vlc_module_properties ...@@ -110,8 +110,8 @@ enum vlc_module_properties
/** /**
* Current plugin ABI version * Current plugin ABI version
*/ */
# define MODULE_SYMBOL 1_2_0h # define MODULE_SYMBOL 1_2_0i
# define MODULE_SUFFIX "__1_2_0h" # define MODULE_SUFFIX "__1_2_0i"
/***************************************************************************** /*****************************************************************************
* Add a few defines. You do not want to read this section. Really. * Add a few defines. You do not want to read this section. Really.
...@@ -166,26 +166,28 @@ enum vlc_module_properties ...@@ -166,26 +166,28 @@ enum vlc_module_properties
*/ */
#define vlc_module_begin() \ #define vlc_module_begin() \
EXTERN_SYMBOL DLL_SYMBOL \ EXTERN_SYMBOL DLL_SYMBOL \
int CDECL_SYMBOL __VLC_SYMBOL(vlc_entry) (module_t *); \ module_t *CDECL_SYMBOL __VLC_SYMBOL(vlc_entry) (void); \
EXTERN_SYMBOL DLL_SYMBOL \ EXTERN_SYMBOL DLL_SYMBOL \
int CDECL_SYMBOL __VLC_SYMBOL(vlc_entry) (module_t *p_module) \ module_t *CDECL_SYMBOL __VLC_SYMBOL(vlc_entry) (void) \
{ \ { \
module_t *p_submodule; \ module_t *module, *p_submodule; \
module_config_t *p_config = NULL; \ module_config_t *p_config = NULL; \
if (vlc_module_set (p_module, VLC_MODULE_NAME, (MODULE_STRING))) \ if (vlc_plugin_set (NULL, NULL, VLC_MODULE_CREATE, &module)) \
goto error; \ goto error; \
p_submodule = p_module; if (vlc_module_set (module, VLC_MODULE_NAME, (MODULE_STRING))) \
goto error; \
p_submodule = module;
#define vlc_module_end() \ #define vlc_module_end() \
(void) p_config; \ (void) p_config; \
return VLC_SUCCESS; \ return module; \
error: \ error: \
return VLC_EGENERIC; \ return NULL; \
} \ } \
VLC_METADATA_EXPORTS VLC_METADATA_EXPORTS
#define add_submodule( ) \ #define add_submodule( ) \
if (vlc_plugin_set (p_module, NULL, VLC_SUBMODULE_CREATE, &p_submodule)) \ if (vlc_plugin_set (module, NULL, VLC_MODULE_CREATE, &p_submodule)) \
goto error; goto error;
#define add_shortcut( ... ) \ #define add_shortcut( ... ) \
...@@ -227,7 +229,7 @@ VLC_METADATA_EXPORTS ...@@ -227,7 +229,7 @@ VLC_METADATA_EXPORTS
goto error; goto error;
#define set_text_domain( dom ) \ #define set_text_domain( dom ) \
if (vlc_module_set (p_module, VLC_MODULE_TEXTDOMAIN, (dom))) \ if (vlc_module_set (module, VLC_MODULE_TEXTDOMAIN, (dom))) \
goto error; goto error;
/***************************************************************************** /*****************************************************************************
...@@ -244,7 +246,7 @@ VLC_METADATA_EXPORTS ...@@ -244,7 +246,7 @@ VLC_METADATA_EXPORTS
*****************************************************************************/ *****************************************************************************/
#define add_type_inner( type ) \ #define add_type_inner( type ) \
vlc_plugin_set (p_module, NULL, VLC_CONFIG_CREATE, (type), &p_config); vlc_plugin_set (module, NULL, VLC_CONFIG_CREATE, (type), &p_config);
#define add_typedesc_inner( type, text, longtext ) \ #define add_typedesc_inner( type, text, longtext ) \
add_type_inner( type ) \ add_type_inner( type ) \
......
...@@ -199,7 +199,7 @@ size_t CacheLoad( vlc_object_t *p_this, const char *dir, module_cache_t **r ) ...@@ -199,7 +199,7 @@ size_t CacheLoad( vlc_object_t *p_this, const char *dir, module_cache_t **r )
uint16_t i_size; uint16_t i_size;
int i_submodules; int i_submodules;
module = vlc_module_create(); module = vlc_module_create (NULL);
/* Load additional infos */ /* Load additional infos */
LOAD_STRING(module->psz_shortname); LOAD_STRING(module->psz_shortname);
...@@ -233,7 +233,7 @@ size_t CacheLoad( vlc_object_t *p_this, const char *dir, module_cache_t **r ) ...@@ -233,7 +233,7 @@ size_t CacheLoad( vlc_object_t *p_this, const char *dir, module_cache_t **r )
while( i_submodules-- ) while( i_submodules-- )
{ {
module_t *submodule = vlc_submodule_create (module); module_t *submodule = vlc_module_create (module);
free (submodule->pp_shortcuts); free (submodule->pp_shortcuts);
LOAD_STRING(submodule->psz_shortname); LOAD_STRING(submodule->psz_shortname);
LOAD_STRING(submodule->psz_longname); LOAD_STRING(submodule->psz_longname);
......
...@@ -39,15 +39,27 @@ static char *strdup_null (const char *str) ...@@ -39,15 +39,27 @@ static char *strdup_null (const char *str)
return (str != NULL) ? strdup (str) : NULL; return (str != NULL) ? strdup (str) : NULL;
} }
module_t *vlc_module_create (void) module_t *vlc_module_create (module_t *parent)
{ {
module_t *module = malloc (sizeof (*module)); module_t *module = malloc (sizeof (*module));
if (module == NULL) if (module == NULL)
return NULL; return NULL;
module->next = NULL; /* TODO: replace module/submodules with plugin/modules */
if (parent == NULL)
{
module->next = NULL;
module->parent = NULL;
}
else
{
module->next = parent->submodule;
parent->submodule = module;
parent->submodule_count++;
module->parent = parent;
}
module->submodule = NULL; module->submodule = NULL;
module->parent = NULL;
module->submodule_count = 0; module->submodule_count = 0;
module->psz_shortname = NULL; module->psz_shortname = NULL;
...@@ -56,8 +68,9 @@ module_t *vlc_module_create (void) ...@@ -56,8 +68,9 @@ module_t *vlc_module_create (void)
module->pp_shortcuts = NULL; module->pp_shortcuts = NULL;
module->i_shortcuts = 0; module->i_shortcuts = 0;
module->psz_capability = NULL; module->psz_capability = NULL;
module->i_score = 1; module->i_score = (parent != NULL) ? parent->i_score : 1;
module->b_unloadable = true; module->b_loaded = false;
module->b_unloadable = parent == NULL;
module->pf_activate = NULL; module->pf_activate = NULL;
module->pf_deactivate = NULL; module->pf_deactivate = NULL;
module->p_config = NULL; module->p_config = NULL;
...@@ -67,7 +80,6 @@ module_t *vlc_module_create (void) ...@@ -67,7 +80,6 @@ module_t *vlc_module_create (void)
/*module->handle = garbage */ /*module->handle = garbage */
module->psz_filename = NULL; module->psz_filename = NULL;
module->domain = NULL; module->domain = NULL;
module->b_loaded = false;
return module; return module;
} }
...@@ -91,44 +103,6 @@ void vlc_module_destroy (module_t *module) ...@@ -91,44 +103,6 @@ void vlc_module_destroy (module_t *module)
free (module); free (module);
} }
module_t *vlc_submodule_create (module_t *module)
{
assert (module != NULL);
module_t *submodule = malloc (sizeof (*submodule));
if (unlikely(submodule == NULL))
return NULL;
/* TODO: replace module/submodules with plugin/modules */
submodule->next = module->submodule;
module->submodule = submodule;
module->submodule_count++;
submodule->parent = module;
submodule->submodule = NULL;
submodule->submodule_count = 0;
submodule->pp_shortcuts = NULL;
submodule->i_shortcuts = 0;
submodule->psz_shortname = NULL;
submodule->psz_longname = NULL;
submodule->psz_help = NULL;
submodule->psz_capability = NULL;
submodule->i_score = module->i_score;
submodule->b_loaded = false;
submodule->b_unloadable = false;
submodule->pf_activate = NULL;
submodule->pf_deactivate = NULL;
submodule->p_config = NULL;
submodule->confsize = 0;
submodule->i_config_items = 0;
submodule->i_bool_items = 0;
/*submodule->handle = unused*/
/*submodule->psz_filename unused */
submodule->domain = NULL;
return submodule;
}
static module_config_t *vlc_config_create (module_t *module, int type) static module_config_t *vlc_config_create (module_t *module, int type)
{ {
unsigned confsize = module->confsize; unsigned confsize = module->confsize;
...@@ -171,10 +145,10 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) ...@@ -171,10 +145,10 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
va_start (ap, propid); va_start (ap, propid);
switch (propid) switch (propid)
{ {
case VLC_SUBMODULE_CREATE: case VLC_MODULE_CREATE:
{ {
module_t **pp = va_arg (ap, module_t **); module_t **pp = va_arg (ap, module_t **);
module_t *submodule = vlc_submodule_create (module); module_t *submodule = vlc_module_create (module);
if (unlikely(submodule == NULL)) if (unlikely(submodule == NULL))
{ {
...@@ -182,6 +156,9 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) ...@@ -182,6 +156,9 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
break; break;
} }
*pp = submodule;
if (module == NULL)
break;
/* Inheritance. Ugly!! */ /* Inheritance. Ugly!! */
submodule->pp_shortcuts = xmalloc (sizeof (char **)); submodule->pp_shortcuts = xmalloc (sizeof (char **));
submodule->pp_shortcuts[0] = strdup_null (module->pp_shortcuts[0]); submodule->pp_shortcuts[0] = strdup_null (module->pp_shortcuts[0]);
...@@ -190,7 +167,6 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...) ...@@ -190,7 +167,6 @@ int vlc_plugin_set (module_t *module, module_config_t *item, int propid, ...)
submodule->psz_shortname = strdup_null (module->psz_shortname); submodule->psz_shortname = strdup_null (module->psz_shortname);
submodule->psz_longname = strdup_null (module->psz_longname); submodule->psz_longname = strdup_null (module->psz_longname);
submodule->psz_capability = strdup_null (module->psz_capability); submodule->psz_capability = strdup_null (module->psz_capability);
*pp = submodule;
break; break;
} }
......
...@@ -65,7 +65,7 @@ static struct ...@@ -65,7 +65,7 @@ static struct
unsigned usage; unsigned usage;
} modules = { VLC_STATIC_MUTEX, NULL, 0 }; } modules = { VLC_STATIC_MUTEX, NULL, 0 };
int vlc_entry__main( module_t * ); module_t *vlc_entry__main (void);
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -80,7 +80,7 @@ static void AllocatePluginDir( vlc_object_t *, module_bank_t *, const char *, ...@@ -80,7 +80,7 @@ static void AllocatePluginDir( vlc_object_t *, module_bank_t *, const char *,
unsigned, cache_mode_t ); unsigned, cache_mode_t );
static int AllocatePluginFile( vlc_object_t *, module_bank_t *, const char *, static int AllocatePluginFile( vlc_object_t *, module_bank_t *, const char *,
const struct stat *, cache_mode_t ); const struct stat *, cache_mode_t );
static module_t * AllocatePlugin( vlc_object_t *, const char *, bool ); static module_t *module_InitDynamic (vlc_object_t *, const char *, bool);
#endif #endif
static module_t *module_InitStatic (vlc_plugin_cb); static module_t *module_InitStatic (vlc_plugin_cb);
static void DeleteModule (module_t **, module_t *); static void DeleteModule (module_t **, module_t *);
...@@ -514,7 +514,7 @@ found_shortcut: ...@@ -514,7 +514,7 @@ found_shortcut:
assert (p_real->psz_filename != NULL); assert (p_real->psz_filename != NULL);
module_t *p_new_module = module_t *p_new_module =
AllocatePlugin( p_this, p_real->psz_filename, false ); module_InitDynamic (p_this, p_real->psz_filename, false);
if( p_new_module == NULL ) if( p_new_module == NULL )
{ /* Corrupted module */ { /* Corrupted module */
msg_Err( p_this, "possibly corrupt module cache" ); msg_Err( p_this, "possibly corrupt module cache" );
...@@ -918,7 +918,7 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank, ...@@ -918,7 +918,7 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank,
p_module = CacheFind (p_bank->loaded_cache, p_bank->i_loaded_cache, p_module = CacheFind (p_bank->loaded_cache, p_bank->i_loaded_cache,
path, st); path, st);
if( p_module == NULL ) if( p_module == NULL )
p_module = AllocatePlugin( p_this, path, true ); p_module = module_InitDynamic (p_this, path, true);
if( p_module == NULL ) if( p_module == NULL )
return -1; return -1;
...@@ -941,7 +941,7 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank, ...@@ -941,7 +941,7 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank,
/* !unloadable not allowed for plugins with callbacks */ /* !unloadable not allowed for plugins with callbacks */
assert( !p_module->b_loaded ); assert( !p_module->b_loaded );
DeleteModule (&modules.head, p_module); DeleteModule (&modules.head, p_module);
p_module = AllocatePlugin( p_this, path, false ); p_module = module_InitDynamic (p_this, path, false);
break; break;
} }
...@@ -957,62 +957,54 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank, ...@@ -957,62 +957,54 @@ static int AllocatePluginFile( vlc_object_t * p_this, module_bank_t *p_bank,
return 0; return 0;
} }
/***************************************************************************** /**
* AllocatePlugin: load a module into memory and initialize it. * Loads a dynamically-linked plug-in into memory and initialize it.
***************************************************************************** *
* This function loads a dynamically loadable module and allocates a structure * The module can then be handled by module_need() and module_unneed().
* for its information data. The module can then be handled by module_need * It can be removed by DeleteModule.
* and module_unneed. It can be removed by DeleteModule. *
*****************************************************************************/ * \param path file path of the shared object
static module_t *AllocatePlugin( vlc_object_t * p_this, const char *psz_file, * \param fast whether to optimize loading for speed or safety
bool fast ) * (fast is used when the plug-in is registered but not used)
*/
static module_t *module_InitDynamic (vlc_object_t *obj,
const char *path, bool fast)
{ {
module_t * p_module = NULL;
module_handle_t handle; module_handle_t handle;
if( module_Load( p_this, psz_file, &handle, fast ) ) if (module_Load (obj, path, &handle, fast))
return NULL;
/* Now that we have successfully loaded the module, we can
* allocate a structure for it */
p_module = vlc_module_create();
if( p_module == NULL )
{
module_Unload( handle );
return NULL; return NULL;
}
p_module->psz_filename = strdup (psz_file);
if (unlikely(p_module->psz_filename == NULL))
goto error;
p_module->handle = handle;
p_module->b_loaded = true;
/* Initialize the module: fill p_module, default config */
static const char entry[] = "vlc_entry" MODULE_SUFFIX;
/* Try to resolve the symbol */ /* Try to resolve the symbol */
int (*pf_symbol)(module_t * p_module) static const char entry_name[] = "vlc_entry" MODULE_SUFFIX;
= (int (*)(module_t *)) module_Lookup( p_module->handle,entry ); vlc_plugin_cb entry =
if( pf_symbol == NULL ) (vlc_plugin_cb) module_Lookup (handle, entry_name);
if (entry == NULL)
{ {
msg_Warn( p_this, "cannot find symbol \"%s\" in plugin `%s'", msg_Warn (obj, "cannot find plug-in entry point in %s", path);
entry, psz_file );
goto error; goto error;
} }
else
/* We can now try to call the symbol */ /* We can now try to call the symbol */
if( pf_symbol( p_module ) != 0 ) module_t *module = entry ();
if (unlikely(module == NULL))
{ {
/* With a well-written module we shouldn't have to print an /* With a well-written module we shouldn't have to print an
* additional error message here, but just make sure. */ * additional error message here, but just make sure. */
msg_Err( p_this, "cannot initialize plugin `%s'", psz_file ); msg_Err (obj, "cannot initialize plug-in %s", path);
goto error; goto error;
} }
return p_module;
module->psz_filename = strdup (path);
if (unlikely(module->psz_filename == NULL))
{
vlc_module_destroy (module);
goto error;
}
module->handle = handle;
module->b_loaded = true;
return module;
error: error:
free( p_module->psz_filename );
vlc_module_destroy (p_module);
module_Unload( handle ); module_Unload( handle );
return NULL; return NULL;
} }
...@@ -1023,13 +1015,10 @@ error: ...@@ -1023,13 +1015,10 @@ error:
*/ */
static module_t *module_InitStatic (vlc_plugin_cb entry) static module_t *module_InitStatic (vlc_plugin_cb entry)
{ {
module_t *module = vlc_module_create ();
if (unlikely(module == NULL))
return NULL;
/* Initializes the module */ /* Initializes the module */
if (entry (module)) module_t *module = entry ();
assert (0); if (unlikely (module == NULL))
abort (); /* FIXME: OOM or bug */
module->b_loaded = true; module->b_loaded = true;
module->b_unloadable = false; module->b_unloadable = false;
......
...@@ -46,7 +46,7 @@ struct module_cache_t ...@@ -46,7 +46,7 @@ struct module_cache_t
/** The module handle type */ /** The module handle type */
typedef void *module_handle_t; typedef void *module_handle_t;
typedef int (*vlc_plugin_cb) (module_t *); typedef module_t *(*vlc_plugin_cb) (void);
/** /**
* Internal module descriptor * Internal module descriptor
...@@ -96,8 +96,7 @@ struct module_t ...@@ -96,8 +96,7 @@ struct module_t
char * domain; /* gettext domain */ char * domain; /* gettext domain */
}; };
module_t *vlc_module_create (void); module_t *vlc_module_create (module_t *);
module_t *vlc_submodule_create (module_t *module);
void vlc_module_destroy (module_t *); void vlc_module_destroy (module_t *);
void module_InitBank (void); void module_InitBank (void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment