* modules.c : Built-in and plugin modules management functions
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: modules.c,v 1.25 2001/04/16 07:40:11 sam Exp $
+ * $Id: modules.c,v 1.31 2001/05/30 17:03:12 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Ethan C. Baldridge <BaldridgeE@cadmus.com>
#include "common.h"
#include "threads.h"
+#include "mtime.h"
+#include "tests.h"
+#include "netutils.h"
+#include "modules.h"
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+
+#include "video.h"
+#include "video_output.h"
+#include "audio_output.h"
+
+#include "interface.h"
#include "intf_msg.h"
-#include "modules.h"
+#include "intf_playlist.h"
+
+#ifdef HAVE_DYNAMIC_PLUGINS
+# include "modules_core.h"
+#endif
#include "modules_builtin.h"
-#include "modules_core.h"
+#include "modules_export.h"
-/* Local prototypes */
+#include "main.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
#ifdef HAVE_DYNAMIC_PLUGINS
-static int AllocatePluginModule ( module_bank_t *, char * );
+static int AllocatePluginModule ( char * );
#endif
-static int AllocateBuiltinModule( module_bank_t *,
- int ( * ) ( module_t * ),
+static int AllocateBuiltinModule( int ( * ) ( module_t * ),
int ( * ) ( module_t * ),
int ( * ) ( module_t * ) );
-static int FreeModule ( module_bank_t * p_bank, module_t * );
+static int DeleteModule ( module_t * );
static int LockModule ( module_t * );
static int UnlockModule ( module_t * );
#ifdef HAVE_DYNAMIC_PLUGINS
static int CallSymbol ( module_t *, char * );
#endif
-/*****************************************************************************
- * module_CreateBank: create the module bank.
- *****************************************************************************
- * This function creates a module bank structure.
- *****************************************************************************/
-module_bank_t * module_CreateBank( void )
-{
- module_bank_t * p_bank;
-
- p_bank = malloc( sizeof( module_bank_t ) );
-
- return( p_bank );
-}
+static module_symbols_t symbols;
/*****************************************************************************
* module_InitBank: create the module bank.
* This function creates a module bank structure and fills it with the
* built-in modules, as well as all the plugin modules it can find.
*****************************************************************************/
-void module_InitBank( module_bank_t * p_bank )
+void module_InitBank( void )
{
#ifdef HAVE_DYNAMIC_PLUGINS
static char * path[] = { ".", "lib", PLUGIN_PATH, NULL, NULL };
struct dirent * file;
#endif /* HAVE_DYNAMIC_PLUGINS */
- p_bank->first = NULL;
- vlc_mutex_init( &p_bank->lock );
+ p_module_bank->first = NULL;
+ vlc_mutex_init( &p_module_bank->lock );
- intf_WarnMsg( 1, "module: module bank initialized" );
+ /*
+ * Store the symbols to be exported
+ */
+ STORE_SYMBOLS( &symbols );
+ /*
+ * Check all the built-in modules
+ */
intf_WarnMsg( 2, "module: checking built-in modules" );
ALLOCATE_ALL_BUILTINS();
+ /*
+ * Check all the plugin modules we can find
+ */
#ifdef HAVE_DYNAMIC_PLUGINS
intf_WarnMsg( 2, "module: checking plugin modules" );
psz_fullpath = *ppsz_path;
}
- intf_WarnMsgImm( 3, "module: browsing `%s'", psz_fullpath );
+ intf_WarnMsgImm( 1, "module: browsing `%s'", psz_fullpath );
if( (dir = opendir( psz_fullpath )) )
{
/* We created a nice filename -- now we just try to load
* it as a plugin module. */
- AllocatePluginModule( p_bank, psz_file );
+ AllocatePluginModule( psz_file );
/* We don't care if the allocation succeeded */
free( psz_file );
}
#endif /* HAVE_DYNAMIC_PLUGINS */
+ intf_WarnMsg( 3, "module: module bank initialized" );
+
return;
}
/*****************************************************************************
- * module_DestroyBank: destroy the module bank.
+ * module_EndBank: empty the module bank.
*****************************************************************************
- * This function unloads all unused plugin modules and removes the module
+ * This function unloads all unused plugin modules and empties the module
* bank in case of success.
*****************************************************************************/
-void module_DestroyBank( module_bank_t * p_bank )
+void module_EndBank( void )
{
module_t * p_next;
- while( p_bank->first != NULL )
+ while( p_module_bank->first != NULL )
{
- if( FreeModule( p_bank, p_bank->first ) )
+ if( DeleteModule( p_module_bank->first ) )
{
/* Module deletion failed */
intf_ErrMsg( "module error: `%s' can't be removed. trying harder.",
- p_bank->first->psz_name );
+ p_module_bank->first->psz_name );
/* We just free the module by hand. Niahahahahaha. */
- p_next = p_bank->first->next;
- free(p_bank->first);
- p_bank->first = p_next;
+ p_next = p_module_bank->first->next;
+ free(p_module_bank->first);
+ p_module_bank->first = p_next;
}
}
/* Destroy the lock */
- vlc_mutex_destroy( &p_bank->lock );
-
- /* We can free the module bank */
- free( p_bank );
+ vlc_mutex_destroy( &p_module_bank->lock );
return;
}
* This function resets the module bank by unloading all unused plugin
* modules.
*****************************************************************************/
-void module_ResetBank( module_bank_t * p_bank )
+void module_ResetBank( void )
{
intf_ErrMsg( "FIXME: module_ResetBank unimplemented" );
return;
* This function parses the module bank and hides modules that have been
* unused for a while.
*****************************************************************************/
-void module_ManageBank( module_bank_t * p_bank )
+void module_ManageBank( void )
{
#ifdef HAVE_DYNAMIC_PLUGINS
module_t * p_module;
/* We take the global lock */
- vlc_mutex_lock( &p_bank->lock );
+ vlc_mutex_lock( &p_module_bank->lock );
/* Parse the module list to see if any modules need to be unloaded */
- for( p_module = p_bank->first ;
+ for( p_module = p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
{
}
else
{
- intf_WarnMsg( 3, "module: hiding unused plugin module `%s'",
+ intf_WarnMsg( 1, "module: hiding unused plugin module `%s'",
p_module->psz_name );
HideModule( p_module );
}
/* We release the global lock */
- vlc_mutex_unlock( &p_bank->lock );
+ vlc_mutex_unlock( &p_module_bank->lock );
#endif /* HAVE_DYNAMIC_PLUGINS */
return;
*****************************************************************************
* This function returns the module that best fits the asked capabilities.
*****************************************************************************/
-module_t * module_Need( module_bank_t *p_bank,
- int i_capabilities, void *p_data )
+module_t * module_Need( int i_capabilities, void *p_data )
{
module_t * p_module;
module_t * p_bestmodule = NULL;
int i_index;
/* We take the global lock */
- vlc_mutex_lock( &p_bank->lock );
+ vlc_mutex_lock( &p_module_bank->lock );
/* Parse the module list for capabilities and probe each of them */
- for( p_module = p_bank->first ;
+ for( p_module = p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
{
}
/* We can release the global lock, module refcount was incremented */
- vlc_mutex_unlock( &p_bank->lock );
+ vlc_mutex_unlock( &p_module_bank->lock );
if( p_bestmodule != NULL )
{
- intf_WarnMsg( 3, "module: locking module `%s'",
+ intf_WarnMsg( 1, "module: locking module `%s'",
p_bestmodule->psz_name );
}
* This function must be called by the thread that called module_Need, to
* decrease the reference count and allow for hiding of modules.
*****************************************************************************/
-void module_Unneed( module_bank_t * p_bank, module_t * p_module )
+void module_Unneed( module_t * p_module )
{
/* We take the global lock */
- vlc_mutex_lock( &p_bank->lock );
+ vlc_mutex_lock( &p_module_bank->lock );
/* Just unlock the module - we can't do anything if it fails,
* so there is no need to check the return value. */
UnlockModule( p_module );
- intf_WarnMsg( 3, "module: unlocking module `%s'", p_module->psz_name );
+ intf_WarnMsg( 1, "module: unlocking module `%s'", p_module->psz_name );
/* We release the global lock */
- vlc_mutex_unlock( &p_bank->lock );
+ vlc_mutex_unlock( &p_module_bank->lock );
return;
}
*****************************************************************************
* This function loads a dynamically loadable module and allocates a structure
* for its information data. The module can then be handled by module_Need,
- * module_Unneed and HideModule. It can be removed by FreeModule.
+ * module_Unneed and HideModule. It can be removed by DeleteModule.
*****************************************************************************/
-static int AllocatePluginModule( module_bank_t * p_bank, char * psz_filename )
+static int AllocatePluginModule( char * psz_filename )
{
module_t * p_module, * p_othermodule;
module_handle_t handle;
if( module_load( psz_filename, &handle ) )
{
/* The plugin module couldn't be opened */
- intf_WarnMsgImm( 3, "module warning: cannot open %s (%s)",
+ intf_WarnMsgImm( 1, "module warning: cannot open %s (%s)",
psz_filename, module_error() );
return( -1 );
}
/* We need to fill these since they may be needed by CallSymbol() */
p_module->is.plugin.psz_filename = psz_filename;
p_module->is.plugin.handle = handle;
+ p_module->p_symbols = &symbols;
/* Initialize the module : fill p_module->psz_name, etc. */
if( CallSymbol( p_module, "InitModule" ) != 0 )
}
/* Check that we don't already have a module with this name */
- for( p_othermodule = p_bank->first ;
+ for( p_othermodule = p_module_bank->first ;
p_othermodule != NULL ;
p_othermodule = p_othermodule->next )
{
p_module->b_builtin = 0;
/* Link module into the linked list */
- if( p_bank->first != NULL )
+ if( p_module_bank->first != NULL )
{
- p_bank->first->prev = p_module;
+ p_module_bank->first->prev = p_module;
}
- p_module->next = p_bank->first;
+ p_module->next = p_module_bank->first;
p_module->prev = NULL;
- p_bank->first = p_module;
+ p_module_bank->first = p_module;
/* Immediate message so that a slow module doesn't make the user wait */
intf_WarnMsgImm( 2, "module: plugin module `%s', %s",
*****************************************************************************
* This function registers a built-in module and allocates a structure
* for its information data. The module can then be handled by module_Need,
- * module_Unneed and HideModule. It can be removed by FreeModule.
+ * module_Unneed and HideModule. It can be removed by DeleteModule.
*****************************************************************************/
-static int AllocateBuiltinModule( module_bank_t * p_bank,
- int ( *pf_init ) ( module_t * ),
+static int AllocateBuiltinModule( int ( *pf_init ) ( module_t * ),
int ( *pf_activate ) ( module_t * ),
int ( *pf_deactivate ) ( module_t * ) )
{
}
/* Check that we don't already have a module with this name */
- for( p_othermodule = p_bank->first ;
+ for( p_othermodule = p_module_bank->first ;
p_othermodule != NULL ;
p_othermodule = p_othermodule->next )
{
p_module->is.builtin.pf_deactivate = pf_deactivate;
/* Link module into the linked list */
- if( p_bank->first != NULL )
+ if( p_module_bank->first != NULL )
{
- p_bank->first->prev = p_module;
+ p_module_bank->first->prev = p_module;
}
- p_module->next = p_bank->first;
+ p_module->next = p_module_bank->first;
p_module->prev = NULL;
- p_bank->first = p_module;
+ p_module_bank->first = p_module;
/* Immediate message so that a slow module doesn't make the user wait */
intf_WarnMsgImm( 2, "module: builtin module `%s', %s",
}
/*****************************************************************************
- * FreeModule: delete a module and its structure.
+ * DeleteModule: delete a module and its structure.
*****************************************************************************
* This function can only be called if i_usage <= 0.
*****************************************************************************/
-static int FreeModule( module_bank_t * p_bank, module_t * p_module )
+static int DeleteModule( module_t * p_module )
{
/* If the module is not in use but is still in memory, we first have
* to hide it and remove it from memory before we can free the
#endif
/* Unlink the module from the linked list. */
- if( p_module == p_bank->first )
+ if( p_module == p_module_bank->first )
{
- p_bank->first = p_module->next;
+ p_module_bank->first = p_module->next;
}
if( p_module->prev != NULL )
*****************************************************************************/
static int CallSymbol( module_t * p_module, char * psz_name )
{
- typedef int ( symbol_t ) ( module_t * p_module );
- symbol_t * p_symbol;
+ int (* pf_symbol) ( module_t * p_module );
/* Try to resolve the symbol */
- p_symbol = module_getsymbol( p_module->is.plugin.handle, psz_name );
+ pf_symbol = module_getsymbol( p_module->is.plugin.handle, psz_name );
- if( !p_symbol )
+ if( pf_symbol == NULL )
{
/* We couldn't load the symbol */
- intf_WarnMsg( 3, "module warning: "
+ intf_WarnMsg( 1, "module warning: "
"cannot find symbol %s in module %s (%s)",
psz_name, p_module->is.plugin.psz_filename,
module_error() );
}
/* We can now try to call the symbol */
- if( p_symbol( p_module ) != 0 )
+ if( pf_symbol( p_module ) != 0 )
{
/* With a well-written module we shouldn't have to print an
* additional error message here, but just make sure. */