Commit 5942b165 authored by Antoine Cellerier's avatar Antoine Cellerier

When scanning multiple lua scripts, create a new lua_State for each script....

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.
parent 39852e8b
...@@ -116,18 +116,36 @@ static const luaL_Reg p_reg_parse[] = ...@@ -116,18 +116,36 @@ static const luaL_Reg p_reg_parse[] =
* the script pointed by psz_filename. * the script pointed by psz_filename.
*****************************************************************************/ *****************************************************************************/
static int probe_luascript( vlc_object_t *p_this, const char * 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); VLC_UNUSED(user_data);
demux_t * p_demux = (demux_t *)p_this; demux_t * p_demux = (demux_t *)p_this;
p_demux->p_sys->psz_filename = strdup(psz_filename); p_demux->p_sys->psz_filename = strdup(psz_filename);
/* In lua, setting a variable's value to nil is equivalent to deleting it */ /* Initialise Lua state structure */
lua_pushnil( L ); lua_State *L = luaL_newstate();
lua_pushnil( L ); if( !L )
lua_setglobal( L, "probe" ); {
lua_setglobal( L, "parse" ); 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) */ /* Load and run the script(s) */
if( luaL_dofile( L, psz_filename ) ) if( luaL_dofile( L, psz_filename ) )
...@@ -167,6 +185,8 @@ static int probe_luascript( vlc_object_t *p_this, const char * psz_filename, ...@@ -167,6 +185,8 @@ static int probe_luascript( vlc_object_t *p_this, const char * psz_filename,
error: error:
lua_pop( L, 1 ); lua_pop( L, 1 );
lua_close( p_demux->p_sys->L );
p_demux->p_sys->L = NULL;
FREENULL( p_demux->p_sys->psz_filename ); FREENULL( p_demux->p_sys->psz_filename );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -191,33 +211,8 @@ int Import_LuaPlaylist( vlc_object_t *p_this ) ...@@ -191,33 +211,8 @@ int Import_LuaPlaylist( vlc_object_t *p_this )
p_demux->pf_control = Control; p_demux->pf_control = Control;
p_demux->pf_demux = Demux; 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", ret = vlclua_scripts_batch_execute( p_this, "playlist",
&probe_luascript, L, NULL ); &probe_luascript, NULL );
if( ret ) if( ret )
Close_LuaPlaylist( p_this ); Close_LuaPlaylist( p_this );
return ret; return ret;
...@@ -230,7 +225,8 @@ int Import_LuaPlaylist( vlc_object_t *p_this ) ...@@ -230,7 +225,8 @@ int Import_LuaPlaylist( vlc_object_t *p_this )
void Close_LuaPlaylist( vlc_object_t *p_this ) void Close_LuaPlaylist( vlc_object_t *p_this )
{ {
demux_t *p_demux = (demux_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->psz_filename );
free( p_demux->p_sys ); free( p_demux->p_sys );
} }
......
...@@ -54,7 +54,7 @@ const char* const ppsz_capabilities[] = { ...@@ -54,7 +54,7 @@ const char* const ppsz_capabilities[] = {
static int ScanExtensions( extensions_manager_t *p_this ); static int ScanExtensions( extensions_manager_t *p_this );
static int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script, 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 Control( extensions_manager_t *, int, va_list );
static int GetMenuEntries( extensions_manager_t *p_mgr, extension_t *p_ext, static int GetMenuEntries( extensions_manager_t *p_mgr, extension_t *p_ext,
char ***pppsz_titles, uint16_t **ppi_ids ); char ***pppsz_titles, uint16_t **ppi_ids );
...@@ -99,15 +99,6 @@ int Open_Extension( vlc_object_t *p_this ) ...@@ -99,15 +99,6 @@ int Open_Extension( vlc_object_t *p_this )
vlc_mutex_init( &p_mgr->lock ); vlc_mutex_init( &p_mgr->lock );
vlc_mutex_init( &p_mgr->p_sys->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 */ /* Scan available Lua Extensions */
if( ScanExtensions( p_mgr ) != VLC_SUCCESS ) if( ScanExtensions( p_mgr ) != VLC_SUCCESS )
{ {
...@@ -115,9 +106,6 @@ int Open_Extension( vlc_object_t *p_this ) ...@@ -115,9 +106,6 @@ int Open_Extension( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
lua_close( L );
p_sys->L = NULL;
// Create the dialog-event variable // Create the dialog-event variable
var_Create( p_this, "dialog-event", VLC_VAR_ADDRESS ); var_Create( p_this, "dialog-event", VLC_VAR_ADDRESS );
var_AddCallback( p_this, "dialog-event", var_AddCallback( p_this, "dialog-event",
...@@ -153,9 +141,6 @@ void Close_Extension( vlc_object_t *p_this ) ...@@ -153,9 +141,6 @@ void Close_Extension( vlc_object_t *p_this )
msg_Dbg( p_mgr, "All extensions are now deactivated" ); msg_Dbg( p_mgr, "All extensions are now deactivated" );
ARRAY_RESET( p_mgr->p_sys->activated_extensions ); 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->lock );
vlc_mutex_destroy( &p_mgr->p_sys->lock ); vlc_mutex_destroy( &p_mgr->p_sys->lock );
free( p_mgr->p_sys ); free( p_mgr->p_sys );
...@@ -199,7 +184,7 @@ static int ScanExtensions( extensions_manager_t *p_mgr ) ...@@ -199,7 +184,7 @@ static int ScanExtensions( extensions_manager_t *p_mgr )
vlclua_scripts_batch_execute( VLC_OBJECT( p_mgr ), vlclua_scripts_batch_execute( VLC_OBJECT( p_mgr ),
"extensions", "extensions",
&ScanLuaCallback, &ScanLuaCallback,
p_mgr->p_sys->L, &b_true ); &b_true );
if( !i_ret ) if( !i_ret )
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -215,7 +200,7 @@ static int ScanExtensions( extensions_manager_t *p_mgr ) ...@@ -215,7 +200,7 @@ static int ScanExtensions( extensions_manager_t *p_mgr )
* @param pb_continue bool* that indicates whether to continue batch or not * @param pb_continue bool* that indicates whether to continue batch or not
**/ **/
int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script, 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; extensions_manager_t *p_mgr = ( extensions_manager_t* ) p_this;
bool b_ok = false; bool b_ok = false;
...@@ -250,6 +235,7 @@ int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script, ...@@ -250,6 +235,7 @@ int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script,
vlc_cond_init( &p_ext->p_sys->wait ); vlc_cond_init( &p_ext->p_sys->wait );
/* Load and run the script(s) */ /* Load and run the script(s) */
lua_State *L = luaL_newstate();
if( luaL_dofile( L, psz_script ) ) if( luaL_dofile( L, psz_script ) )
{ {
msg_Warn( p_mgr, "Error loading script %s: %s", 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, ...@@ -414,6 +400,7 @@ int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script,
b_ok = true; b_ok = true;
exit: exit:
lua_close( L );
if( !b_ok ) if( !b_ok )
{ {
free( p_ext->psz_name ); free( p_ext->psz_name );
......
...@@ -48,9 +48,6 @@ struct extensions_manager_sys_t ...@@ -48,9 +48,6 @@ struct extensions_manager_sys_t
/* Lock for this list */ /* Lock for this list */
vlc_mutex_t lock; vlc_mutex_t lock;
/* Lua specific */
lua_State *L;
/* Flag indicating that the module is about to be unloaded */ /* Flag indicating that the module is about to be unloaded */
bool b_killed; bool b_killed;
}; };
......
...@@ -126,14 +126,19 @@ error: ...@@ -126,14 +126,19 @@ error:
* pointed by psz_filename. * pointed by psz_filename.
*****************************************************************************/ *****************************************************************************/
static int fetch_art( vlc_object_t *p_this, const char * 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; int s;
lua_State *L = init( p_this, p_item );
int i_ret = run(p_this, psz_filename, L, "fetch_art"); int i_ret = run(p_this, psz_filename, L, "fetch_art");
if(i_ret != VLC_SUCCESS) if(i_ret != VLC_SUCCESS)
{
lua_close( L );
return i_ret; return i_ret;
}
if((s = lua_gettop( L ))) if((s = lua_gettop( L )))
{ {
...@@ -145,7 +150,8 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename, ...@@ -145,7 +150,8 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
if( psz_value && *psz_value != 0 ) if( psz_value && *psz_value != 0 )
{ {
lua_Dbg( p_this, "setting arturl: %s", psz_value ); 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; return VLC_SUCCESS;
} }
} }
...@@ -160,6 +166,7 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename, ...@@ -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" ); msg_Err( p_this, "Script went completely foobar" );
} }
lua_close( L );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -168,15 +175,20 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename, ...@@ -168,15 +175,20 @@ static int fetch_art( vlc_object_t *p_this, const char * psz_filename,
* pointed by psz_filename. * pointed by psz_filename.
*****************************************************************************/ *****************************************************************************/
static int read_meta( vlc_object_t *p_this, const char * 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"); int i_ret = run(p_this, psz_filename, L, "read_meta");
if(i_ret != VLC_SUCCESS) if(i_ret != VLC_SUCCESS)
{
lua_close( L );
return i_ret; return i_ret;
}
// Continue, all "meta reader" are always run. // Continue, all "meta reader" are always run.
lua_close( L );
return 1; return 1;
} }
...@@ -186,11 +198,15 @@ static int read_meta( vlc_object_t *p_this, const char * psz_filename, ...@@ -186,11 +198,15 @@ static int read_meta( vlc_object_t *p_this, const char * psz_filename,
* pointed by psz_filename. * pointed by psz_filename.
*****************************************************************************/ *****************************************************************************/
static int fetch_meta( vlc_object_t *p_this, const char * 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 );
int ret = run(p_this, psz_filename, L, "fetch_meta");
lua_close( L );
return run(p_this, psz_filename, L, "fetch_meta"); return ret;
} }
/***************************************************************************** /*****************************************************************************
...@@ -202,9 +218,7 @@ int ReadMeta( vlc_object_t *p_this ) ...@@ -202,9 +218,7 @@ int ReadMeta( vlc_object_t *p_this )
demux_meta_t *p_demux_meta = (demux_meta_t *)p_this; demux_meta_t *p_demux_meta = (demux_meta_t *)p_this;
input_item_t *p_item = p_demux_meta->p_item; 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, p_item );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/reader", &read_meta, L, NULL );
lua_close( L );
return i_ret; return i_ret;
} }
...@@ -219,9 +233,7 @@ int FetchMeta( vlc_object_t *p_this ) ...@@ -219,9 +233,7 @@ int FetchMeta( vlc_object_t *p_this )
demux_meta_t *p_demux_meta = (demux_meta_t *)p_this; demux_meta_t *p_demux_meta = (demux_meta_t *)p_this;
input_item_t *p_item = p_demux_meta->p_item; 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, p_item );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/fetcher", &fetch_meta, L, NULL );
lua_close( L );
return i_ret; return i_ret;
} }
...@@ -235,9 +247,7 @@ int FindArt( vlc_object_t *p_this ) ...@@ -235,9 +247,7 @@ int FindArt( vlc_object_t *p_this )
art_finder_t *p_finder = (art_finder_t *)p_this; art_finder_t *p_finder = (art_finder_t *)p_this;
input_item_t *p_item = p_finder->p_item; 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, p_item );
int i_ret = vlclua_scripts_batch_execute( p_this, "meta/art", &fetch_art, L, p_item );
lua_close( L );
return i_ret; return i_ret;
} }
......
...@@ -202,8 +202,7 @@ void vlclua_dir_list_free( char **ppsz_dir_list ) ...@@ -202,8 +202,7 @@ void vlclua_dir_list_free( char **ppsz_dir_list )
*****************************************************************************/ *****************************************************************************/
int vlclua_scripts_batch_execute( vlc_object_t *p_this, int vlclua_scripts_batch_execute( vlc_object_t *p_this,
const char * luadirname, const char * luadirname,
int (*func)(vlc_object_t *, const char *, lua_State *, void *), int (*func)(vlc_object_t *, const char *, void *),
lua_State * L,
void * user_data) void * user_data)
{ {
char *ppsz_dir_list[] = { NULL, NULL, NULL, NULL }; char *ppsz_dir_list[] = { NULL, NULL, NULL, NULL };
...@@ -240,7 +239,7 @@ int vlclua_scripts_batch_execute( vlc_object_t *p_this, ...@@ -240,7 +239,7 @@ int vlclua_scripts_batch_execute( vlc_object_t *p_this,
{ {
msg_Dbg( p_this, "Trying Lua playlist script %s", msg_Dbg( p_this, "Trying Lua playlist script %s",
psz_filename ); psz_filename );
i_ret = func( p_this, psz_filename, L, user_data ); i_ret = func( p_this, psz_filename, user_data );
free( psz_filename ); free( psz_filename );
if( i_ret == VLC_SUCCESS ) if( i_ret == VLC_SUCCESS )
break; break;
......
...@@ -104,8 +104,8 @@ int vlclua_push_ret( lua_State *, int i_error ); ...@@ -104,8 +104,8 @@ int vlclua_push_ret( lua_State *, int i_error );
* success. * success.
*****************************************************************************/ *****************************************************************************/
int vlclua_scripts_batch_execute( vlc_object_t *p_this, const char * luadirname, int vlclua_scripts_batch_execute( vlc_object_t *p_this, const char * luadirname,
int (*func)(vlc_object_t *, const char *, lua_State *, void *), int (*func)(vlc_object_t *, const char *, void *),
lua_State * L, void * user_data ); void * user_data );
int vlclua_dir_list( vlc_object_t *p_this, const char *luadirname, char **ppsz_dir_list ); 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 ); 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 ); char *vlclua_find_file( vlc_object_t *p_this, const char *psz_luadirname, const char *psz_name );
......
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