[vlc-devel] [PATCH 5/5] addons: Make fetcher & installer threads interruptible

Hugo Beauzée-Luyssen hugo at beauzee.fr
Fri Nov 3 11:47:29 CET 2017


---
 src/misc/addons.c | 86 ++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 66 insertions(+), 20 deletions(-)

diff --git a/src/misc/addons.c b/src/misc/addons.c
index 662b6bcc79..fd5ee96e56 100644
--- a/src/misc/addons.c
+++ b/src/misc/addons.c
@@ -26,6 +26,7 @@
 #include <vlc_atomic.h>
 #include <vlc_modules.h>
 #include <vlc_arrays.h>
+#include <vlc_interrupt.h>
 #include "libvlc.h"
 
 #include <vlc_addons.h>
@@ -50,6 +51,7 @@ struct addons_manager_private_t
         vlc_cond_t waitcond;
         bool b_live;
         vlc_mutex_t lock;
+        vlc_interrupt_t *p_interrupt;
         DECL_ARRAY(char*) uris;
         DECL_ARRAY(addon_entry_t*) entries;
     } finder;
@@ -60,6 +62,7 @@ struct addons_manager_private_t
         vlc_cond_t waitcond;
         bool b_live;
         vlc_mutex_t lock;
+        vlc_interrupt_t *p_interrupt;
         DECL_ARRAY(addon_entry_t*) entries;
     } installer;
 };
@@ -140,6 +143,20 @@ addons_manager_t *addons_manager_New( vlc_object_t *p_this,
     p_manager->owner = *owner;
     p_manager->p_priv->p_parent = p_this;
 
+    p_manager->p_priv->finder.p_interrupt = vlc_interrupt_create();
+    p_manager->p_priv->installer.p_interrupt = vlc_interrupt_create();
+    if ( !p_manager->p_priv->finder.p_interrupt ||
+         !p_manager->p_priv->installer.p_interrupt )
+    {
+        if( p_manager->p_priv->finder.p_interrupt )
+            vlc_interrupt_destroy( p_manager->p_priv->finder.p_interrupt );
+        if( p_manager->p_priv->installer.p_interrupt )
+            vlc_interrupt_destroy( p_manager->p_priv->installer.p_interrupt );
+        free( p_manager->p_priv );
+        free( p_manager );
+        return NULL;
+    }
+
 #define INIT_QUEUE( name ) \
     p_manager->p_priv->name.b_live = false;\
     vlc_mutex_init( &p_manager->p_priv->name.lock );\
@@ -162,7 +179,7 @@ void addons_manager_Delete( addons_manager_t *p_manager )
     vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
     if ( b_live )
     {
-        vlc_cancel( p_manager->p_priv->finder.thread );
+        vlc_interrupt_kill( p_manager->p_priv->finder.p_interrupt );
         vlc_join( p_manager->p_priv->finder.thread, NULL );
     }
 
@@ -171,7 +188,7 @@ void addons_manager_Delete( addons_manager_t *p_manager )
     vlc_mutex_unlock( &p_manager->p_priv->installer.lock );
     if ( b_live )
     {
-        vlc_cancel( p_manager->p_priv->installer.thread );
+        vlc_interrupt_kill( p_manager->p_priv->installer.p_interrupt );
         vlc_join( p_manager->p_priv->installer.thread, NULL );
     }
 
@@ -181,7 +198,8 @@ void addons_manager_Delete( addons_manager_t *p_manager )
     FOREACH_END();\
     ARRAY_RESET( p_manager->p_priv->name.entries );\
     vlc_mutex_destroy( &p_manager->p_priv->name.lock );\
-    vlc_cond_destroy( &p_manager->p_priv->name.waitcond );
+    vlc_cond_destroy( &p_manager->p_priv->name.waitcond );\
+    vlc_interrupt_destroy( p_manager->p_priv->name.p_interrupt );
 
     FREE_QUEUE( finder )
     FREE_QUEUE( installer )
@@ -299,27 +317,40 @@ static void LoadLocalStorage( addons_manager_t *p_manager )
     vlc_object_release( p_finder );
 }
 
