[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