[vlc-devel] [PATCH] jack: don't deactivate/activate client in Flush()

Rémi Denis-Courmont remi at remlab.net
Thu May 2 16:22:58 CEST 2013


Le jeudi 2 mai 2013 16:36:36, Tristan Matthews a écrit :
> Instead, protect the resetting of the ringbuffer with an atomic
> flag, to avoid resetting while its being read by the Process()
> thread. Fixes #8551
> ---
>  modules/audio_output/jack.c | 72
> +++++++++++---------------------------------- 1 file changed, 17
> insertions(+), 55 deletions(-)
> 
> diff --git a/modules/audio_output/jack.c b/modules/audio_output/jack.c
> index 4571394..552cc52 100644
> --- a/modules/audio_output/jack.c
> +++ b/modules/audio_output/jack.c
> @@ -37,6 +37,7 @@
>  #include <vlc_common.h>
>  #include <vlc_plugin.h>
>  #include <vlc_aout.h>
> +#include <vlc_atomic.h>
> 
>  #include <jack/jack.h>
>  #include <jack/ringbuffer.h>
> @@ -61,6 +62,7 @@ struct aout_sys_t
>      float soft_gain;
>      bool soft_mute;
>      mtime_t paused; /**< Time when (last) paused */
> +    vlc_atomic_t reset_safe;
>  };
> 
>  /*************************************************************************
> **** @@ -117,6 +119,7 @@ static int Start( audio_output_t *p_aout,
> audio_sample_format_t *restrict fmt )
> 
>      p_sys->latency = 0;
>      p_sys->paused = VLC_TS_INVALID;
> +    vlc_atomic_set( &p_sys->reset_safe, true );
> 
>      /* Connect to the JACK server */
>      snprintf( psz_name, sizeof(psz_name), "vlc_%d", getpid());
> @@ -175,6 +178,12 @@ static int Start( audio_output_t *p_aout,
> audio_sample_format_t *restrict fmt ) goto error_out;
>      }
> 
> +    if( jack_ringbuffer_mlock( p_sys->p_jack_ringbuffer ))
> +    {
> +        msg_Err( p_aout, "failed to lock JACK ringbuffer in memory" );
> +        status = VLC_EGENERIC;
> +    }
> +

What does that have to do with the rest of the patch?

>      /* Create the output ports */
>      for( i = 0; i < p_sys->i_channels; i++ )
>      {
> @@ -307,8 +316,6 @@ static void Flush(audio_output_t *p_aout, bool wait)
>  {
>      struct aout_sys_t * p_sys = p_aout->sys;
>      jack_ringbuffer_t *rb = p_sys->p_jack_ringbuffer;
> -    jack_client_t *client = p_sys->p_jack_client;
> -    int i_error;
> 
>      /* Sleep if wait was requested */
>      if( wait )
> @@ -318,60 +325,9 @@ static void Flush(audio_output_t *p_aout, bool wait)
>              msleep(delay);
>      }
> 
> -    /* FIXME: maybe the ringbuffer_reset should just be protected by
> signalling -     * with atomic variables?
> -     * Here we save and restore connections, otherwise we'd lose the
> connections -     * every seek because of the deactivate/activate */
> -
> -    /* Save connections */
> -    const char **connections_list[p_sys->i_channels];
> -
> -    for( size_t i = 0; i < p_sys->i_channels; i++ )
> -    {
> -        const char **port_connections = jack_port_get_all_connections(
> client, -                p_sys->p_jack_ports[i] );
> -        connections_list[i] = port_connections;
> -    }
> -
> -    /* Suspend audio processing */
> -    i_error = jack_deactivate( p_sys->p_jack_client );
> -    if( i_error )
> -    {
> -        msg_Err( p_aout, "failed to deactivate JACK client (error %d)",
> -                i_error );
> -        return;
> -    }
> -
>      /* reset ringbuffer read and write pointers */
> -    jack_ringbuffer_reset(rb);
> -
> -    /* Resume audio processing */
> -    i_error = jack_activate( p_sys->p_jack_client );
> -    if( i_error )
> -    {
> -        msg_Err( p_aout, "failed to activate JACK client (error %d)",
> i_error ); -        return;
> -    }
> -
> -    /* Restore connections */
> -    for( size_t i = 0; i < p_sys->i_channels; i++ )
> -    {
> -        const char **port_connections = connections_list[i];
> -        const char *psz_out = jack_port_name( p_sys->p_jack_ports[i] );
> -        for (const char **psz_in = port_connections; psz_in && *psz_in;
> -                psz_in++)
> -        {
> -            i_error = jack_connect( client, psz_out, *psz_in );
> -            if( i_error )
> -            {
> -                msg_Err( p_aout, "failed to connect ports %s and %s (error
> %d)", -                        psz_out, *psz_in, i_error );
> -            }
> -        }
> -
> -        if( port_connections )
> -            jack_free(port_connections);
> -    }
> +    if( vlc_atomic_get( &p_sys->reset_safe ) )
> +        jack_ringbuffer_reset(rb);

This does not look valid to me. I see no proof that reset_safe did not change 
to false after vlc_atomic_get() and before jack_ringbuffer_reset(). Besides, 
the same problem already exists with paused and latency so I gather the JACK 
plugin is not thread-safe (and, AFAIK, never was).

If you do not care about race conditions, then there is no point in using 
<vlc_atomic.h>.

-- 
Rémi Denis-Courmont
http://www.remlab.net/



More information about the vlc-devel mailing list