mirror of https://code.videolan.org/videolan/vlc
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:
parent
39852e8bdf
commit
5942b165dd
|
@ -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,
|
||||||
|
|
||||||
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 )
|
||||||
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 )
|
||||||
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[] = {
|
||||||
|
|
||||||
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 )
|
||||||
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 )
|
||||||
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 )
|
||||||
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 )
|
||||||
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 )
|
||||||
* @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,
|
||||||
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,
|
||||||
|
|
||||||
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
|
||||||
/* 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:
|
||||||
* 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,
|
||||||
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,
|
||||||
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,
|
||||||
* 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,
|
||||||
* 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 );
|
||||||
|
|
||||||
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;
|
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 )
|
||||||
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 )
|
||||||
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 )
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
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,
|
||||||
{
|
{
|
||||||
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 );
|
||||||
* 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 );
|
||||||
|
|
Loading…
Reference in New Issue