]> git.sesse.net Git - vlc/commitdiff
LUA intf: fix lock_and_wait, and stop using vlc_object_wait()
authorRémi Denis-Courmont <rdenis@simphalempin.com>
Mon, 12 Jan 2009 17:52:01 +0000 (19:52 +0200)
committerRémi Denis-Courmont <rdenis@simphalempin.com>
Mon, 12 Jan 2009 17:52:01 +0000 (19:52 +0200)
The only event that lock_and_wait can only wait for the end of the
interface event (safely). That is the only piece of state which is read
under the lock.

Also it is not possible to wait on a random object since (deprecated)
vlc_object_signal() is _not_ broadcasting the object condition variable.
In effect, VLC threads shall only wait on their own object (this is not
LUA-specific).

Ultimately, lock_and_wait is of barely any use, and in any case is now
poorly named (my fault for inventing vlc_object_lock_and_wait()). By the
way, it always returns true now.

modules/misc/lua/intf.c
modules/misc/lua/libs/misc.c
modules/misc/lua/vlc.h

index dba8fd5b5b04afa4a8e0f3d61412e5559c787dce..fb4194b044a1c481cd9939d0d9cdd9c3a98b7492 100644 (file)
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-struct intf_sys_t
-{
-    char *psz_filename;
-    lua_State *L;
-};
-
-static void Run( intf_thread_t *p_intf );
+static void *Run( void * );
 
 /*****************************************************************************
  *
@@ -264,32 +258,54 @@ int Open_LuaIntf( vlc_object_t *p_this )
 
     p_sys->L = L;
 
-    p_intf->pf_run = Run;
-    p_intf->psz_header = strdup( psz_name ); /* Do I need to clean that up myself in Close_LuaIntf? */
+    p_intf->psz_header = psz_name;
+    /* ^^ Do I need to clean that up myself in Close_LuaIntf? */
+
+    vlc_mutex_init( &p_sys->lock );
+    vlc_cond_init( &p_sys->wait );
+    p_sys->exiting = false;
+
+    if( vlc_clone( &p_sys->thread, Run, p_intf, VLC_THREAD_PRIORITY_LOW ) )
+    {
+        p_sys->exiting = true;
+        Close_LuaIntf( p_this );
+        return VLC_ENOMEM;
+    }
 
-    free( psz_name );
     return VLC_SUCCESS;
 }
 
 void Close_LuaIntf( vlc_object_t *p_this )
 {
     intf_thread_t *p_intf = (intf_thread_t*)p_this;
+    intf_sys_t *p_sys = p_intf->p_sys;
+
+    if( !p_sys->exiting ) /* <- Read-only here and in thread: no locking */
+    {
+        vlc_mutex_lock( &p_sys->lock );
+        p_sys->exiting = true;
+        vlc_cond_signal( &p_sys->wait );
+        vlc_mutex_unlock( &p_sys->lock );
+        vlc_join( p_sys->thread, NULL );
+    }
+    vlc_cond_destroy( &p_sys->wait );
+    vlc_mutex_destroy( &p_sys->lock );
 
-    lua_close( p_intf->p_sys->L );
-    free( p_intf->p_sys );
+    lua_close( p_sys->L );
+    free( p_sys );
 }
 
-static void Run( intf_thread_t *p_intf )
+static void *Run( void *data )
 {
-    int canc = vlc_savecancel( );
-    lua_State *L = p_intf->p_sys->L;
+    intf_thread_t *p_intf = data;
+    intf_sys_t *p_sys = p_intf->p_sys;
+    lua_State *L = p_sys->L;
 
-    if( luaL_dofile( L, p_intf->p_sys->psz_filename ) )
+    if( luaL_dofile( L, p_sys->psz_filename ) )
     {
-        msg_Err( p_intf, "Error loading script %s: %s",
-                 p_intf->p_sys->psz_filename,
+        msg_Err( p_intf, "Error loading script %s: %s", p_sys->psz_filename,
                  lua_tostring( L, lua_gettop( L ) ) );
         lua_pop( L, 1 );
     }
-    vlc_restorecancel( canc );
+    return NULL;
 }
index db8bb9f4eed6a861fd4b998ef3e95524c250373d..8a21cceeebc5d2b465b56a7d9acde6a8187209ad 100644 (file)
@@ -170,18 +170,14 @@ static int vlclua_datadir_list( lua_State *L )
  *****************************************************************************/
 static int vlclua_lock_and_wait( lua_State *L )
 {
-    vlc_object_t *p_this = vlclua_get_this( L );
-    int b_quit;
-
-    vlc_object_lock( p_this );
-    b_quit = vlc_object_alive( p_this );
-    if( b_quit )
-    {
-        vlc_object_wait( p_this );
-        b_quit = vlc_object_alive( p_this );
-    }
-    vlc_object_unlock( p_this );
-    lua_pushboolean( L, b_quit );
+    intf_thread_t *p_intf = (intf_thread_t *)vlclua_get_this( L );
+    intf_sys_t *p_sys = p_intf->p_sys;
+
+    vlc_mutex_lock( &p_sys->lock );
+    while( !p_sys->exiting )
+        vlc_cond_wait( &p_sys->wait, &p_sys->lock );
+    vlc_mutex_unlock( &p_sys->lock );
+    lua_pushboolean( L, 1 );
     return 1;
 }
 
index c4cb9a4abdb232fd4895c3a6dbbb400aecfc424a..94d69f6357a5b200bc181491410d47d25467c284 100644 (file)
@@ -122,6 +122,19 @@ int __vlclua_playlist_add_internal( vlc_object_t *, lua_State *, playlist_t *,
                                     input_item_t *, bool );
 #define vlclua_playlist_add_internal(a,b,c,d,e) __vlclua_playlist_add_internal(VLC_OBJECT(a),b,c,d,e)
 
+/**
+ * Per-interface private state
+ */
+struct intf_sys_t
+{
+    char *psz_filename;
+    lua_State *L;
+
+    vlc_thread_t thread;
+    vlc_mutex_t lock;
+    vlc_cond_t wait;
+    bool exiting;
+};
 
 #endif /* VLC_LUA_H */