+static void finder_thread_interrupted( void* p_data )
+{
+    addons_manager_t *p_manager = p_data;
+    vlc_mutex_lock( &p_manager->p_priv->finder.lock );
+    p_manager->p_priv->finder.b_live = false;
+    vlc_cond_signal( &p_manager->p_priv->finder.waitcond );
+    vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
+}
+
 static void *FinderThread( void *p_data )
 {
     addons_manager_t *p_manager = p_data;
+    int i_cancel = vlc_savecancel();
+    vlc_interrupt_set( p_manager->p_priv->finder.p_interrupt );
 
-    for( ;; )
+    vlc_mutex_lock( &p_manager->p_priv->finder.lock );
+    while( p_manager->p_priv->finder.b_live )
     {
         char *psz_uri;
 
-        vlc_mutex_lock( &p_manager->p_priv->finder.lock );
-        mutex_cleanup_push( &p_manager->p_priv->finder.lock );
-        while( p_manager->p_priv->finder.uris.i_size == 0 )
+        vlc_interrupt_register( finder_thread_interrupted, p_data );
+        while( p_manager->p_priv->finder.uris.i_size == 0 &&
+               p_manager->p_priv->finder.b_live )
         {
             vlc_cond_wait( &p_manager->p_priv->finder.waitcond,
                            &p_manager->p_priv->finder.lock );
         }
+        vlc_interrupt_unregister();
+        if( !p_manager->p_priv->finder.b_live )
+            break;
         psz_uri = p_manager->p_priv->finder.uris.p_elems[0];
         ARRAY_REMOVE( p_manager->p_priv->finder.uris, 0 );
-        vlc_cleanup_pop();
-        vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
 
-        int i_cancel = vlc_savecancel();
+        vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
 
         addons_finder_t *p_finder =
                 vlc_custom_create( p_manager->p_priv->p_parent, sizeof( *p_finder ), "entries finder" );
@@ -344,10 +375,11 @@ static void *FinderThread( void *p_data )
         }
 
         p_manager->owner.discovery_ended( p_manager );
-        vlc_restorecancel( i_cancel );
-        vlc_testcancel();
+        vlc_mutex_lock( &p_manager->p_priv->finder.lock );
     }
 
+    vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
+    vlc_restorecancel( i_cancel );
     return NULL;
 }
 
@@ -411,29 +443,42 @@ static int installOrRemoveAddon( addons_manager_t *p_manager, addon_entry_t *p_e
     return i_return;
 }
 
+static void installer_thread_interrupted( void* p_data )
+{
+    addons_manager_t *p_manager = p_data;
+    vlc_mutex_lock( &p_manager->p_priv->installer.lock );
+    p_manager->p_priv->installer.b_live = false;
+    vlc_cond_signal( &p_manager->p_priv->installer.waitcond );
+    vlc_mutex_unlock( &p_manager->p_priv->installer.lock );
+}
+
 static void *InstallerThread( void *p_data )
 {
     addons_manager_t *p_manager = p_data;
+    int i_cancel = vlc_savecancel();
+    vlc_interrupt_set( p_manager->p_priv->installer.p_interrupt );
     int i_ret;
 
-    for( ;; )
+    vlc_mutex_lock( &p_manager->p_priv->installer.lock );
+    while( p_manager->p_priv->installer.b_live )
     {
-        vlc_mutex_lock( &p_manager->p_priv->installer.lock );
-        mutex_cleanup_push( &p_manager->p_priv->installer.lock );
-        while ( !p_manager->p_priv->installer.entries.i_size )
+        vlc_interrupt_register( installer_thread_interrupted, p_data );
+        while ( !p_manager->p_priv->installer.entries.i_size &&
+                p_manager->p_priv->installer.b_live )
         {
             /* No queued addons */
             vlc_cond_wait( &p_manager->p_priv->installer.waitcond,
                            &p_manager->p_priv->installer.lock );
         }
-        vlc_cleanup_pop();
+        vlc_interrupt_unregister();
+        if( !p_manager->p_priv->installer.b_live )
+            break;
 
         addon_entry_t *p_entry = p_manager->p_priv->installer.entries.p_elems[0];
         ARRAY_REMOVE( p_manager->p_priv->installer.entries, 0 );
         addon_entry_Hold( p_entry );
         vlc_mutex_unlock( &p_manager->p_priv->installer.lock );
 
-        int i_cancel = vlc_savecancel();
         vlc_mutex_lock( &p_entry->lock );
         /* DO WORK */
         if ( p_entry->e_state == ADDON_INSTALLED )
@@ -472,9 +517,10 @@ static void *InstallerThread( void *p_data )
         addon_entry_Release( p_entry );
 
         addons_manager_WriteCatalog( p_manager );
-        vlc_restorecancel( i_cancel );
+        vlc_mutex_lock( &p_manager->p_priv->installer.lock );
     }
-
+    vlc_mutex_unlock( &p_manager->p_priv->installer.lock );
+    vlc_restorecancel( i_cancel );
     return NULL;
 }
 
-- 
2.11.0



More information about the vlc-devel mailing list