From 5942b165dda37a5fc14ebc82b40f0d910bb5b4a5 Mon Sep 17 00:00:00 2001 From: Antoine Cellerier Date: Sat, 13 Feb 2010 14:07:30 +0100 Subject: [PATCH] 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. --- modules/misc/lua/demux.c | 62 +++++++++++++++++------------------- modules/misc/lua/extension.c | 23 +++---------- modules/misc/lua/extension.h | 3 -- modules/misc/lua/meta.c | 44 +++++++++++++++---------- modules/misc/lua/vlc.c | 5 ++- modules/misc/lua/vlc.h | 4 +-- 6 files changed, 65 insertions(+), 76 deletions(-) diff --git a/modules/misc/lua/demux.c b/modules/misc/lua/demux.c index 018779dfd7..29d80139c9 100644 --- a/modules/misc/lua/demux.c +++ b/modules/misc/lua/demux.c @@ -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 ); } diff --git a/modules/misc/lua/extension.c b/modules/misc/lua/extension.c index 2a6f4041ca..c82d11a0f7 100644 --- a/modules/misc/lua/extension.c +++ b/modules/misc/lua/extension.c @@ -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 ); diff --git a/modules/misc/lua/extension.h b/modules/misc/lua/extension.h index 78928b53a6..921ad4327e 100644 --- a/modules/misc/lua/extension.h +++ b/modules/misc/lua/extension.h @@ -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; }; diff --git a/modules/misc/lua/meta.c b/modules/misc/lua/meta.c index a0275cb077..23220ca2b7 100644 --- a/modules/misc/lua/meta.c +++ b/modules/misc/lua/meta.c @@ -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 ); + + 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 ) 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; } diff --git a/modules/misc/lua/vlc.c b/modules/misc/lua/vlc.c index 6b400d5dd5..5e82328c5b 100644 --- a/modules/misc/lua/vlc.c +++ b/modules/misc/lua/vlc.c @@ -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; diff --git a/modules/misc/lua/vlc.h b/modules/misc/lua/vlc.h index 21ba79c72a..cb71d98b30 100644 --- a/modules/misc/lua/vlc.h +++ b/modules/misc/lua/vlc.h @@ -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 ); -- 2.39.2