Commit 5dc2da73 authored by Sam Hocevar's avatar Sam Hocevar

* ./src/misc/modules.c: the module linked list is going bye bye. We now use

    the vlc_object_* and vlc_list_* functions to manage modules. The Win32
    interface doesn't build, but I'll fix this.
parent 17e19cc1
......@@ -2,7 +2,7 @@
* modules.h : Module management functions.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: modules.h,v 1.59 2002/07/31 20:56:50 sam Exp $
* $Id: modules.h,v 1.60 2002/08/15 12:11:15 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -45,11 +45,6 @@ struct module_bank_t
{
VLC_COMMON_MEMBERS
module_t * first; /* First module in the bank */
int i_count; /* Number of allocated modules */
vlc_mutex_t lock; /* Global lock -- you can't imagine how awful *
it is to design thread-safe linked lists */
module_symbols_t symbols;
};
......@@ -98,12 +93,6 @@ struct module_t
vlc_bool_t b_builtin; /* Set to true if the module is built in */
int i_usage; /* Reference counter */
int i_unused_delay; /* Delay until module is unloaded */
module_t *next; /* Next module */
module_t *prev; /* Previous module */
/*
* Symbol table we send to the module so that it can access vlc symbols
*/
......@@ -125,8 +114,6 @@ void __module_LoadPlugins ( vlc_object_t * );
void __module_EndBank ( vlc_object_t * );
#define module_ResetBank(a) __module_ResetBank(VLC_OBJECT(a))
void __module_ResetBank ( vlc_object_t * );
#define module_ManageBank(a) __module_ManageBank(VLC_OBJECT(a))
void __module_ManageBank ( vlc_object_t * );
#define module_Need(a,b,c) __module_Need(VLC_OBJECT(a),b,c)
VLC_EXPORT( module_t *, __module_Need, ( vlc_object_t *, const char *, const char * ) );
......
......@@ -2,7 +2,7 @@
* vlc_objects.h: vlc_object_t definition.
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: vlc_objects.h,v 1.9 2002/08/14 17:06:53 sam Exp $
* $Id: vlc_objects.h,v 1.10 2002/08/15 12:11:15 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -52,7 +52,7 @@ VLC_EXPORT( void *, __vlc_object_find, ( vlc_object_t *, int, int ) );
VLC_EXPORT( void, __vlc_object_yield, ( vlc_object_t * ) );
VLC_EXPORT( void, __vlc_object_release, ( vlc_object_t * ) );
VLC_EXPORT( vlc_list_t *, __vlc_list_find, ( vlc_object_t *, int, int ) );
VLC_EXPORT( void, __vlc_list_release, ( vlc_object_t *, vlc_list_t * ) );
VLC_EXPORT( void, vlc_list_release, ( vlc_list_t * ) );
VLC_EXPORT( void, __vlc_liststructure, ( vlc_object_t * ) );
VLC_EXPORT( void, __vlc_dumpstructure, ( vlc_object_t * ) );
......@@ -82,9 +82,6 @@ VLC_EXPORT( void, __vlc_dumpstructure, ( vlc_object_t * ) );
#define vlc_list_find(a,b,c) \
__vlc_list_find( VLC_OBJECT(a),b,c)
#define vlc_list_release(a,b) \
__vlc_list_release( VLC_OBJECT(a),b )
#define vlc_liststructure(a) \
__vlc_liststructure( VLC_OBJECT(a) )
......
......@@ -93,7 +93,6 @@ struct module_symbols_t
void (* __msg_Unsubscribe_inner) ( vlc_object_t *, msg_subscription_t * ) ;
void (* __msg_Warn_inner) ( void *, const char *, ... ) ;
void (* __vlc_dumpstructure_inner) ( vlc_object_t * ) ;
void (* __vlc_list_release_inner) ( vlc_object_t *, vlc_list_t * ) ;
void (* __vlc_liststructure_inner) ( vlc_object_t * ) ;
void (* __vlc_object_attach_inner) ( vlc_object_t *, vlc_object_t * ) ;
void (* __vlc_object_destroy_inner) ( vlc_object_t * ) ;
......@@ -129,6 +128,7 @@ struct module_symbols_t
void (* mwait_inner) ( mtime_t date ) ;
void (* playlist_Command_inner) ( playlist_t *, int, int ) ;
void (* sout_DeleteInstance_inner) ( sout_instance_t * ) ;
void (* vlc_list_release_inner) ( vlc_list_t * ) ;
void (* vout_AllocatePicture_inner) ( vout_thread_t *, picture_t *, int, int, u32 ) ;
void (* vout_DatePicture_inner) ( vout_thread_t *, picture_t *, mtime_t ) ;
void (* vout_DestroyPicture_inner) ( vout_thread_t *, picture_t * ) ;
......@@ -191,7 +191,6 @@ struct module_symbols_t
# define __vlc_cond_init p_symbols->__vlc_cond_init_inner
# define __vlc_dumpstructure p_symbols->__vlc_dumpstructure_inner
# define __vlc_list_find p_symbols->__vlc_list_find_inner
# define __vlc_list_release p_symbols->__vlc_list_release_inner
# define __vlc_liststructure p_symbols->__vlc_liststructure_inner
# define __vlc_mutex_destroy p_symbols->__vlc_mutex_destroy_inner
# define __vlc_mutex_init p_symbols->__vlc_mutex_init_inner
......@@ -272,6 +271,7 @@ struct module_symbols_t
# define playlist_Command p_symbols->playlist_Command_inner
# define playlist_Delete p_symbols->playlist_Delete_inner
# define sout_DeleteInstance p_symbols->sout_DeleteInstance_inner
# define vlc_list_release p_symbols->vlc_list_release_inner
# define vout_AllocatePicture p_symbols->vout_AllocatePicture_inner
# define vout_ChromaCmp p_symbols->vout_ChromaCmp_inner
# define vout_CreatePicture p_symbols->vout_CreatePicture_inner
......
......@@ -2,7 +2,7 @@
* gtk_preferences.c: functions to handle the preferences dialog box.
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: preferences.c,v 1.3 2002/08/14 17:06:53 sam Exp $
* $Id: preferences.c,v 1.4 2002/08/15 12:11:15 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
* Loc Minier <lool@via.ecp.fr>
......@@ -118,7 +118,8 @@ void GtkPreferencesShow( GtkMenuItem * menuitem, gpointer user_data )
static void GtkCreateConfigDialog( char *psz_module_name,
intf_thread_t *p_intf )
{
module_t *p_module;
module_t **pp_parser;
vlc_list_t *p_list;
module_config_t *p_item;
guint rows = 0;
......@@ -173,27 +174,36 @@ static void GtkCreateConfigDialog( char *psz_module_name,
/* Look for the selected module */
for( p_module = p_intf->p_vlc->p_module_bank->first ; p_module != NULL ;
p_module = p_module->next )
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
if( psz_module_name
&& !strcmp( psz_module_name, p_module->psz_object_name ) )
&& !strcmp( psz_module_name, (*pp_parser)->psz_object_name ) )
{
break;
}
}
if( !p_module ) return;
if( !(*pp_parser) )
{
vlc_list_release( p_list );
return;
}
/* We found it, now we can start building its configuration interface */
/* Create the configuration dialog box */
#ifdef MODULE_NAME_IS_gnome
config_dialog = gnome_dialog_new( p_module->psz_longname, NULL );
config_dialog = gnome_dialog_new( (*pp_parser)->psz_longname, NULL );
config_dialog_vbox = GNOME_DIALOG(config_dialog)->vbox;
#else
config_dialog = gtk_dialog_new();
gtk_window_set_title( GTK_WINDOW(config_dialog), p_module->psz_longname );
gtk_window_set_title( GTK_WINDOW(config_dialog),
(*pp_parser)->psz_longname );
config_dialog_vbox = GTK_DIALOG(config_dialog)->vbox;
#endif
......@@ -215,8 +225,9 @@ static void GtkCreateConfigDialog( char *psz_module_name,
gtk_container_add( GTK_CONTAINER(config_dialog_vbox), config_notebook );
/* Enumerate config options and add corresponding config boxes */
p_item = p_module->p_config;
do
p_item = (*pp_parser)->p_config;
if( p_item ) do
{
switch( p_item->i_type )
{
......@@ -318,9 +329,7 @@ static void GtkCreateConfigDialog( char *psz_module_name,
/* build a list of available modules */
{
gchar * entry[2];
vlc_list_t *p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE,
FIND_ANYWHERE );
module_t **pp_parser = (module_t **)p_list->pp_objects;
pp_parser = (module_t **)p_list->pp_objects;
for( ; *pp_parser ; pp_parser++ )
{
......@@ -332,8 +341,6 @@ static void GtkCreateConfigDialog( char *psz_module_name,
gtk_clist_append( GTK_CLIST(module_clist), entry );
}
}
vlc_list_release( p_intf, p_list );
}
gtk_clist_set_column_auto_resize( GTK_CLIST(module_clist),
......@@ -508,6 +515,8 @@ static void GtkCreateConfigDialog( char *psz_module_name,
}
while( p_item->i_type != CONFIG_HINT_END && p_item++ );
vlc_list_release( p_list );
#ifndef MODULE_NAME_IS_gnome
/* Now let's add the action buttons at the bottom of the page */
dialog_action_area = GTK_DIALOG(config_dialog)->action_area;
......@@ -649,35 +658,41 @@ void GtkModuleHighlighted( GtkCList *module_clist, int row, int column,
{
intf_thread_t *p_intf;
GtkWidget *config_button;
module_t *p_module;
module_t **pp_parser;
vlc_list_t *p_list;
char *psz_name;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(module_clist),
"p_intf" );
if( gtk_clist_get_text( GTK_CLIST(module_clist), row, 0, &psz_name ) )
if( !gtk_clist_get_text( GTK_CLIST(module_clist), row, 0, &psz_name ) )
{
/* look for module 'psz_name' */
for( p_module = p_intf->p_vlc->p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
return;
}
/* look for module 'psz_name' */
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
if( !strcmp( (*pp_parser)->psz_object_name, psz_name ) )
{
if( !strcmp( p_module->psz_object_name, psz_name ) )
{
gtk_object_set_data( GTK_OBJECT(module_clist),
"module_highlighted", p_module );
config_button = gtk_object_get_data( GTK_OBJECT(module_clist),
"config_button" );
if( p_module->i_config_items )
gtk_widget_set_sensitive( config_button, TRUE );
else
gtk_widget_set_sensitive( config_button, FALSE );
break;
}
}
gtk_object_set_data( GTK_OBJECT(module_clist),
"module_highlighted", (*pp_parser) );
config_button = gtk_object_get_data( GTK_OBJECT(module_clist),
"config_button" );
if( (*pp_parser)->i_config_items )
gtk_widget_set_sensitive( config_button, TRUE );
else
gtk_widget_set_sensitive( config_button, FALSE );
break;
}
}
vlc_list_release( p_list );
}
/****************************************************************************
......
......@@ -2,7 +2,7 @@
* preferences.cpp: preferences window for the kde gui
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: preferences.cpp,v 1.3 2002/08/14 17:06:53 sam Exp $
* $Id: preferences.cpp,v 1.4 2002/08/15 12:11:15 sam Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> Mon Aug 12 2002
*
......@@ -51,7 +51,6 @@ KPreferences::KPreferences(intf_thread_t *p_intf, const char *psz_module_name,
KDialogBase ( Tabbed, caption, Ok| Apply|Cancel|User1, Ok, parent,
"vlc preferences", true, false, "Save")
{
module_t *p_module;
module_t **pp_parser;
vlc_list_t *p_list;
module_config_t *p_item;
......@@ -60,17 +59,30 @@ KPreferences::KPreferences(intf_thread_t *p_intf, const char *psz_module_name,
this->p_intf = p_intf;
/* List all modules */
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
/* Look for the selected module */
for( p_module = p_intf->p_vlc->p_module_bank->first ; p_module != NULL ;
p_module = p_module->next )
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
if( psz_module_name && !strcmp( psz_module_name, p_module->psz_object_name ) )
if( psz_module_name
&& !strcmp( psz_module_name, (*pp_parser)->psz_object_name ) )
{
break;
}
}
if( !p_module ) return;
p_item = p_module->p_config;
do
if( !(*pp_parser) )
{
vlc_list_release( p_list );
return;
}
p_item = (*pp_parser)->p_config;
if( p_item ) do
{
switch( p_item->i_type )
{
......@@ -118,11 +130,9 @@ KPreferences::KPreferences(intf_thread_t *p_intf, const char *psz_module_name,
/* build a list of available plugins */
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE,
FIND_ANYWHERE );
pp_parser = (module_t **)p_list->pp_objects;
for( ; *pp_parser ; pp_parser++ )
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
if( !strcmp( (*pp_parser)->psz_capability,
p_item->psz_type ) )
......@@ -132,7 +142,6 @@ KPreferences::KPreferences(intf_thread_t *p_intf, const char *psz_module_name,
(*pp_parser)->psz_longname);
}
}
vlc_list_release( p_intf, p_list );
vlc_mutex_unlock( p_item->p_lock );
}
......@@ -221,8 +230,10 @@ KPreferences::KPreferences(intf_thread_t *p_intf, const char *psz_module_name,
p_item++;
}
while( p_item->i_type != CONFIG_HINT_END );
vlc_list_release( p_list );
exec();
}
/*
......@@ -237,16 +248,25 @@ KPreferences::~KPreferences()
*/
bool KPreferences::isConfigureable(QString module)
{
module_t *p_module;
for( p_module = p_intf->p_vlc->p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next ) {
if( !module.compare( p_module->psz_object_name ) ) {
return p_module->i_config_items != 0;
module_t **pp_parser;
vlc_list_t *p_list;
p_list = vlc_list_find( this->p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
if( !module.compare( (*pp_parser)->psz_object_name ) )
{
bool ret = (*pp_parser)->i_config_items != 0;
vlc_list_release( p_list );
return ret;
}
}
return false;
vlc_list_release( p_list );
return false;
}
/*
......
......@@ -394,7 +394,7 @@ void __fastcall TPreferencesDlg::CreateConfigDialog( char *psz_module_name )
/* Enumerate config options and add corresponding config boxes */
p_item = p_module->p_config;
do
if( p_item ) do
{
switch( p_item->i_type )
{
......@@ -438,7 +438,7 @@ void __fastcall TPreferencesDlg::CreateConfigDialog( char *psz_module_name )
}
}
vlc_list_release( p_intfGlobal, p_list );
vlc_list_release( p_list );
break;
......
......@@ -2,7 +2,7 @@
* libvlc.c: main libvlc source
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: libvlc.c,v 1.25 2002/08/12 09:34:15 sam Exp $
* $Id: libvlc.c,v 1.26 2002/08/15 12:11:15 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -272,13 +272,12 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
}
p_help_module->psz_object_name = "help";
config_Duplicate( p_help_module, p_help_config );
p_help_module->next = p_vlc->p_module_bank->first;
p_vlc->p_module_bank->first = p_help_module;
vlc_object_attach( p_help_module, p_vlc->p_module_bank );
/* End hack */
if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
{
p_vlc->p_module_bank->first = p_help_module->next;
vlc_object_detach( p_help_module );
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
module_EndBank( p_vlc );
......@@ -294,7 +293,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
Usage( p_vlc, "help" );
Usage( p_vlc, "main" );
p_vlc->p_module_bank->first = p_help_module->next;
vlc_object_detach( p_help_module );
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
module_EndBank( p_vlc );
......@@ -306,7 +305,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
if( config_GetInt( p_vlc, "version" ) )
{
Version();
p_vlc->p_module_bank->first = p_help_module->next;
vlc_object_detach( p_help_module );
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
module_EndBank( p_vlc );
......@@ -315,7 +314,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
}
/* Hack: remove the help module here */
p_vlc->p_module_bank->first = p_help_module->next;
vlc_object_detach( p_help_module );
/* End hack */
/*
......@@ -327,11 +326,10 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
module_LoadBuiltins( p_vlc );
module_LoadPlugins( p_vlc );
msg_Dbg( p_vlc, "module bank initialized, found %i modules",
p_vlc->p_module_bank->i_count );
p_vlc->p_module_bank->i_children );
/* Hack: insert the help module here */
p_help_module->next = p_vlc->p_module_bank->first;
p_vlc->p_module_bank->first = p_help_module;
vlc_object_attach( p_help_module, p_vlc->p_module_bank );
/* End hack */
/* Check for help on modules */
......@@ -339,7 +337,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
{
Usage( p_vlc, p_tmp );
free( p_tmp );
p_vlc->p_module_bank->first = p_help_module->next;
vlc_object_detach( p_help_module );
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
module_EndBank( p_vlc );
......@@ -351,7 +349,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
if( config_GetInt( p_vlc, "longhelp" ) )
{
Usage( p_vlc, NULL );
p_vlc->p_module_bank->first = p_help_module->next;
vlc_object_detach( p_help_module );
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
module_EndBank( p_vlc );
......@@ -363,7 +361,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
if( config_GetInt( p_vlc, "list" ) )
{
ListModules( p_vlc );
p_vlc->p_module_bank->first = p_help_module->next;
vlc_object_detach( p_help_module );
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
module_EndBank( p_vlc );
......@@ -372,7 +370,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
}
/* Hack: remove the help module here */
p_vlc->p_module_bank->first = p_help_module->next;
vlc_object_detach( p_help_module );
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
/* End hack */
......@@ -902,7 +900,8 @@ static void Usage( vlc_t *p_this, const char *psz_module_name )
*/
#define LINE_START 8
#define PADDING_SPACES 25
module_t *p_module;
vlc_list_t *p_list;
module_t **pp_parser;
module_config_t *p_item;
char psz_spaces[PADDING_SPACES+LINE_START+1];
char psz_format[sizeof(FORMAT_STRING)];
......@@ -916,30 +915,34 @@ static void Usage( vlc_t *p_this, const char *psz_module_name )
ShowConsole();
#endif
/* List all modules */
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
/* Enumerate the config for each module */
for( p_module = p_this->p_vlc->p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
vlc_bool_t b_help_module = !strcmp( "help", p_module->psz_object_name );
vlc_bool_t b_help_module =
!strcmp( "help", (*pp_parser)->psz_object_name );
if( psz_module_name && strcmp( psz_module_name,
p_module->psz_object_name ) )
(*pp_parser)->psz_object_name ) )
{
continue;
}
/* Ignore modules without config options */
if( !p_module->i_config_items )
if( !(*pp_parser)->i_config_items )
{
continue;
}
/* Print module name */
fprintf( stderr, _("%s module options:\n\n"),
p_module->psz_object_name );
(*pp_parser)->psz_object_name );
for( p_item = p_module->p_config;
for( p_item = (*pp_parser)->p_config;
p_item->i_type != CONFIG_HINT_END;
p_item++ )
{
......@@ -1072,6 +1075,9 @@ static void Usage( vlc_t *p_this, const char *psz_module_name )
}
/* Release the module list */
vlc_list_release( p_list );
#ifdef WIN32 /* Pause the console because it's destroyed when we exit */
fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
getchar();
......@@ -1086,7 +1092,8 @@ static void Usage( vlc_t *p_this, const char *psz_module_name )
*****************************************************************************/
static void ListModules( vlc_t *p_this )
{
module_t *p_module;
vlc_list_t *p_list;
module_t **pp_parser;
char psz_spaces[22];
memset( psz_spaces, ' ', 22 );
......@@ -1101,24 +1108,26 @@ static void ListModules( vlc_t *p_this )
fprintf( stderr, _("[module] [description]\n") );
/* List all modules */
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
/* Enumerate each module */
for( p_module = p_this->p_vlc->p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
int i;
/* Nasty hack, but right now I'm too tired to think about a nice
* solution */
i = 22 - strlen( p_module->psz_object_name ) - 1;
i = 22 - strlen( (*pp_parser)->psz_object_name ) - 1;
if( i < 0 ) i = 0;
psz_spaces[i] = 0;
fprintf( stderr, " %s%s %s\n", p_module->psz_object_name, psz_spaces,
p_module->psz_longname );
fprintf( stderr, " %s%s %s\n", (*pp_parser)->psz_object_name,
psz_spaces, (*pp_parser)->psz_longname );
psz_spaces[i] = ' ';
}
#ifdef WIN32 /* Pause the console because it's destroyed when we exit */
......
......@@ -2,7 +2,7 @@
* configuration.c management of the modules configuration
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: configuration.c,v 1.36 2002/08/11 08:30:01 gbazin Exp $
* $Id: configuration.c,v 1.37 2002/08/15 12:11:15 sam Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -258,19 +258,26 @@ void __config_PutFloat( vlc_object_t *p_this,
* config_FindConfig: find the config structure associated with an option.
*****************************************************************************
* FIXME: This function really needs to be optimized.
* FIXME: And now even more.
*****************************************************************************/
module_config_t *config_FindConfig( vlc_object_t *p_this, const char *psz_name)
module_config_t *config_FindConfig( vlc_object_t *p_this, const char *psz_name )
{
module_t *p_module;
vlc_list_t *p_list;
module_t **pp_parser;
module_config_t *p_item;
if( !psz_name ) return NULL;
for( p_module = p_this->p_vlc->p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
for( p_item = p_module->p_config;
if( !(*pp_parser)->i_config_items )
continue;
for( p_item = (*pp_parser)->p_config;
p_item->i_type != CONFIG_HINT_END;
p_item++ )
{
......@@ -278,10 +285,15 @@ module_config_t *config_FindConfig( vlc_object_t *p_this, const char *psz_name)
/* ignore hints */
continue;
if( !strcmp( psz_name, p_item->psz_name ) )
{
vlc_list_release( p_list );
return p_item;
}
}
}
vlc_list_release( p_list );
return NULL;
}
......@@ -378,6 +390,11 @@ void config_Free( module_t *p_module )
module_config_t *p_item = p_module->p_config;
int i;
if( p_item == NULL )
{
return;
}
for( ; p_item->i_type != CONFIG_HINT_END ; p_item++ )
{
if( p_item->psz_type )
......@@ -446,21 +463,18 @@ void config_UnsetCallbacks( module_config_t *p_new )
*****************************************************************************/
int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{
module_t *p_module;
vlc_list_t *p_list;
module_t **pp_parser;
module_config_t *p_item;
FILE *file;
char line[1024];
char *p_index, *psz_option_name, *psz_option_value;
char *psz_filename, *psz_homedir;
/* Acquire config file lock */
vlc_mutex_lock( &p_this->p_vlc->config_lock );
psz_homedir = p_this->p_vlc->psz_homedir;
if( !psz_homedir )
{
msg_Err( p_this, "psz_homedir is null" );
vlc_mutex_unlock( &p_this->p_vlc->config_lock );
return -1;
}
psz_filename = (char *)malloc( strlen("/" CONFIG_DIR "/" CONFIG_FILE) +
......@@ -468,13 +482,15 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
if( !psz_filename )
{
msg_Err( p_this, "out of memory" );
vlc_mutex_unlock( &p_this->p_vlc->config_lock );
return -1;
}
sprintf( psz_filename, "%s/" CONFIG_DIR "/" CONFIG_FILE, psz_homedir );
msg_Dbg( p_this, "opening config file %s", psz_filename );
/* Acquire config file lock */
vlc_mutex_lock( &p_this->p_vlc->config_lock );
file = fopen( psz_filename, "rt" );
if( !file )
{
......@@ -485,12 +501,15 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
}
/* Look for the selected module, if NULL then save everything */
for( p_module = p_this->p_vlc->p_module_bank->first ; p_module != NULL ;
p_module = p_module->next )
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
if( psz_module_name
&& strcmp( psz_module_name, p_module->psz_object_name ) )
&& strcmp( psz_module_name, (*pp_parser)->psz_object_name ) )
{
continue;
}
......@@ -500,14 +519,15 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
rewind( file );
while( fgets( line, 1024, file ) )
{
if( (line[0] == '[') && (p_index = strchr(line,']')) &&
(p_index - &line[1] == strlen(p_module->psz_object_name) ) &&
!memcmp( &line[1], p_module->psz_object_name,
strlen(p_module->psz_object_name) ) )
if( (line[0] == '[')
&& (p_index = strchr(line,']'))
&& (p_index - &line[1] == strlen((*pp_parser)->psz_object_name))
&& !memcmp( &line[1], (*pp_parser)->psz_object_name,
strlen((*pp_parser)->psz_object_name) ) )
{
#if 0
msg_Dbg( p_this, "loading config for module \"%s\"",
p_module->psz_object_name );
(*pp_parser)->psz_object_name );
#endif
break;
......@@ -537,8 +557,13 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
*p_index = (char)0;
psz_option_value = p_index + 1;
if( !(*pp_parser)->i_config_items )
{
continue;
}
/* try to match this option with one of the module's options */
for( p_item = p_module->p_config;
for( p_item = (*pp_parser)->p_config;
p_item->i_type != CONFIG_HINT_END;
p_item++ )
{
......@@ -597,6 +622,8 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
}
vlc_list_release( p_list );
fclose( file );
free( psz_filename );
......@@ -626,7 +653,8 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
*****************************************************************************/
int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{
module_t *p_module;
module_t **pp_parser;
vlc_list_t *p_list;
module_config_t *p_item;
FILE *file;
char p_line[1024], *p_index2;
......@@ -694,6 +722,9 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
}
p_bigbuffer[0] = 0;
/* List all available modules */
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
/* backup file into memory, we only need to backup the sections we won't
* save later on */
b_backup = 0;
......@@ -701,25 +732,26 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{
if( (p_line[0] == '[') && (p_index2 = strchr(p_line,']')))
{
/* we found a section, check if we need to do a backup */
for( p_module = p_this->p_vlc->p_module_bank->first;
p_module != NULL;
p_module = p_module->next )
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
if( ((p_index2 - &p_line[1])
== strlen(p_module->psz_object_name) ) &&
!memcmp( &p_line[1], p_module->psz_object_name,
strlen(p_module->psz_object_name) ) )
== strlen((*pp_parser)->psz_object_name) ) &&
!memcmp( &p_line[1], (*pp_parser)->psz_object_name,
strlen((*pp_parser)->psz_object_name) ) )
{
if( !psz_module_name )
break;
else if( !strcmp( psz_module_name,
p_module->psz_object_name ) )
(*pp_parser)->psz_object_name ) )
break;
}
}
if( !p_module )
if( !(*pp_parser) )
{
/* we don't have this section in our list so we need to back
* it up */
......@@ -758,6 +790,7 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
msg_Warn( p_this, "could not open config file %s for writing",
psz_filename );
free( psz_filename );
vlc_list_release( p_list );
vlc_mutex_unlock( &p_this->p_vlc->config_lock );
return -1;
}
......@@ -765,27 +798,28 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
fprintf( file, "###\n### " COPYRIGHT_MESSAGE "\n###\n\n" );
/* Look for the selected module, if NULL then save everything */
for( p_module = p_this->p_vlc->p_module_bank->first ; p_module != NULL ;
p_module = p_module->next )
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
if( psz_module_name && strcmp( psz_module_name,
p_module->psz_object_name ) )
(*pp_parser)->psz_object_name ) )
continue;
if( !p_module->i_config_items )
if( !(*pp_parser)->i_config_items )
continue;
msg_Dbg( p_this, "saving config for module \"%s\"",
p_module->psz_object_name );
(*pp_parser)->psz_object_name );
fprintf( file, "[%s]", p_module->psz_object_name );
if( p_module->psz_longname )
fprintf( file, " # %s\n\n", p_module->psz_longname );
fprintf( file, "[%s]", (*pp_parser)->psz_object_name );
if( (*pp_parser)->psz_longname )
fprintf( file, " # %s\n\n", (*pp_parser)->psz_longname );
else
fprintf( file, "\n\n" );
for( p_item = p_module->p_config;
for( p_item = (*pp_parser)->p_config;
p_item->i_type != CONFIG_HINT_END;
p_item++ )
{
......@@ -824,6 +858,7 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
fprintf( file, "\n" );
}
vlc_list_release( p_list );
/*
* Restore old settings from the config in file
......@@ -851,7 +886,8 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
vlc_bool_t b_ignore_errors )
{
int i_cmd, i_index, i_opts, i_shortopts, flag;
module_t *p_module;
module_t **pp_parser;
vlc_list_t *p_list;
module_config_t *p_item;
struct option *p_longopts;
......@@ -885,25 +921,30 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
}
#endif
/* List all modules */
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
/*
* Generate the longopts and shortopts structures used by getopt_long
*/
i_opts = 0;
for( p_module = p_this->p_vlc->p_module_bank->first;
p_module != NULL ;
p_module = p_module->next )
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
/* count the number of exported configuration options (to allocate
* longopts). We also need to allocate space for too options when
* dealing with boolean to allow for --foo and --no-foo */
i_opts += (p_module->i_config_items + 2 * p_module->i_bool_items);
i_opts += (*pp_parser)->i_config_items
+ 2 * (*pp_parser)->i_bool_items;
}
p_longopts = malloc( sizeof(struct option) * (i_opts + 1) );
if( p_longopts == NULL )
{
msg_Err( p_this, "out of memory" );
vlc_list_release( p_list );
return -1;
}
......@@ -912,6 +953,7 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
{
msg_Err( p_this, "out of memory" );
free( p_longopts );
vlc_list_release( p_list );
return -1;
}
......@@ -926,6 +968,7 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
msg_Err( p_this, "out of memory" );
free( psz_shortopts );
free( p_longopts );
vlc_list_release( p_list );
return -1;
}
memcpy( ppsz_argv, p_this->p_vlc->ppsz_argv,
......@@ -940,11 +983,14 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
/* Fill the p_longopts and psz_shortopts structures */
i_index = 0;
for( p_module = p_this->p_vlc->p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
for( pp_parser = (module_t **)p_list->pp_objects ;
*pp_parser ;
pp_parser++ )
{
for( p_item = p_module->p_config;
if( !(*pp_parser)->i_config_items )
continue;
for( p_item = (*pp_parser)->p_config;
p_item->i_type != CONFIG_HINT_END;
p_item++ )
{
......@@ -1004,6 +1050,9 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
}
}
/* We don't need the module list anymore */
vlc_list_release( p_list );
/* Close the longopts and shortopts structures */
memset( &p_longopts[i_index], 0, sizeof(struct option) );
psz_shortopts[i_shortopts] = '\0';
......
......@@ -2,7 +2,7 @@
* modules.c : Builtin and plugin modules management functions
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: modules.c,v 1.86 2002/08/14 17:06:53 sam Exp $
* $Id: modules.c,v 1.87 2002/08/15 12:11:15 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Ethan C. Baldridge <BaldridgeE@cadmus.com>
......@@ -96,10 +96,7 @@ static int AllocatePluginFile ( vlc_object_t *, char * );
#endif
static int AllocateBuiltinModule( vlc_object_t *, int ( * ) ( module_t * ) );
static int DeleteModule ( module_t * );
static int LockModule ( module_t * );
static int UnlockModule ( module_t * );
#ifdef HAVE_DYNAMIC_PLUGINS
static int HideModule ( module_t * );
static void DupModule ( module_t * );
static void UndupModule ( module_t * );
static int CallEntry ( module_t * );
......@@ -118,10 +115,6 @@ void __module_InitBank( vlc_object_t *p_this )
p_bank = vlc_object_create( p_this, sizeof(module_bank_t) );
p_bank->psz_object_name = "module bank";
p_bank->first = NULL;
p_bank->i_count = 0;
vlc_mutex_init( p_this, &p_bank->lock );
/*
* Store the symbols to be exported
*/
......@@ -160,25 +153,22 @@ void __module_EndBank( vlc_object_t *p_this )
vlc_object_detach( p_this->p_vlc->p_module_bank );
while( p_this->p_vlc->p_module_bank->first != NULL )
while( p_this->p_vlc->p_module_bank->i_children )
{
if( DeleteModule( p_this->p_vlc->p_module_bank->first ) )
p_next = (module_t *)p_this->p_vlc->p_module_bank->pp_children[0];
if( DeleteModule( p_next ) )
{
/* Module deletion failed */
msg_Err( p_this, "module \"%s\" can't be removed, trying harder",
p_this->p_vlc->p_module_bank->first->psz_object_name );
p_next->psz_object_name );
/* We just free the module by hand. Niahahahahaha. */
p_next = p_this->p_vlc->p_module_bank->first->next;
vlc_object_detach( p_this->p_vlc->p_module_bank->first );
vlc_object_destroy( p_this->p_vlc->p_module_bank->first );
p_this->p_vlc->p_module_bank->first = p_next;
vlc_object_detach( p_next );
vlc_object_destroy( p_next );
}
}
/* Destroy the lock */
vlc_mutex_destroy( &p_this->p_vlc->p_module_bank->lock );
vlc_object_destroy( p_this->p_vlc->p_module_bank );
return;
......@@ -221,51 +211,6 @@ void __module_LoadPlugins( vlc_object_t * p_this )
#endif
}
/*****************************************************************************
* module_ManageBank: manage the module bank.
*****************************************************************************
* This function parses the module bank and hides modules that have been
* unused for a while.
*****************************************************************************/
void __module_ManageBank( vlc_object_t *p_this )
{
#ifdef HAVE_DYNAMIC_PLUGINS
module_t * p_module;
/* We take the global lock */
vlc_mutex_lock( &p_this->p_vlc->p_module_bank->lock );
/* Parse the module list to see if any modules need to be unloaded */
for( p_module = p_this->p_vlc->p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
{
/* If the module is unused and if it is a plugin module... */
if( p_module->i_usage == 0 && !p_module->b_builtin )
{
if( p_module->i_unused_delay < MODULE_HIDE_DELAY )
{
p_module->i_unused_delay++;
}
else
{
msg_Dbg( p_this, "hiding unused plugin module \"%s\"",
p_module->psz_object_name );
HideModule( p_module );
/* Break here, so that we only hide one module at a time */
break;
}
}
}
/* We release the global lock */
vlc_mutex_unlock( &p_this->p_vlc->p_module_bank->lock );
#endif /* HAVE_DYNAMIC_PLUGINS */
return;
}
/*****************************************************************************
* module_Need: return the best module function, given a capability list.
*****************************************************************************
......@@ -284,11 +229,13 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
};
module_list_t *p_list, *p_first, *p_tmp;
vlc_list_t *p_all;
int i_index = 0;
vlc_bool_t b_intf = VLC_FALSE;
module_t *p_module;
module_t **pp_parser;
int i_shortcuts = 0;
char *psz_shortcuts = NULL, *psz_var = NULL;
......@@ -327,22 +274,19 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
}
}
/* We take the global lock */
vlc_mutex_lock( &p_this->p_vlc->p_module_bank->lock );
/* Sort the modules and test them */
p_list = malloc( p_this->p_vlc->p_module_bank->i_count
* sizeof( module_list_t ) );
p_all = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
p_list = malloc( p_all->i_count * sizeof( module_list_t ) );
p_first = NULL;
/* Parse the module list for capabilities and probe each of them */
for( p_module = p_this->p_vlc->p_module_bank->first ;
p_module != NULL ;
p_module = p_module->next )
for( pp_parser = (module_t**)p_all->pp_objects ; *pp_parser ; pp_parser++ )
{
module_t * p_submodule = NULL;
int i_shortcut_bonus = 0, i_submodule;
p_module = *pp_parser;
/* Test that this module can do what we need */
if( strcmp( p_module->psz_capability, psz_capability ) )
{
......@@ -476,16 +420,16 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
msg_Dbg( p_this, "probing %i candidate%s",
i_index, i_index == 1 ? "" : "s" );
/* Lock all selected modules */
/* Lock all candidate modules */
p_tmp = p_first;
while( p_tmp != NULL )
{
LockModule( p_tmp->p_module );
vlc_object_yield( p_tmp->p_module );
p_tmp = p_tmp->p_next;
}
/* We can release the global lock, module refcounts were incremented */
vlc_mutex_unlock( &p_this->p_vlc->p_module_bank->lock );
/* We can release the list, interesting modules were yielded */
vlc_list_release( p_all );
/* Parse the linked list and use the first successful module */
p_tmp = p_first;
......@@ -497,7 +441,7 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
break;
}
UnlockModule( p_tmp->p_module );
vlc_object_release( p_tmp->p_module );
p_tmp = p_tmp->p_next;
}
......@@ -515,7 +459,7 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
/* Unlock the remaining modules */
while( p_tmp != NULL )
{
UnlockModule( p_tmp->p_module );
vlc_object_release( p_tmp->p_module );
p_tmp = p_tmp->p_next;
}
......@@ -565,17 +509,9 @@ void __module_Unneed( vlc_object_t * p_this, module_t * p_module )
p_module->pf_deactivate( p_this );
}
/* We take the global lock */
vlc_mutex_lock( &p_module->p_vlc->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 );
msg_Info( p_module, "unlocking module \"%s\"", p_module->psz_object_name );
/* We release the global lock */
vlc_mutex_unlock( &p_module->p_vlc->p_module_bank->lock );
vlc_object_release( p_module );
return;
}
......@@ -711,8 +647,8 @@ static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir,
* AllocatePluginFile: load a module into memory and initialize it.
*****************************************************************************
* 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 DeleteModule.
* for its information data. The module can then be handled by module_Need
* and module_Unneed. It can be removed by DeleteModule.
*****************************************************************************/
static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file )
{
......@@ -760,21 +696,8 @@ static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file )
p_module->psz_longname = strdup( p_module->psz_longname );
/* Everything worked fine ! The module is ready to be added to the list. */
p_module->i_usage = 0;
p_module->i_unused_delay = 0;
p_module->b_builtin = VLC_FALSE;
/* Link module into the linked list */
if( p_this->p_vlc->p_module_bank->first != NULL )
{
p_this->p_vlc->p_module_bank->first->prev = p_module;
}
p_module->next = p_this->p_vlc->p_module_bank->first;
p_module->prev = NULL;
p_this->p_vlc->p_module_bank->first = p_module;
p_this->p_vlc->p_module_bank->i_count++;
/* msg_Dbg( p_this, "plugin \"%s\", %s",
p_module->psz_object_name, p_module->psz_longname ); */
......@@ -850,8 +773,8 @@ static void UndupModule( module_t *p_module )
* AllocateBuiltinModule: initialize a builtin module.
*****************************************************************************
* This function registers a builtin 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 DeleteModule.
* for its information data. The module can then be handled by module_Need
* and module_Unneed. It can be removed by DeleteModule.
*****************************************************************************/
static int AllocateBuiltinModule( vlc_object_t * p_this,
int ( *pf_entry ) ( module_t * ) )
......@@ -878,21 +801,8 @@ static int AllocateBuiltinModule( vlc_object_t * p_this,
}
/* Everything worked fine ! The module is ready to be added to the list. */
p_module->i_usage = 0;
p_module->i_unused_delay = 0;
p_module->b_builtin = VLC_TRUE;
/* Link module into the linked list */
if( p_this->p_vlc->p_module_bank->first != NULL )
{
p_this->p_vlc->p_module_bank->first->prev = p_module;
}
p_module->next = p_this->p_vlc->p_module_bank->first;
p_module->prev = NULL;
p_this->p_vlc->p_module_bank->first = p_module;
p_this->p_vlc->p_module_bank->i_count++;
/* msg_Dbg( p_this, "builtin \"%s\", %s",
p_module->psz_object_name, p_module->psz_longname ); */
......@@ -904,68 +814,17 @@ static int AllocateBuiltinModule( vlc_object_t * p_this,
/*****************************************************************************
* DeleteModule: delete a module and its structure.
*****************************************************************************
* This function can only be called if i_usage <= 0.
* This function can only be called if the module isn't being used.
*****************************************************************************/
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
* data structure. */
if( p_module->b_builtin )
{
if( p_module->i_usage != 0 )
{
msg_Err( p_module, "trying to free builtin module \"%s\" with "
"usage %i", p_module->psz_object_name, p_module->i_usage );
return -1;
}
}
#ifdef HAVE_DYNAMIC_PLUGINS
else
{
if( p_module->i_usage >= 1 )
{
msg_Err( p_module, "trying to free module \"%s\" which is "
"still in use", p_module->psz_object_name );
return -1;
}
/* Two possibilities here: i_usage == -1 and the module is already
* unloaded, we can continue, or i_usage == 0, and we have to hide
* the module before going on. */
if( p_module->i_usage == 0 )
{
if( HideModule( p_module ) != 0 )
{
return -1;
}
}
}
#endif
vlc_object_detach( p_module );
/* Unlink the module from the linked list. */
if( p_module->prev != NULL )
{
p_module->prev->next = p_module->next;
}
else
{
p_module->p_vlc->p_module_bank->first = p_module->next;
}
if( p_module->next != NULL )
{
p_module->next->prev = p_module->prev;
}
p_module->p_vlc->p_module_bank->i_count--;
/* We free the structures that we strdup()ed in Allocate*Module(). */
#ifdef HAVE_DYNAMIC_PLUGINS
if( !p_module->b_builtin )
{
module_unload( p_module->handle );
UndupModule( p_module );
free( p_module->psz_filename );
free( p_module->psz_longname );
......@@ -986,125 +845,7 @@ static int DeleteModule( module_t * p_module )
return 0;
}
/*****************************************************************************
* LockModule: increase the usage count of a module and load it if needed.
*****************************************************************************
* This function has to be called before a thread starts using a module. If
* the module is already loaded, we just increase its usage count. If it isn't
* loaded, we have to dynamically open it and initialize it.
* If you successfully call LockModule() at any moment, be careful to call
* UnlockModule() when you don't need it anymore.
*****************************************************************************/
static int LockModule( module_t * p_module )
{
if( p_module->i_usage >= 0 )
{
/* This module is already loaded and activated, we can return */
p_module->i_usage++;
return 0;
}
if( p_module->b_builtin )
{
/* A builtin module should always have a refcount >= 0 ! */
msg_Err( p_module, "builtin module \"%s\" has refcount %i",
p_module->psz_object_name, p_module->i_usage );
return -1;
}
#ifdef HAVE_DYNAMIC_PLUGINS
if( p_module->i_usage != -1 )
{
/* This shouldn't happen. Ever. We have serious problems here. */
msg_Err( p_module, "plugin module \"%s\" has refcount %i",
p_module->psz_object_name, p_module->i_usage );
return -1;
}
/* i_usage == -1, which means that the module isn't in memory */
if( module_load( p_module->psz_filename, &p_module->handle ) )
{
char psz_buffer[256];
/* The plugin module couldn't be opened */
msg_Err( p_module, "cannot open `%s' (%s)",
p_module->psz_filename, module_error(psz_buffer) );
return -1;
}
/* FIXME: what to do if the guy modified the plugin while it was
* unloaded ? It makes XMMS crash nastily, perhaps we should try
* to be a bit more clever here. */
/* Everything worked fine ! The module is ready to be used */
p_module->i_usage = 1;
#endif /* HAVE_DYNAMIC_PLUGINS */
return 0;
}
/*****************************************************************************
* UnlockModule: decrease the usage count of a module.
*****************************************************************************
* We decrease the usage count of a module so that we know when a module
* becomes unused and can be hidden.
*****************************************************************************/
static int UnlockModule( module_t * p_module )
{
if( p_module->i_usage <= 0 )
{
/* This shouldn't happen. Ever. We have serious problems here. */
msg_Err( p_module, "trying to call module_Unneed() on \"%s\" "
"which is not in use", p_module->psz_object_name );
return -1;
}
/* This module is still in use, we can return */
p_module->i_usage--;
p_module->i_unused_delay = 0;
return 0;
}
#ifdef HAVE_DYNAMIC_PLUGINS
/*****************************************************************************
* HideModule: remove a module from memory but keep its structure.
*****************************************************************************
* This function can only be called if i_usage == 0. It will make a call
* to the module's inner module_deactivate() symbol, and then unload it
* from memory. A call to module_Need() will automagically load it again.
*****************************************************************************/
static int HideModule( module_t * p_module )
{
if( p_module->b_builtin )
{
/* A builtin module should never be hidden. */
msg_Err( p_module, "trying to hide builtin module \"%s\"",
p_module->psz_object_name );
return -1;
}
if( p_module->i_usage >= 1 )
{
msg_Err( p_module, "trying to hide module \"%s\" which is still "
"in use", p_module->psz_object_name );
return -1;
}
if( p_module->i_usage <= -1 )
{
msg_Err( p_module, "trying to hide module \"%s\" which is already "
"hidden", p_module->psz_object_name );
return -1;
}
/* Everything worked fine, we can safely unload the module. */
module_unload( p_module->handle );
p_module->i_usage = -1;
return 0;
}
/*****************************************************************************
* CallEntry: call an entry point.
*****************************************************************************
......
......@@ -304,7 +304,7 @@ static const char * module_error( char *psz_buffer )
(p_symbols)->__vlc_object_yield_inner = __vlc_object_yield; \
(p_symbols)->__vlc_object_release_inner = __vlc_object_release; \
(p_symbols)->__vlc_list_find_inner = __vlc_list_find; \
(p_symbols)->__vlc_list_release_inner = __vlc_list_release; \
(p_symbols)->vlc_list_release_inner = vlc_list_release; \
(p_symbols)->__vlc_liststructure_inner = __vlc_liststructure; \
(p_symbols)->__vlc_dumpstructure_inner = __vlc_dumpstructure; \
(p_symbols)->playlist_Command_inner = playlist_Command; \
......
......@@ -2,7 +2,7 @@
* objects.c: vlc_object_t handling
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: objects.c,v 1.18 2002/08/14 17:06:53 sam Exp $
* $Id: objects.c,v 1.19 2002/08/15 12:11:15 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -410,9 +410,8 @@ vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode )
/*****************************************************************************
* vlc_liststructure: print the current vlc objects
*****************************************************************************
* This function prints an ASCII tree showing the connections between vlc
* objects, and additional information such as their refcount, thread ID,
* address, etc.
* This function prints alist of vlc objects, and additional information such
* as their refcount, thread ID, etc.
*****************************************************************************/
void __vlc_liststructure( vlc_object_t *p_this )
{
......@@ -444,8 +443,7 @@ void __vlc_liststructure( vlc_object_t *p_this )
* vlc_dumpstructure: print the current vlc structure
*****************************************************************************
* This function prints an ASCII tree showing the connections between vlc
* objects, and additional information such as their refcount, thread ID,
* address, etc.
* objects, and additional information such as their refcount, thread ID, etc.
*****************************************************************************/
void __vlc_dumpstructure( vlc_object_t *p_this )
{
......@@ -463,19 +461,23 @@ void __vlc_dumpstructure( vlc_object_t *p_this )
* This function decreases the refcount of all objects in the list and
* frees the list.
*****************************************************************************/
void __vlc_list_release( vlc_object_t *p_this, vlc_list_t *p_list )
void vlc_list_release( vlc_list_t *p_list )
{
vlc_object_t **p_current = p_list->pp_objects;
if( p_list->i_count )
{
vlc_t * p_vlc = p_list->pp_objects[0]->p_vlc;
vlc_object_t ** pp_current = p_list->pp_objects;
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_vlc->structure_lock );
while( p_current[0] )
{
p_current[0]->i_refcount--;
p_current++;
}
while( pp_current[0] )
{
pp_current[0]->i_refcount--;
pp_current++;
}
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_vlc->structure_lock );
}
free( p_list );
}
......
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