When scanning multiple lua scripts, create a new lua_State for each script. This will prevent data corruption from a previous script affecting subsequent scripts.

This commit is contained in:
Antoine Cellerier 2010-02-13 14:07:30 +01:00
parent 39852e8bdf
commit 5942b165dd
6 changed files with 65 additions and 76 deletions

View File

@ -116,18 +116,36 @@ static const luaL_Reg p_reg_parse[] =
* the script pointed by psz_filename.
*****************************************************************************/
static int probe_luascript( vlc_object_t *p_this, const char * psz_filename,
lua_State * L, void * user_data )
void * user_data )
{
VLC_UNUSED(user_data);
demux_t * p_demux = (demux_t *)p_this;
p_demux->p_sys->psz_filename = strdup(psz_filename);
/* In lua, setting a variable's value to nil is equivalent to deleting it */
lua_pushnil( L );
lua_pushnil( L );
lua_setglobal( L, "probe" );
lua_setglobal( L, "parse" );
/* Initialise Lua state structure */
lua_State *L = luaL_newstate();
if( !L )
{
msg_Err( p_demux, "Could not create new Lua State" );
goto error;
}
p_demux->p_sys->L = L;
/* Load Lua libraries */
luaL_openlibs( L ); /* FIXME: Don't open all the libs? */
luaL_register( L, "vlc", p_reg );
luaopen_msg( L );
luaopen_strings( L );
lua_pushlightuserdata( L, p_demux );
lua_setfield( L, -2, "private" );
lua_pushstring( L, p_demux->psz_path );
lua_setfield( L, -2, "path" );
lua_pushstring( L, p_demux->psz_access );
lua_setfield( L, -2, "access" );
lua_pop( L, 1 );
/* Load and run the script(s) */
if( luaL_dofile( L, psz_filename ) )
@ -167,6 +185,8 @@ static int probe_luascript( vlc_object_t *p_this, const char * psz_filename,
error:
lua_pop( L, 1 );
lua_close( p_demux->p_sys->L );
p_demux->p_sys->L = NULL;
FREENULL( p_demux->p_sys->psz_filename );
return VLC_EGENERIC;
}
@ -191,33 +211,8 @@ int Import_LuaPlaylist( vlc_object_t *p_this )
p_demux->pf_control = Control;
p_demux->pf_demux = Demux;
/* Initialise Lua state structure */
L = luaL_newstate();
if( !L )
{
msg_Err( p_demux, "Could not create new Lua State" );
free( p_demux->p_sys );
return VLC_EGENERIC;
}
p_demux->p_sys->L = L;
/* Load Lua libraries */
luaL_openlibs( L ); /* FIXME: Don't open all the libs? */
luaL_register( L, "vlc", p_reg );
luaopen_msg( L );
luaopen_strings( L );
lua_pushlightuserdata( L, p_demux );
lua_setfield( L, -2, "private" );
lua_pushstring( L, p_demux->psz_path );
lua_setfield( L, -2, "path" );
lua_pushstring( L, p_demux->psz_access );
lua_setfield( L, -2, "access" );
lua_pop( L, 1 );
ret = vlclua_scripts_batch_execute( p_this, "playlist",
&probe_luascript, L, NULL );
&probe_luascript, NULL );
if( ret )
Close_LuaPlaylist( p_this );
return ret;
@ -230,7 +225,8 @@ int Import_LuaPlaylist( vlc_object_t *p_this )
void Close_LuaPlaylist( vlc_object_t *p_this )
{
demux_t *p_demux = (demux_t *)p_this;
lua_close( p_demux->p_sys->L );
if( p_demux->p_sys->L )
lua_close( p_demux->p_sys->L );
free( p_demux->p_sys->psz_filename );
free( p_demux->p_sys );
}

View File

