[vlc-devel] commit: LUA intf: fix lock_and_wait, and stop using vlc_object_wait() ( Rémi Denis-Courmont )

git version control git at videolan.org
Mon Jan 12 19:33:37 CET 2009


vlc | branch: master | Rémi Denis-Courmont <rdenis at simphalempin.com> | Mon Jan 12 19:52:01 2009 +0200| [b935abee4d16231e34ab6a2b092fcc1e757483c5] | committer: Rémi Denis-Courmont 

LUA intf: fix lock_and_wait, and stop using vlc_object_wait()

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.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b935abee4d16231e34ab6a2b092fcc1e757483c5
---

 modules/misc/lua/intf.c      |   54 +++++++++++++++++++++++++++--------------
 modules/misc/lua/libs/misc.c |   20 ++++++---------
 modules/misc/lua/vlc.h       |   13 ++++++++++
 3 files changed, 56 insertions(+), 31 deletions(-)

diff --git a/modules/misc/lua/intf.c b/modules/misc/lua/intf.c
index dba8fd5..fb4194b 100644
--- a/modules/misc/lua/intf.c
+++ b/modules/misc/lua/intf.c
@@ -50,13 +50,7 @@
 /*****************************************************************************
  * 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;
 }
diff --git a/modules/misc/lua/libs/misc.c b/modules/misc/lua/libs/misc.c
index db8bb9f..8a21cce 100644
--- a/modules/misc/lua/libs/misc.c
+++ b/modules/misc/lua/libs/misc.c
@@ -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;
 }
 
diff --git a/modules/misc/lua/vlc.h b/modules/misc/lua/vlc.h
index c4cb9a4..94d69f6 100644
--- a/modules/misc/lua/vlc.h
+++ b/modules/misc/lua/vlc.h
@@ -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 */
 




More information about the vlc-devel mailing list