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

Tristan Matthews le.businessman at gmail.com
Thu May 2 16:45:29 CEST 2013


On Thu, May 2, 2013 at 10:22 AM, Rémi Denis-Courmont <remi at remlab.net> wrote:
> 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?

Aside from affecting the ringbuffer, I guess it's not related.
I will send it as a separate 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>.

Ok, will fix and resend.

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



--
Tristan Matthews
web: http://tristanswork.blogspot.com



More information about the vlc-devel mailing list