Commit da6e1f75 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Fetcher: use nornal thread API

parent 4edec0d6
...@@ -99,7 +99,7 @@ int input_ArtFind( playlist_t *p_playlist, input_item_t *p_item ) ...@@ -99,7 +99,7 @@ int input_ArtFind( playlist_t *p_playlist, input_item_t *p_item )
/* If we already checked this album in this session, skip */ /* If we already checked this album in this session, skip */
if( psz_artist && psz_album ) if( psz_artist && psz_album )
{ {
FOREACH_ARRAY( playlist_album_t album, pl_priv(p_playlist)->p_fetcher->albums ) FOREACH_ARRAY( playlist_album_t album, pl_priv(p_playlist)->fetcher.albums )
if( !strcmp( album.psz_artist, psz_artist ) && if( !strcmp( album.psz_artist, psz_artist ) &&
!strcmp( album.psz_album, psz_album ) ) !strcmp( album.psz_album, psz_album ) )
{ {
...@@ -179,7 +179,7 @@ int input_ArtFind( playlist_t *p_playlist, input_item_t *p_item ) ...@@ -179,7 +179,7 @@ int input_ArtFind( playlist_t *p_playlist, input_item_t *p_item )
a.psz_album = psz_album; a.psz_album = psz_album;
a.psz_arturl = input_item_GetArtURL( p_item ); a.psz_arturl = input_item_GetArtURL( p_item );
a.b_found = (i_ret == VLC_EGENERIC ? false : true ); a.b_found = (i_ret == VLC_EGENERIC ? false : true );
ARRAY_APPEND( pl_priv(p_playlist)->p_fetcher->albums, a ); ARRAY_APPEND( pl_priv(p_playlist)->fetcher.albums, a );
} }
else else
{ {
......
...@@ -219,19 +219,15 @@ int playlist_PreparseEnqueueItem( playlist_t *p_playlist, ...@@ -219,19 +219,15 @@ int playlist_PreparseEnqueueItem( playlist_t *p_playlist,
int playlist_AskForArtEnqueue( playlist_t *p_playlist, int playlist_AskForArtEnqueue( playlist_t *p_playlist,
input_item_t *p_item ) input_item_t *p_item )
{ {
playlist_fetcher_t *p_fetcher = pl_priv(p_playlist)->p_fetcher; playlist_fetcher_t *p_fetcher = &pl_priv(p_playlist)->fetcher;
vlc_object_lock( p_fetcher );
if( !vlc_object_alive( p_fetcher ) )
{
vlc_object_unlock( p_fetcher );
return VLC_EGENERIC;
}
vlc_gc_incref( p_item ); vlc_gc_incref( p_item );
vlc_mutex_lock( &p_fetcher->lock );
INSERT_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, INSERT_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting,
p_fetcher->i_waiting, p_item ); p_fetcher->i_waiting, p_item );
vlc_object_signal_unlocked( p_fetcher ); vlc_cond_signal( &p_fetcher->wait );
vlc_object_unlock( p_fetcher ); vlc_mutex_unlock( &p_fetcher->lock );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -534,8 +530,7 @@ int playlist_PlayItem( playlist_t *p_playlist, playlist_item_t *p_item ) ...@@ -534,8 +530,7 @@ int playlist_PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
} }
free( psz_uri ); free( psz_uri );
if( pl_priv(p_playlist)->p_fetcher && if( pl_priv(p_playlist)->fetcher.i_art_policy == ALBUM_ART_WHEN_PLAYED )
pl_priv(p_playlist)->p_fetcher->i_art_policy == ALBUM_ART_WHEN_PLAYED )
{ {
bool b_has_art; bool b_has_art;
......
...@@ -176,9 +176,9 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) ...@@ -176,9 +176,9 @@ playlist_t * playlist_Create( vlc_object_t *p_parent )
static void playlist_Destructor( vlc_object_t * p_this ) static void playlist_Destructor( vlc_object_t * p_this )
{ {
playlist_t * p_playlist = (playlist_t *)p_this; playlist_t * p_playlist = (playlist_t *)p_this;
playlist_preparse_t *p_preparse = &pl_priv(p_playlist)->preparse;
/* Destroy the item preparser */ /* Destroy the item preparser */
playlist_preparse_t *p_preparse = &pl_priv(p_playlist)->preparse;
if (p_preparse->up) if (p_preparse->up)
{ {
vlc_cancel (p_preparse->thread); vlc_cancel (p_preparse->thread);
...@@ -193,10 +193,20 @@ static void playlist_Destructor( vlc_object_t * p_this ) ...@@ -193,10 +193,20 @@ static void playlist_Destructor( vlc_object_t * p_this )
vlc_mutex_destroy (&p_preparse->lock); vlc_mutex_destroy (&p_preparse->lock);
/* Destroy the item meta-infos fetcher */ /* Destroy the item meta-infos fetcher */
if( pl_priv(p_playlist)->p_fetcher ) playlist_fetcher_t *p_fetcher = &pl_priv(p_playlist)->fetcher;
if (p_fetcher->up)
{ {
vlc_object_release( pl_priv(p_playlist)->p_fetcher ); vlc_cancel (p_fetcher->thread);
vlc_join (p_fetcher->thread, NULL);
}
while (p_fetcher->i_waiting > 0)
{ /* Any left-over unparsed item? */
vlc_gc_decref (p_fetcher->pp_waiting[0]);
REMOVE_ELEM (p_fetcher->pp_waiting, p_fetcher->i_waiting, 0);
} }
vlc_cond_destroy (&p_fetcher->wait);
vlc_mutex_destroy (&p_fetcher->lock);
msg_Dbg( p_this, "Destroyed" ); msg_Dbg( p_this, "Destroyed" );
} }
...@@ -530,9 +540,6 @@ void playlist_LastLoop( playlist_t *p_playlist ) ...@@ -530,9 +540,6 @@ void playlist_LastLoop( playlist_t *p_playlist )
playlist_ServicesDiscoveryKillAll( p_playlist ); playlist_ServicesDiscoveryKillAll( p_playlist );
playlist_MLDump( p_playlist ); playlist_MLDump( p_playlist );
vlc_object_kill( pl_priv(p_playlist)->p_fetcher );
vlc_thread_join( pl_priv(p_playlist)->p_fetcher );
PL_LOCK; PL_LOCK;
/* Release the current node */ /* Release the current node */
...@@ -571,7 +578,6 @@ void *playlist_PreparseLoop( void *data ) ...@@ -571,7 +578,6 @@ void *playlist_PreparseLoop( void *data )
playlist_preparse_t *p_preparse = data; playlist_preparse_t *p_preparse = data;
playlist_t *p_playlist = &((playlist_private_t *)(((char *)p_preparse) playlist_t *p_playlist = &((playlist_private_t *)(((char *)p_preparse)
- offsetof(playlist_private_t, preparse)))->public_data; - offsetof(playlist_private_t, preparse)))->public_data;
int i_activity;
for( ;; ) for( ;; )
{ {
...@@ -615,21 +621,16 @@ void *playlist_PreparseLoop( void *data ) ...@@ -615,21 +621,16 @@ void *playlist_PreparseLoop( void *data )
*/ */
char *psz_arturl = input_item_GetArtURL( p_current ); char *psz_arturl = input_item_GetArtURL( p_current );
char *psz_name = input_item_GetName( p_current ); char *psz_name = input_item_GetName( p_current );
playlist_fetcher_t *p_fetcher = pl_priv(p_playlist)->p_fetcher; playlist_fetcher_t *p_fetcher = &pl_priv(p_playlist)->fetcher;
if( p_fetcher->i_art_policy == ALBUM_ART_ALL && if( p_fetcher->i_art_policy == ALBUM_ART_ALL &&
( !psz_arturl || strncmp( psz_arturl, "file://", 7 ) ) ) ( !psz_arturl || strncmp( psz_arturl, "file://", 7 ) ) )
{ {
PL_DEBUG("meta ok for %s, need to fetch art", psz_name ); PL_DEBUG("meta ok for %s, need to fetch art", psz_name );
vlc_object_lock( p_fetcher ); vlc_mutex_lock( &p_fetcher->lock );
if( vlc_object_alive( p_fetcher ) ) INSERT_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting,
{ p_fetcher->i_waiting, p_current);
INSERT_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, vlc_cond_signal( &p_fetcher->wait );
p_fetcher->i_waiting, p_current); vlc_mutex_unlock( &p_fetcher->lock );
vlc_object_signal_unlocked( p_fetcher );
}
else
vlc_gc_decref( p_current );
vlc_object_unlock( p_fetcher );
} }
else else
{ {
...@@ -643,7 +644,7 @@ void *playlist_PreparseLoop( void *data ) ...@@ -643,7 +644,7 @@ void *playlist_PreparseLoop( void *data )
vlc_restorecancel( canc ); vlc_restorecancel( canc );
} }
i_activity = var_GetInteger( p_playlist, "activity" ); int i_activity = var_GetInteger( p_playlist, "activity" );
if( i_activity < 0 ) i_activity = 0; if( i_activity < 0 ) i_activity = 0;
/* Sleep at least 1ms */ /* Sleep at least 1ms */
msleep( (i_activity+1) * 1000 ); msleep( (i_activity+1) * 1000 );
...@@ -656,36 +657,38 @@ void *playlist_PreparseLoop( void *data ) ...@@ -656,36 +657,38 @@ void *playlist_PreparseLoop( void *data )
/** /**
* Fetcher loop * Fetcher loop
* *
* Main loop for secondary preparser queue * \return never
* \param p_obj items to preparse
* \return nothing
*/ */
void playlist_FetcherLoop( playlist_fetcher_t *p_obj ) void *playlist_FetcherLoop( void *data )
{ {
playlist_t *p_playlist = (playlist_t *)p_obj->p_parent; playlist_fetcher_t *p_fetcher = data;
input_item_t *p_item; playlist_t *p_playlist = &((playlist_private_t *)(((char *)p_fetcher)
int i_activity; - offsetof(playlist_private_t, fetcher)))->public_data;
vlc_object_lock( p_obj );
while( vlc_object_alive( p_obj ) ) for( ;; )
{ {
if( p_obj->i_waiting == 0 ) input_item_t *p_item;
{
vlc_object_wait( p_obj ); vlc_mutex_lock( &p_fetcher->lock );
continue; mutex_cleanup_push( &p_fetcher->lock );
}
while( p_fetcher->i_waiting == 0 )
vlc_cond_wait( &p_fetcher->wait, &p_fetcher->lock );
p_item = p_obj->pp_waiting[0]; p_item = p_fetcher->pp_waiting[0];
REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 ); REMOVE_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, 0 );
vlc_object_unlock( p_obj ); vlc_cleanup_run( );
int canc = vlc_savecancel();
if( p_item ) if( p_item )
{ {
int i_ret; int i_ret;
/* Check if it is not yet preparsed and if so wait for it (at most 0.5s) /* Check if it is not yet preparsed and if so wait for it
* (at most 0.5s)
* (This can happen if we fetch art on play) * (This can happen if we fetch art on play)
* FIXME this doesn't work if we need to fetch meta before art ... */ * FIXME this doesn't work if we need to fetch meta before art...
*/
for( i_ret = 0; i_ret < 10 && !input_item_IsPreparsed( p_item ); i_ret++ ) for( i_ret = 0; i_ret < 10 && !input_item_IsPreparsed( p_item ); i_ret++ )
{ {
bool b_break; bool b_break;
...@@ -723,22 +726,16 @@ void playlist_FetcherLoop( playlist_fetcher_t *p_obj ) ...@@ -723,22 +726,16 @@ void playlist_FetcherLoop( playlist_fetcher_t *p_obj )
} }
vlc_gc_decref( p_item ); vlc_gc_decref( p_item );
} }
vlc_object_lock( p_obj ); vlc_restorecancel( canc );
i_activity = var_GetInteger( p_playlist, "activity" );
int i_activity = var_GetInteger( p_playlist, "activity" );
if( i_activity < 0 ) i_activity = 0; if( i_activity < 0 ) i_activity = 0;
vlc_object_unlock( p_obj );
/* Sleep at least 1ms */ /* Sleep at least 1ms */
msleep( (i_activity+1) * 1000 ); msleep( (i_activity+1) * 1000 );
vlc_object_lock( p_obj );
}
while( p_obj->i_waiting > 0 )
{
vlc_gc_decref( p_obj->pp_waiting[0] );
REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 );
} }
vlc_object_unlock( p_obj ); assert( 0 );
return NULL;
} }
static void VariablesInit( playlist_t *p_playlist ) static void VariablesInit( playlist_t *p_playlist )
......
...@@ -49,11 +49,13 @@ typedef struct playlist_preparse_t ...@@ -49,11 +49,13 @@ typedef struct playlist_preparse_t
typedef struct playlist_fetcher_t typedef struct playlist_fetcher_t
{ {
VLC_COMMON_MEMBERS vlc_thread_t thread;
vlc_mutex_t lock; vlc_mutex_t lock;
vlc_cond_t wait;
int i_art_policy; int i_art_policy;
int i_waiting; int i_waiting;
input_item_t **pp_waiting; input_item_t **pp_waiting;
bool up;
DECL_ARRAY(playlist_album_t) albums; DECL_ARRAY(playlist_album_t) albums;
} playlist_fetcher_t; } playlist_fetcher_t;
...@@ -62,7 +64,7 @@ typedef struct playlist_private_t ...@@ -62,7 +64,7 @@ typedef struct playlist_private_t
{ {
playlist_t public_data; playlist_t public_data;
playlist_preparse_t preparse; /**< Preparser data */ playlist_preparse_t preparse; /**< Preparser data */
playlist_fetcher_t *p_fetcher; /**< Meta and art fetcher object */ playlist_fetcher_t fetcher; /**< Meta and art fetcher data */
sout_instance_t *p_sout; /**< Kept sout instance */ sout_instance_t *p_sout; /**< Kept sout instance */
} playlist_private_t; } playlist_private_t;
...@@ -86,7 +88,7 @@ playlist_t *playlist_Create ( vlc_object_t * ); ...@@ -86,7 +88,7 @@ playlist_t *playlist_Create ( vlc_object_t * );
void playlist_MainLoop( playlist_t * ); void playlist_MainLoop( playlist_t * );
void playlist_LastLoop( playlist_t * ); void playlist_LastLoop( playlist_t * );
void *playlist_PreparseLoop( void * ); void *playlist_PreparseLoop( void * );
void playlist_FetcherLoop( playlist_fetcher_t * ); void *playlist_FetcherLoop( void * );
void ResetCurrentlyPlaying( playlist_t *, bool, playlist_item_t * ); void ResetCurrentlyPlaying( playlist_t *, bool, playlist_item_t * );
......
...@@ -36,8 +36,6 @@ ...@@ -36,8 +36,6 @@
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static void* RunControlThread ( vlc_object_t * ); static void* RunControlThread ( vlc_object_t * );
static void* RunFetcher ( vlc_object_t * );
static void FetcherDestructor ( vlc_object_t * );
/***************************************************************************** /*****************************************************************************
* Main functions for the global thread * Main functions for the global thread
...@@ -73,30 +71,21 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) ...@@ -73,30 +71,21 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent )
p_preparse->up = true; p_preparse->up = true;
// Secondary Preparse // Secondary Preparse
static const char fname[] = "fetcher"; playlist_fetcher_t *p_fetcher = &pl_priv(p_playlist)->fetcher;
playlist_fetcher_t *p_fetcher = vlc_mutex_init (&p_fetcher->lock);
pl_priv(p_playlist)->p_fetcher = vlc_cond_init (&p_fetcher->wait);
vlc_custom_create( p_playlist, sizeof( playlist_fetcher_t ),
VLC_OBJECT_GENERIC, fname );
if( !p_fetcher )
{
msg_Err( p_playlist, "unable to create secondary preparser" );
vlc_object_release( p_playlist );
return;
}
p_fetcher->i_waiting = 0; p_fetcher->i_waiting = 0;
p_fetcher->pp_waiting = NULL; p_fetcher->pp_waiting = NULL;
p_fetcher->i_art_policy = var_CreateGetInteger( p_playlist, "album-art" ); p_fetcher->i_art_policy = var_CreateGetInteger( p_playlist, "album-art" );
vlc_object_set_destructor( p_fetcher, FetcherDestructor ); if( vlc_clone( &p_fetcher->thread, playlist_FetcherLoop, p_fetcher,
vlc_object_attach( p_fetcher, p_playlist ); VLC_THREAD_PRIORITY_LOW ) )
if( vlc_thread_create( p_fetcher, "fetcher", RunFetcher,
VLC_THREAD_PRIORITY_LOW, false ) )
{ {
msg_Err( p_playlist, "cannot spawn secondary preparse thread" ); msg_Err( p_playlist, "cannot spawn secondary preparse thread" );
vlc_object_release( p_fetcher ); p_fetcher->up = false;
return; return;
} }
p_fetcher->up = true;
// Start the thread // Start the thread
if( vlc_thread_create( p_playlist, "playlist", RunControlThread, if( vlc_thread_create( p_playlist, "playlist", RunControlThread,
...@@ -151,19 +140,3 @@ static void* RunControlThread ( vlc_object_t *p_this ) ...@@ -151,19 +140,3 @@ static void* RunControlThread ( vlc_object_t *p_this )
vlc_restorecancel (canc); vlc_restorecancel (canc);
return NULL; return NULL;
} }
static void* RunFetcher( vlc_object_t *p_this )
{
playlist_fetcher_t *p_obj = (playlist_fetcher_t *)p_this;
int canc = vlc_savecancel ();
playlist_FetcherLoop( p_obj );
vlc_restorecancel (canc);
return NULL;
}
static void FetcherDestructor( vlc_object_t * p_this )
{
playlist_fetcher_t * p_fetcher = (playlist_fetcher_t *)p_this;
free( p_fetcher->pp_waiting );
msg_Dbg( p_this, "Destroyed" );
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment