[vlc-devel] [PATCH 6/9] preparser: add playlist_preparser_Cancel
Thomas Guillem
thomas at gllm.fr
Wed Jun 1 18:46:25 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 | 41 ++++++++++++++++++++++++++++++++++++++---
src/playlist/preparser.h | 12 +++++++++++-
4 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/src/libvlc.c b/src/libvlc.c
index 3468e0e..887c41f 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 a5751c5..331a9e1 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;
vlc_mutex_t lock;
vlc_cond_t wait;
@@ -70,6 +72,7 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent )
return NULL;
p_preparser->input = NULL;
+ p_preparser->input_id = NULL;
p_preparser->object = parent;
p_preparser->p_fetcher = playlist_fetcher_New( parent );
if( unlikely(p_preparser->p_fetcher == NULL) )
@@ -85,7 +88,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) );
@@ -93,6 +97,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 );
@@ -116,6 +121,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( unsigned 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 );
@@ -152,7 +183,7 @@ void playlist_preparser_Delete( playlist_preparser_t *p_preparser )
* This function preparses an item when needed.
*/
static int Preparse( playlist_preparser_t *preparser, input_item_t *p_item,
- input_item_meta_request_option_t i_options )
+ input_item_meta_request_option_t i_options, void *id )
{
vlc_mutex_lock( &p_item->lock );
int i_type = p_item->i_type;
@@ -179,6 +210,7 @@ static int Preparse( playlist_preparser_t *preparser, input_item_t *p_item,
input_item_SignalPreparseEnded( p_item, ITEM_PREPARSE_FAILED );
return VLC_EGENERIC;
}
+ preparser->input_id = id;
vlc_mutex_unlock( &preparser->lock );
int i_ret = input_Read( preparser->input, true );
@@ -186,6 +218,7 @@ static int Preparse( playlist_preparser_t *preparser, input_item_t *p_item,
input_Close( preparser->input );
preparser->input = NULL;
+ preparser->input_id = NULL;
if( i_ret != VLC_SUCCESS )
{
@@ -259,6 +292,7 @@ static void *Thread( void *data )
{
input_item_t *p_current;
input_item_meta_request_option_t i_options;
+ void *id;
/* */
if( p_preparser->i_waiting > 0 )
@@ -266,6 +300,7 @@ static void *Thread( void *data )
preparser_entry_t *p_entry = p_preparser->pp_waiting[0];
p_current = p_entry->p_item;
i_options = p_entry->i_options;
+ id = p_entry->id;
free( p_entry );
REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
}
@@ -278,7 +313,7 @@ static void *Thread( void *data )
}
assert( p_current );
- if( Preparse( p_preparser, p_current, i_options ) == VLC_SUCCESS )
+ if( Preparse( p_preparser, p_current, i_options, id ) == VLC_SUCCESS )
Art( p_preparser, p_current );
vlc_gc_decref(p_current);
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