[vlc-commits] input: remove recursive locking in input_item_CopyOptions()

Rémi Denis-Courmont git at videolan.org
Wed Apr 13 22:29:53 CEST 2016


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Apr 13 23:23:43 2016 +0300| [9d47c00b66c3d50c06147b2ea5bedda8cc82e175] | committer: Rémi Denis-Courmont

input: remove recursive locking in input_item_CopyOptions()

Locking two muteces of the same type can lead to lock inversion.

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

 src/input/item.c |   37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/input/item.c b/src/input/item.c
index c8a67eb..e87f089 100644
--- a/src/input/item.c
+++ b/src/input/item.c
@@ -162,14 +162,43 @@ void input_item_SetMeta( input_item_t *p_i, vlc_meta_type_t meta_type, const cha
 void input_item_CopyOptions( input_item_t *p_parent,
                              input_item_t *p_child )
 {
+    char **optv = NULL;
+    uint8_t *flagv = NULL;
+    size_t optc;
+
     vlc_mutex_lock( &p_parent->lock );
 
-    for( int i = 0 ; i< p_parent->i_options; i++ )
-        input_item_AddOption( p_child,
-                              p_parent->ppsz_options[i],
-                              p_parent->optflagv[i] );
+    optc = p_parent->i_options;
+    if( optc > 0 )
+    {
+        optv = xmalloc( optc * sizeof (*optv) );
+        for( size_t i = 0; i < optc; i++ )
+            optv[i] = xstrdup( p_parent->ppsz_options[i] );
+
+        flagv = xmalloc( optc * sizeof (*flagv) );
+        memcpy( flagv, p_parent->optflagv, optc * sizeof (*flagv) );
+    }
 
     vlc_mutex_unlock( &p_parent->lock );
+
+    vlc_mutex_lock( &p_child->lock );
+
+    p_child->ppsz_options = xrealloc( p_child->ppsz_options,
+                                (p_child->i_options + optc) * sizeof (*optv) );
+    memcpy( p_child->ppsz_options + p_child->i_options, optv,
+            optc * sizeof (*optv) );
+    p_child->i_options += optc;
+
+    p_child->optflagv = xrealloc( p_child->optflagv,
+                               (p_child->i_options + optc) * sizeof (*flagv) );
+    memcpy( p_child->optflagv + p_child->i_options, flagv,
+            optc * sizeof (*flagv) );
+    p_child->optflagc += optc;
+
+    vlc_mutex_unlock( &p_child->lock );
+
+    free( flagv );
+    free( optv );
 }
 
 static void post_subitems( input_item_node_t *p_node )



More information about the vlc-commits mailing list