Commit 6a327f35 authored by Francois Cartegnie's avatar Francois Cartegnie

addons: fix threading and cancelable sections

parent 314047bf
...@@ -48,6 +48,7 @@ struct addons_manager_private_t ...@@ -48,6 +48,7 @@ struct addons_manager_private_t
struct struct
{ {
vlc_thread_t thread; vlc_thread_t thread;
vlc_cond_t waitcond;
bool b_live; bool b_live;
vlc_mutex_t lock; vlc_mutex_t lock;
char *psz_uri_hint; /* uri hint for non repo based install */ char *psz_uri_hint; /* uri hint for non repo based install */
...@@ -57,6 +58,7 @@ struct addons_manager_private_t ...@@ -57,6 +58,7 @@ struct addons_manager_private_t
struct struct
{ {
vlc_thread_t thread; vlc_thread_t thread;
vlc_cond_t waitcond;
bool b_live; bool b_live;
vlc_mutex_t lock; vlc_mutex_t lock;
DECL_ARRAY(addon_entry_t*) entries; DECL_ARRAY(addon_entry_t*) entries;
...@@ -147,6 +149,7 @@ addons_manager_t *addons_manager_New( vlc_object_t *p_this ) ...@@ -147,6 +149,7 @@ addons_manager_t *addons_manager_New( vlc_object_t *p_this )
#define INIT_QUEUE( name ) \ #define INIT_QUEUE( name ) \
p_manager->p_priv->name.b_live = false;\ p_manager->p_priv->name.b_live = false;\
vlc_mutex_init( &p_manager->p_priv->name.lock );\ vlc_mutex_init( &p_manager->p_priv->name.lock );\
vlc_cond_init( &p_manager->p_priv->name.waitcond );\
ARRAY_INIT( p_manager->p_priv->name.entries ); ARRAY_INIT( p_manager->p_priv->name.entries );
INIT_QUEUE( finder ) INIT_QUEUE( finder )
...@@ -164,18 +167,25 @@ addons_manager_t *addons_manager_New( vlc_object_t *p_this ) ...@@ -164,18 +167,25 @@ addons_manager_t *addons_manager_New( vlc_object_t *p_this )
void addons_manager_Delete( addons_manager_t *p_manager ) void addons_manager_Delete( addons_manager_t *p_manager )
{ {
bool b_live;
vlc_mutex_lock( &p_manager->p_priv->finder.lock ); vlc_mutex_lock( &p_manager->p_priv->finder.lock );
if ( p_manager->p_priv->finder.b_live ) b_live = p_manager->p_priv->finder.b_live;
vlc_cancel( p_manager->p_priv->finder.thread );
vlc_mutex_unlock( &p_manager->p_priv->finder.lock ); vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
if ( b_live )
{
vlc_cancel( p_manager->p_priv->finder.thread );
vlc_join( p_manager->p_priv->finder.thread, NULL );
}
vlc_mutex_lock( &p_manager->p_priv->installer.lock ); vlc_mutex_lock( &p_manager->p_priv->installer.lock );
if ( p_manager->p_priv->installer.b_live ) b_live = p_manager->p_priv->installer.b_live;
vlc_cancel( p_manager->p_priv->installer.thread );
vlc_mutex_unlock( &p_manager->p_priv->installer.lock ); vlc_mutex_unlock( &p_manager->p_priv->installer.lock );
if ( b_live )
vlc_join( p_manager->p_priv->finder.thread, NULL ); {
vlc_join( p_manager->p_priv->installer.thread, NULL ); vlc_cancel( p_manager->p_priv->installer.thread );
vlc_join( p_manager->p_priv->installer.thread, NULL );
}
vlc_event_manager_fini( p_manager->p_event_manager ); vlc_event_manager_fini( p_manager->p_event_manager );
...@@ -186,7 +196,8 @@ void addons_manager_Delete( addons_manager_t *p_manager ) ...@@ -186,7 +196,8 @@ void addons_manager_Delete( addons_manager_t *p_manager )
FOREACH_END();\ FOREACH_END();\
ARRAY_RESET( p_manager->p_priv->name.entries );\ ARRAY_RESET( p_manager->p_priv->name.entries );\
vlc_mutex_unlock( &p_manager->p_priv->name.lock );\ vlc_mutex_unlock( &p_manager->p_priv->name.lock );\
vlc_mutex_destroy( &p_manager->p_priv->name.lock ); vlc_mutex_destroy( &p_manager->p_priv->name.lock );\
vlc_cond_destroy( &p_manager->p_priv->name.waitcond );
FREE_QUEUE( finder ) FREE_QUEUE( finder )
FREE_QUEUE( installer ) FREE_QUEUE( installer )
...@@ -200,12 +211,6 @@ void addons_manager_Delete( addons_manager_t *p_manager ) ...@@ -200,12 +211,6 @@ void addons_manager_Delete( addons_manager_t *p_manager )
void addons_manager_Gather( addons_manager_t *p_manager, const char *psz_uri ) void addons_manager_Gather( addons_manager_t *p_manager, const char *psz_uri )
{ {
vlc_mutex_lock( &p_manager->p_priv->finder.lock ); vlc_mutex_lock( &p_manager->p_priv->finder.lock );
if( p_manager->p_priv->finder.b_live )
{
/* Ignore if we're already running */
vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
return;
}
if ( psz_uri ) if ( psz_uri )
{ {
p_manager->p_priv->finder.psz_uri_hint = strdup( psz_uri ); p_manager->p_priv->finder.psz_uri_hint = strdup( psz_uri );
...@@ -214,12 +219,20 @@ void addons_manager_Gather( addons_manager_t *p_manager, const char *psz_uri ) ...@@ -214,12 +219,20 @@ void addons_manager_Gather( addons_manager_t *p_manager, const char *psz_uri )
{ {
if( vlc_clone( &p_manager->p_priv->finder.thread, FinderThread, p_manager, if( vlc_clone( &p_manager->p_priv->finder.thread, FinderThread, p_manager,
VLC_THREAD_PRIORITY_LOW ) ) VLC_THREAD_PRIORITY_LOW ) )
{
msg_Err( p_manager->p_priv->p_parent, msg_Err( p_manager->p_priv->p_parent,
"cannot spawn entries provider thread" ); "cannot spawn entries provider thread" );
else vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
p_manager->p_priv->finder.b_live = true; return;
}
p_manager->p_priv->finder.b_live = true;
vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
}
else
{
vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
vlc_cond_signal( &p_manager->p_priv->finder.waitcond );
} }
vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
} }
/***************************************************************************** /*****************************************************************************
...@@ -307,40 +320,47 @@ static void *FinderThread( void *p_data ) ...@@ -307,40 +320,47 @@ static void *FinderThread( void *p_data )
addons_manager_t *p_manager = p_data; addons_manager_t *p_manager = p_data;
int i_cancel; int i_cancel;
addons_finder_t *p_finder = for( ;; )
vlc_custom_create( p_manager->p_priv->p_parent, sizeof( *p_finder ), "entries finder" );
if( p_finder != NULL )
{ {
module_t *p_module; addons_finder_t *p_finder =
ARRAY_INIT( p_finder->entries ); vlc_custom_create( p_manager->p_priv->p_parent, sizeof( *p_finder ), "entries finder" );
p_finder->psz_uri = p_manager->p_priv->finder.psz_uri_hint;
p_manager->p_priv->finder.psz_uri_hint = NULL;
p_module = module_need( p_finder, "addons finder", NULL, false ); i_cancel = vlc_savecancel();
if( p_module ) if( p_finder != NULL )
{ {
i_cancel = vlc_savecancel(); module_t *p_module;
p_finder->pf_find( p_finder ); ARRAY_INIT( p_finder->entries );
vlc_restorecancel( i_cancel ); vlc_mutex_lock( &p_manager->p_priv->finder.lock );
module_unneed( p_finder, p_module ); p_finder->psz_uri = p_manager->p_priv->finder.psz_uri_hint;
p_manager->p_priv->finder.psz_uri_hint = NULL;
MergeSources( p_manager, p_finder->entries.p_elems, p_finder->entries.i_size ); vlc_mutex_unlock( &p_manager->p_priv->finder.lock );
p_module = module_need( p_finder, "addons finder", NULL, false );
if( p_module )
{
p_finder->pf_find( p_finder );
module_unneed( p_finder, p_module );
MergeSources( p_manager, p_finder->entries.p_elems, p_finder->entries.i_size );
}
ARRAY_RESET( p_finder->entries );
free( p_finder->psz_uri );
vlc_object_release( p_finder );
} }
ARRAY_RESET( p_finder->entries ); vlc_event_t event;
free( p_finder->psz_uri ); event.type = vlc_AddonsDiscoveryEnded;
vlc_object_release( p_finder ); event.u.addon_generic_event.p_entry = NULL;
} vlc_event_send( p_manager->p_event_manager, &event );
vlc_mutex_lock( & p_manager->p_priv->finder.lock ); vlc_restorecancel( i_cancel );
p_manager->p_priv->finder.b_live = false; vlc_testcancel();
vlc_mutex_unlock( & p_manager->p_priv->finder.lock );
vlc_event_t event; vlc_mutex_lock( &p_manager->p_priv->finder.lock );
event.type = vlc_AddonsDiscoveryEnded; vlc_cleanup_push( vlc_mutex_unlock, &p_manager->p_priv->finder.lock );
event.u.addon_generic_event.p_entry = NULL; vlc_cond_wait( &p_manager->p_priv->finder.waitcond,
vlc_event_send( p_manager->p_event_manager, &event ); &p_manager->p_priv->finder.lock );
vlc_cleanup_run();
}
return NULL; return NULL;
} }
...@@ -412,15 +432,15 @@ static void *InstallerThread( void *p_data ) ...@@ -412,15 +432,15 @@ static void *InstallerThread( void *p_data )
for( ;; ) for( ;; )
{ {
vlc_testcancel();
vlc_mutex_lock( &p_manager->p_priv->installer.lock ); vlc_mutex_lock( &p_manager->p_priv->installer.lock );
if ( !p_manager->p_priv->installer.entries.i_size ) vlc_cleanup_push( vlc_mutex_unlock, &p_manager->p_priv->installer.lock );
while ( !p_manager->p_priv->installer.entries.i_size )
{ {
/* No queued addons */ /* No queued addons */
p_manager->p_priv->installer.b_live = false; vlc_cond_wait( &p_manager->p_priv->installer.waitcond,
vlc_mutex_unlock( &p_manager->p_priv->installer.lock ); &p_manager->p_priv->installer.lock );
break;
} }
vlc_cleanup_pop();
addon_entry_t *p_entry = p_manager->p_priv->installer.entries.p_elems[0]; addon_entry_t *p_entry = p_manager->p_priv->installer.entries.p_elems[0];
ARRAY_REMOVE( p_manager->p_priv->installer.entries, 0 ); ARRAY_REMOVE( p_manager->p_priv->installer.entries, 0 );
...@@ -435,10 +455,10 @@ static void *InstallerThread( void *p_data ) ...@@ -435,10 +455,10 @@ static void *InstallerThread( void *p_data )
vlc_mutex_unlock( &p_entry->lock ); vlc_mutex_unlock( &p_entry->lock );
/* notify */ /* notify */
i_cancel = vlc_savecancel();
event.u.addon_generic_event.p_entry = p_entry; event.u.addon_generic_event.p_entry = p_entry;
vlc_event_send( p_manager->p_event_manager, &event ); vlc_event_send( p_manager->p_event_manager, &event );
i_cancel = vlc_savecancel();
i_ret = installOrRemoveAddon( p_manager, p_entry, false ); i_ret = installOrRemoveAddon( p_manager, p_entry, false );
vlc_restorecancel( i_cancel ); vlc_restorecancel( i_cancel );
...@@ -453,10 +473,10 @@ static void *InstallerThread( void *p_data ) ...@@ -453,10 +473,10 @@ static void *InstallerThread( void *p_data )
vlc_mutex_unlock( &p_entry->lock ); vlc_mutex_unlock( &p_entry->lock );
/* notify */ /* notify */
i_cancel = vlc_savecancel();
event.u.addon_generic_event.p_entry = p_entry; event.u.addon_generic_event.p_entry = p_entry;
vlc_event_send( p_manager->p_event_manager, &event ); vlc_event_send( p_manager->p_event_manager, &event );
i_cancel = vlc_savecancel();
i_ret = installOrRemoveAddon( p_manager, p_entry, true ); i_ret = installOrRemoveAddon( p_manager, p_entry, true );
vlc_restorecancel( i_cancel ); vlc_restorecancel( i_cancel );
...@@ -469,15 +489,17 @@ static void *InstallerThread( void *p_data ) ...@@ -469,15 +489,17 @@ static void *InstallerThread( void *p_data )
vlc_mutex_unlock( &p_entry->lock ); vlc_mutex_unlock( &p_entry->lock );
/* !DO WORK */ /* !DO WORK */
i_cancel = vlc_savecancel();
event.u.addon_generic_event.p_entry = p_entry; event.u.addon_generic_event.p_entry = p_entry;
vlc_event_send( p_manager->p_event_manager, &event ); vlc_event_send( p_manager->p_event_manager, &event );
vlc_restorecancel( i_cancel );
addon_entry_Release( p_entry ); addon_entry_Release( p_entry );
}
i_cancel = vlc_savecancel(); i_cancel = vlc_savecancel();
addons_manager_WriteCatalog( p_manager ); addons_manager_WriteCatalog( p_manager );
vlc_restorecancel( i_cancel ); vlc_restorecancel( i_cancel );
}
return NULL; return NULL;
} }
...@@ -495,12 +517,17 @@ static int InstallEntry( addons_manager_t *p_manager, addon_entry_t *p_entry ) ...@@ -495,12 +517,17 @@ static int InstallEntry( addons_manager_t *p_manager, addon_entry_t *p_entry )
{ {
if( vlc_clone( &p_manager->p_priv->installer.thread, InstallerThread, p_manager, if( vlc_clone( &p_manager->p_priv->installer.thread, InstallerThread, p_manager,
VLC_THREAD_PRIORITY_LOW ) ) VLC_THREAD_PRIORITY_LOW ) )
{
msg_Err( p_manager->p_priv->p_parent, msg_Err( p_manager->p_priv->p_parent,
"cannot spawn addons installer thread" ); "cannot spawn addons installer thread" );
vlc_mutex_unlock( &p_manager->p_priv->installer.lock );
return VLC_EGENERIC;
}
else else
p_manager->p_priv->installer.b_live = true; p_manager->p_priv->installer.b_live = true;
} }
vlc_mutex_unlock( &p_manager->p_priv->installer.lock ); vlc_mutex_unlock( &p_manager->p_priv->installer.lock );
vlc_cond_signal( &p_manager->p_priv->installer.waitcond );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
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