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 dba8fd5..fb4194b 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 db8bb9f..8a21cce 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 c4cb9a4..94d69f6 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 */