[vlc-devel] [PATCH 4/9] preparser: add playlist_preparser_Cancel

Thomas Guillem thomas at gllm.fr
Sun Jun 5 11:41:45 CEST 2016


Add a void * to playlist_preparser_Push arguments. This void * can be used as a
unique id to identity the caller of the request. playlist_preparser_Cancel()
will cancel all requets done with this id.
---
 src/libvlc.c             |  2 +-
 src/playlist/item.c      |  2 +-
 src/playlist/preparser.c | 35 ++++++++++++++++++++++++++++++++++-
 src/playlist/preparser.h | 12 +++++++++++-
 4 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/libvlc.c b/src/libvlc.c
index deb8a8d..694e3bb 100644
--- a/src/libvlc.c
+++ b/src/libvlc.c
@@ -627,7 +627,7 @@ int libvlc_MetaRequest(libvlc_int_t *libvlc, input_item_t *item,
     if( i_options & META_REQUEST_OPTION_DO_INTERACT )
         item->b_preparse_interact = true;
     vlc_mutex_unlock( &item->lock );
-    playlist_preparser_Push(priv->parser, item, i_options);
+    playlist_preparser_Push(priv->parser, item, i_options, NULL);
     return VLC_SUCCESS;
 }
 
diff --git a/src/playlist/item.c b/src/playlist/item.c
index a96a15e..00bd046 100644
--- a/src/playlist/item.c
+++ b/src/playlist/item.c
@@ -781,7 +781,7 @@ static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
     char *psz_album = input_item_GetAlbum( p_item->p_input );
     if( sys->p_preparser != NULL && !input_item_IsPreparsed( p_item->p_input )
      && (EMPTY_STR(psz_artist) || EMPTY_STR(psz_album)) )
-        playlist_preparser_Push( sys->p_preparser, p_item->p_input, 0 );
+        playlist_preparser_Push( sys->p_preparser, p_item->p_input, 0, NULL );
     free( psz_artist );
     free( psz_album );
 }
diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c
index ef88d49..cf62690 100644
--- a/src/playlist/preparser.c
+++ b/src/playlist/preparser.c
@@ -42,6 +42,7 @@ struct preparser_entry_t
 {
     input_item_t    *p_item;
     input_item_meta_request_option_t i_options;
+    void            *id;
 };
 
 struct playlist_preparser_t
@@ -50,6 +51,7 @@ struct playlist_preparser_t
     playlist_fetcher_t  *p_fetcher;
 
     input_thread_t      *input;
+    void                *input_id;
     bool                 input_done;
 
     vlc_mutex_t     lock;
@@ -72,6 +74,7 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent )
         return NULL;
 
     p_preparser->input = NULL;
+    p_preparser->input_id = NULL;
     p_preparser->input_done = false;
     p_preparser->object = parent;
     p_preparser->p_fetcher = playlist_fetcher_New( parent );
@@ -89,7 +92,8 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent )
 }
 
 void playlist_preparser_Push( playlist_preparser_t *p_preparser, input_item_t *p_item,
-                              input_item_meta_request_option_t i_options )
+                              input_item_meta_request_option_t i_options,
+                              void *id )
 {
     preparser_entry_t *p_entry = malloc( sizeof(preparser_entry_t) );
 
@@ -97,6 +101,7 @@ void playlist_preparser_Push( playlist_preparser_t *p_preparser, input_item_t *p
         return;
     p_entry->p_item = p_item;
     p_entry->i_options = i_options;
+    p_entry->id = id;
     vlc_gc_incref( p_entry->p_item );
 
     vlc_mutex_lock( &p_preparser->lock );
@@ -120,6 +125,32 @@ void playlist_preparser_fetcher_Push( playlist_preparser_t *p_preparser,
         playlist_fetcher_Push( p_preparser->p_fetcher, p_item, i_options );
 }
 
+void playlist_preparser_Cancel( playlist_preparser_t *p_preparser, void *id )
+{
+    assert( id != NULL );
+    vlc_mutex_lock( &p_preparser->lock );
+
+    /* Remove entries that match with the id */
+    for( int i = p_preparser->i_waiting - 1; i >= 0; ++i )
+    {
+        preparser_entry_t *p_entry = p_preparser->pp_waiting[i];
+        if( p_entry->id == id )
+        {
+            vlc_gc_decref( p_entry->p_item );
+            free( p_entry );
+            REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, i );
+        }
+    }
+
+    /* Stop the input_thread reading the item (if any) */
+    if( p_preparser->input_id == id )
+    {
+        assert( p_preparser->input != NULL );
+        input_Stop( p_preparser->input );
+    }
+    vlc_mutex_unlock( &p_preparser->lock );
+}
+
 void playlist_preparser_Delete( playlist_preparser_t *p_preparser )
 {
     vlc_mutex_lock( &p_preparser->lock );
@@ -203,6 +234,7 @@ static void Preparse( playlist_preparser_t *preparser,
             return;
         }
         preparser->input_done = false;
+        preparser->input_id = p_entry->id;
 
         var_AddCallback( preparser->input, "intf-event", InputEvent,
                          preparser );
@@ -216,6 +248,7 @@ static void Preparse( playlist_preparser_t *preparser,
                          preparser );
         input_Close( preparser->input );
         preparser->input = NULL;
+        preparser->input_id = NULL;
 
         var_SetAddress( preparser->object, "item-change", p_item );
         input_item_SetPreparsed( p_item, true );
diff --git a/src/playlist/preparser.h b/src/playlist/preparser.h
index fabb57b..fb2b105 100644
--- a/src/playlist/preparser.h
+++ b/src/playlist/preparser.h
@@ -47,14 +47,24 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t * );
  * preparser object is deleted.
  * Listen to vlc_InputItemPreparseEnded event to get notified when item is
  * preparsed.
+ *
+ * @param id unique id provided by the caller. This is can be used to cancel
+ * the request with playlist_preparser_Cancel()
  */
 void playlist_preparser_Push( playlist_preparser_t *, input_item_t *,
-                              input_item_meta_request_option_t );
+                              input_item_meta_request_option_t, void *id );
 
 void playlist_preparser_fetcher_Push( playlist_preparser_t *, input_item_t *,
                                       input_item_meta_request_option_t );
 
 /**
+ * This function cancel all preparsing requests for a given id
+ *
+ * @param id unique id given to playlist_preparser_Push()
+ */
+void playlist_preparser_Cancel( playlist_preparser_t *, void *id );
+
+/**
  * This function destroys the preparser object and thread.
  *
  * All pending input items will be released.
-- 
2.8.1



More information about the vlc-devel mailing list