@ -54,7 +54,7 @@ const char* const ppsz_capabilities[] = {
static int ScanExtensions( extensions_manager_t *p_this );
static int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script,
lua_State *L, void *pb_continue );
void *pb_continue );
static int Control( extensions_manager_t *, int, va_list );
static int GetMenuEntries( extensions_manager_t *p_mgr, extension_t *p_ext,
char ***pppsz_titles, uint16_t **ppi_ids );
@ -99,15 +99,6 @@ int Open_Extension( vlc_object_t *p_this )
vlc_mutex_init( &p_mgr->lock );
vlc_mutex_init( &p_mgr->p_sys->lock );
/* Initialise Lua state structure */
lua_State *L = GetLuaState( p_mgr, NULL );
if( !L )
{
free( p_sys );
return VLC_EGENERIC;
}
p_sys->L = L;
/* Scan available Lua Extensions */
if( ScanExtensions( p_mgr ) != VLC_SUCCESS )
{
@ -115,9 +106,6 @@ int Open_Extension( vlc_object_t *p_this )
return VLC_EGENERIC;
}
lua_close( L );
p_sys->L = NULL;
// Create the dialog-event variable
var_Create( p_this, "dialog-event", VLC_VAR_ADDRESS );
var_AddCallback( p_this, "dialog-event",
@ -153,9 +141,6 @@ void Close_Extension( vlc_object_t *p_this )
msg_Dbg( p_mgr, "All extensions are now deactivated" );
ARRAY_RESET( p_mgr->p_sys->activated_extensions );
if( p_mgr->p_sys && p_mgr->p_sys->L )
lua_close( p_mgr->p_sys->L );
vlc_mutex_destroy( &p_mgr->lock );
vlc_mutex_destroy( &p_mgr->p_sys->lock );
free( p_mgr->p_sys );
@ -199,7 +184,7 @@ static int ScanExtensions( extensions_manager_t *p_mgr )
vlclua_scripts_batch_execute( VLC_OBJECT( p_mgr ),
"extensions",
&ScanLuaCallback,
p_mgr->p_sys->L, &b_true );
&b_true );
if( !i_ret )
return VLC_EGENERIC;
@ -215,7 +200,7 @@ static int ScanExtensions( extensions_manager_t *p_mgr )
* @param pb_continue bool* that indicates whether to continue batch or not
**/
int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script,
lua_State *L, void *pb_continue )
void *pb_continue )
{
extensions_manager_t *p_mgr = ( extensions_manager_t* ) p_this;
bool b_ok = false;
@ -250,6 +235,7 @@ int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script,
vlc_cond_init( &p_ext->p_sys->wait );
/* Load and run the script(s) */
lua_State *L = luaL_newstate();
if( luaL_dofile( L, psz_script ) )
{
msg_Warn( p_mgr, "Error loading script %s: %s", psz_script,
@ -414,6 +400,7 @@ int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script,
b_ok = true;
exit:
lua_close( L );
if( !b_ok )
{
free( p_ext->psz_name );

View File

@ -48,9 +48,6 @@ struct extensions_manager_sys_t
/* Lock for this list */
vlc_mutex_t lock;
/* Lua specific */
lua_State *L;
/* Flag indicating that the module is about to be unloaded */
bool b_killed;
};

View File

@ -126,14 +126,19 @@ error:
* pointed by psz_filename.
*****************************************************************************/
static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
lua_State * L, void * user_data )
void * user_data )
{
input_item_t * p_input = user_data;
input_item_t * p_item = user_data;
int s;
lua_State *L = init( p_this, p_item );
int i_ret = run(p_this, psz_filename, L, "fetch_art");
if(i_ret != VLC_SUCCESS)
{
lua_close( L );
return i_ret;
}
if((s = lua_gettop( L )))
{
@ -145,7 +150,8 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
if( psz_value && *psz_value != 0 )
{
lua_Dbg( p_this, "setting arturl: %s", psz_value );
input_item_SetArtURL ( p_input, psz_value );
input_item_SetArtURL ( p_item, psz_value );
lua_close( L );
return VLC_SUCCESS;
}
}
@ -160,6 +166,7 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
msg_Err( p_this, "Script went completely foobar" );
}
lua_close( L );
return VLC_EGENERIC;
}
@ -168,15 +175,20 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
* pointed by psz_filename.
*****************************************************************************/
static int read_meta( vlc_object_t *p_this, const char * psz_filename,
lua_State * L, void * user_data )
void * user_data )
{
VLC_UNUSED(user_data);
input_item_t * p_item = user_data;
lua_State *L = init( p_this, p_item );
int i_ret = run(p_this, psz_filename, L, "read_meta");
if(i_ret != VLC_SUCCESS)
{
lua_close( L );
return i_ret;
}
// Continue, all "meta reader" are always run.
lua_close( L );
return 1;
}
@ -186,11 +198,15 @@ static int read_meta( vlc_object_t *p_this, const char * psz_filename,
* pointed by psz_filename.
*****************************************************************************/
static int fetch_meta( vlc_object_t *p_this, const char * psz_filename,
lua_State * L, void * user_data )
void * user_data )
{
VLC_UNUSED(user_data);
input_item_t * p_item = user_data;
lua_State *L = init( p_this, p_item );
return run(p_this, psz_filename, L, "fetch_meta");
int ret = run(p_this, psz_filename, L, "fetch_meta");
lua_close( L );
return ret;
}
/*****************************************************************************
@ -202,9 +218,7 @@ int ReadMeta( vlc_object_t *p_this )
demux_meta_t *p_demux_meta = (demux_meta_t *)p_this;
input_item_t *p_item = p_demux_meta->p_item;
lua_State *L = init( p_this, p_item );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/reader", &read_meta, L, NULL );
lua_close( L );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/reader", &read_meta, p_item );
return i_ret;
}
@ -219,9 +233,7 @@ int FetchMeta( vlc_object_t *p_this )
demux_meta_t *p_demux_meta = (demux_meta_t *)p_this;
input_item_t *p_item = p_demux_meta->p_item;
lua_State *L = init( p_this, p_item );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/fetcher", &fetch_meta, L, NULL );
lua_close( L );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/fetcher", &fetch_meta, p_item );
return i_ret;
}
@ -235,9 +247,7 @@ int FindArt( vlc_object_t *p_this )
art_finder_t *p_finder = (art_finder_t *)p_this;
input_item_t *p_item = p_finder->p_item;
lua_State *L = init( p_this, p_item );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/art", &fetch_art, L, p_item );
lua_close( L );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/art", &fetch_art, p_item );
return i_ret;
}

View File

@ -202,8 +202,7 @@ void vlclua_dir_list_free( char **ppsz_dir_list )
*****************************************************************************/
int vlclua_scripts_batch_execute( vlc_object_t *p_this,
const char * luadirname,
int (*func)(vlc_object_t *, const char *, lua_State *, void *),
lua_State * L,
int (*func)(vlc_object_t *, const char *, void *),
void * user_data)
{
char *ppsz_dir_list[] = { NULL, NULL, NULL, NULL };
@ -240,7 +239,7 @@ int vlclua_scripts_batch_execute( vlc_object_t *p_this,
{
msg_Dbg( p_this, "Trying Lua playlist script %s",
psz_filename );
i_ret = func( p_this, psz_filename, L, user_data );
i_ret = func( p_this, psz_filename, user_data );
free( psz_filename );
if( i_ret == VLC_SUCCESS )
break;

View File

@ -104,8 +104,8 @@ int vlclua_push_ret( lua_State *, int i_error );
* success.
*****************************************************************************/
int vlclua_scripts_batch_execute( vlc_object_t *p_this, const char * luadirname,
int (*func)(vlc_object_t *, const char *, lua_State *, void *),
lua_State * L, void * user_data );
int (*func)(vlc_object_t *, const char *, void *),
void * user_data );
int vlclua_dir_list( vlc_object_t *p_this, const char *luadirname, char **ppsz_dir_list );
void vlclua_dir_list_free( char **ppsz_dir_list );
char *vlclua_find_file( vlc_object_t *p_this, const char *psz_luadirname, const char *psz_name );