[vlc-devel] [RFC PATCH 8/8] dsm/sd: thread stay alive and handle commands
Thomas Guillem
thomas at gllm.fr
Thu Nov 27 12:32:17 CET 2014
On Thu, Nov 27, 2014, at 12:00, Thomas Guillem wrote:
> ---
> modules/access/dsm/sd.c | 176
> ++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 148 insertions(+), 28 deletions(-)
>
> diff --git a/modules/access/dsm/sd.c b/modules/access/dsm/sd.c
> index 8c4cddf..4cf4796 100644
> --- a/modules/access/dsm/sd.c
> +++ b/modules/access/dsm/sd.c
> @@ -34,8 +34,14 @@
>
> struct services_discovery_sys_t
> {
> - netbios_ns *ns;
> + bdsm_sys_t bdsm;
> vlc_thread_t thread;
> + vlc_mutex_t mutex;
> + vlc_cond_t cond;
> +
> + bool b_stop;
> + enum services_discovery_command_e cmd;
> + char *psz_cmd_arg;
> };
>
> int bdsm_sd_probe_Open (vlc_object_t *p_this)
> @@ -48,64 +54,169 @@ int bdsm_sd_probe_Open (vlc_object_t *p_this)
> return VLC_PROBE_CONTINUE;
> }
>
> +static bool IsStopped (services_discovery_t *p_sd)
> +{
> + services_discovery_sys_t *p_sys = p_sd->p_sys;
> +
> + bool b_stop;
> + vlc_mutex_lock( &p_sys->mutex );
> + b_stop = p_sys->b_stop;
> + vlc_mutex_unlock( &p_sys->mutex );
> + return b_stop;
> +}
> +
> +static int AddToSD (void *p_ctx, input_item_t *p_item)
> +{
> + services_discovery_t *p_sd = p_ctx;
> + services_discovery_AddItem( p_sd, p_item, NULL );
> + return 0;
> +}
> +
> +static int SdNavigate (services_discovery_t *p_sd, const char *psz_path)
> +{
> + services_discovery_sys_t *p_sys = p_sd->p_sys;
> + netbios_ns *ns = p_sys->bdsm.p_ns;
> +
> + if( psz_path == NULL ) {
> + /* search for netbios */
> + if( !netbios_ns_discover( ns ) )
> + return VLC_EGENERIC;
> +
> + if( IsStopped( p_sd ) )
> + return VLC_EGENERIC;
> +
> + for( ssize_t i = 0; i < netbios_ns_entry_count( ns ); i++ )
> + {
> + netbios_ns_entry *p_entry = netbios_ns_entry_at( ns, i );
> +
> + if( p_entry->type == 0x20 )
> + {
> + input_item_t *p_item;
> + char *psz_mrl;
> +
> + if( asprintf(&psz_mrl, "smb://%s", p_entry->name) < 0 )
> + return VLC_EGENERIC;
> +
> + p_item = input_item_NewWithType( psz_mrl, p_entry->name,
> 0, NULL,
> + 0, -1, ITEM_TYPE_NODE
> );
> + msg_Dbg( p_sd, "Adding item %s", psz_mrl );
> +
> + services_discovery_AddItem( p_sd, p_item, NULL );
> +
> + free( psz_mrl );
> + }
> + }
> + } else {
> + bdsm_item_cb_t cb;
> +
> + if( bdsm_Connect( &p_sys->bdsm, NULL, psz_path ) != VLC_SUCCESS
> )
> + return VLC_SUCCESS;
> +
> + cb.pf_add_item = AddToSD;
> + cb.p_ctx = p_sd;
> + bdsm_Browse( &p_sys->bdsm, &cb, psz_path );
> + }
> +
> + return VLC_SUCCESS;
> +}
> +
> static void *Run( void *data )
> {
> services_discovery_t *p_sd = data;
> - netbios_ns *ns;
> + services_discovery_sys_t *p_sys = p_sd->p_sys;
>
> /* Let's create a NETBIOS name service object */
> - ns = netbios_ns_new();
> - if( ns == NULL )
> + if( bdsm_Init( &p_sys->bdsm, VLC_OBJECT(p_sd) ) != VLC_SUCCESS )
> goto error;
>
> - if( !netbios_ns_discover( ns ) )
> - goto error;
> + while( true ) {
> + enum services_discovery_command_e cmd;
> + char *psz_cmd_arg;
> + int i_ret = 0;
> +
> + vlc_mutex_lock( &p_sys->mutex );
> + while( !p_sys->b_stop && p_sys->cmd == 0 )
> + vlc_cond_wait( &p_sys->cond, &p_sys->mutex );
> + if( p_sys->b_stop ) {
> + vlc_mutex_unlock( &p_sys->mutex );
> + break;
> + }
> + cmd = p_sys->cmd;
> + psz_cmd_arg = p_sys->psz_cmd_arg;
>
> - for( ssize_t i = 0; i < netbios_ns_entry_count( ns ); i++ )
> - {
> - netbios_ns_entry *p_entry = netbios_ns_entry_at( ns, i );
> + p_sys->cmd = 0;
> + p_sys->psz_cmd_arg = NULL;
>
> - if( p_entry->type == 0x20 )
> + vlc_mutex_unlock( &p_sys->mutex );
> + switch( cmd )
> {
> - input_item_t *p_item;
> - char *psz_mrl;
> + case SD_CMD_NAVIGATE:
> + i_ret = SdNavigate( p_sd, psz_cmd_arg );
> + break;
> + default:
> + msg_Warn( p_sd, "unknown command ");
> + }
>
> - if( asprintf(&psz_mrl, "smb://%s", p_entry->name) < 0 )
> - goto error;
> + free(psz_cmd_arg);
> + if( i_ret != 0 )
> + break;
> + }
> + error:
> + msg_Err( p_sd, "thread exited" );
> + bdsm_Destroy( &p_sys->bdsm );
>
> - p_item = input_item_NewWithType( psz_mrl, p_entry->name, 0,
> NULL,
> - 0, -1, ITEM_TYPE_NODE );
> - msg_Dbg( p_sd, "Adding item %s", psz_mrl );
> + return NULL;
> +}
> +
> +static int Control (services_discovery_t *p_sd, int i_control, va_list
> args)
> +{
> + services_discovery_sys_t *p_sys = p_sd->p_sys;
>
> - services_discovery_AddItem( p_sd, p_item, NULL );
> + switch( i_control)
> + {
> + case SD_CMD_NAVIGATE:
> + {
> + const char *psz_path = va_arg( args, const char * );
>
> - free( psz_mrl );
> + vlc_mutex_lock( &p_sys->mutex );
> + p_sys->cmd = i_control;
> + p_sys->psz_cmd_arg = psz_path ? strdup( psz_path ) : NULL;
Forgot a vlc_cond_signal here.
> + vlc_mutex_unlock( &p_sys->mutex );
> + return VLC_SUCCESS;
> }
> }
> - error:
> - if( ns != NULL )
> - netbios_ns_destroy( ns );
> -
> - return NULL;
> + return VLC_EGENERIC;
> }
>
> int bdsm_SdOpen (vlc_object_t *p_this)
> {
> services_discovery_t *p_sd = (services_discovery_t *)p_this;
> - services_discovery_sys_t *p_sys = malloc (sizeof (*p_sys));
> + services_discovery_sys_t *p_sys = calloc (1, sizeof (*p_sys));
>
> if( p_sys == NULL )
> return VLC_ENOMEM;
>
> p_sd->p_sys = p_sys;
>
> + vlc_mutex_init( &p_sys->mutex );
> + vlc_cond_init( &p_sys->cond );
> +
> + p_sys->cmd = SD_CMD_NAVIGATE;
> + p_sys->psz_cmd_arg = NULL;
> +
> if( vlc_clone( &p_sys->thread, Run, p_sd, VLC_THREAD_PRIORITY_LOW )
> )
> {
> - free(p_sys);
> - return VLC_EGENERIC;
> + p_sys->thread = 0;
> + goto error;
> }
>
> + p_sd->pf_control = Control;
> +
> return VLC_SUCCESS;
> +
> + error:
> + bdsm_SdClose( p_this );
> + return VLC_EGENERIC;
> }
>
> void bdsm_SdClose (vlc_object_t *p_this)
> @@ -116,7 +227,16 @@ void bdsm_SdClose (vlc_object_t *p_this)
> if( p_sys == NULL )
> return;
>
> - vlc_join( p_sys->thread, NULL );
> + if( p_sys->thread ) {
> + vlc_mutex_lock( &p_sys->mutex );
> + p_sys->b_stop = true;
> + vlc_cond_signal( &p_sys->cond );
> + vlc_mutex_unlock( &p_sys->mutex );
> + vlc_join( p_sys->thread, NULL );
> + }
> +
> + vlc_mutex_destroy( &p_sys->mutex );
> + vlc_cond_destroy( &p_sys->cond );
>
> free( p_sys );
> }
> --
> 2.1.3
>
More information about the vlc-devel
mailing list