Commit 7a87d576 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Debug audio output lock ordering

parent 47f7069e
...@@ -164,51 +164,83 @@ int aout_DecGetResetLost( aout_instance_t *, aout_input_t * ); ...@@ -164,51 +164,83 @@ int aout_DecGetResetLost( aout_instance_t *, aout_input_t * );
void aout_DecChangePause( aout_instance_t *, aout_input_t *, bool b_paused, mtime_t i_date ); void aout_DecChangePause( aout_instance_t *, aout_input_t *, bool b_paused, mtime_t i_date );
void aout_DecFlush( aout_instance_t *, aout_input_t * ); void aout_DecFlush( aout_instance_t *, aout_input_t * );
/* Helpers */ /* Audio output locking */
#if !defined (NDEBUG) \
&& defined __linux__ && (defined (__i386__) || defined (__x86_64__))
# define AOUT_DEBUG 1
#endif
#ifdef AOUT_DEBUG
enum
{
MIXER_LOCK=1,
INPUT_LOCK=2,
INPUT_FIFO_LOCK=4,
OUTPUT_FIFO_LOCK=8,
};
void aout_lock (unsigned);
void aout_unlock (unsigned);
#else
# define aout_lock( i ) (void)0
# define aout_unlock( i ) (void)0
#endif
static inline void aout_lock_mixer( aout_instance_t *p_aout ) static inline void aout_lock_mixer( aout_instance_t *p_aout )
{ {
aout_lock( MIXER_LOCK );
vlc_mutex_lock( &p_aout->mixer_lock ); vlc_mutex_lock( &p_aout->mixer_lock );
} }
static inline void aout_unlock_mixer( aout_instance_t *p_aout ) static inline void aout_unlock_mixer( aout_instance_t *p_aout )
{ {
aout_unlock( MIXER_LOCK );
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->mixer_lock );
} }
static inline void aout_lock_input_fifos( aout_instance_t *p_aout ) static inline void aout_lock_input_fifos( aout_instance_t *p_aout )
{ {
aout_lock( INPUT_FIFO_LOCK );
vlc_mutex_lock( &p_aout->input_fifos_lock ); vlc_mutex_lock( &p_aout->input_fifos_lock );
} }
static inline void aout_unlock_input_fifos( aout_instance_t *p_aout ) static inline void aout_unlock_input_fifos( aout_instance_t *p_aout )
{ {
aout_unlock( INPUT_FIFO_LOCK );
vlc_mutex_unlock( &p_aout->input_fifos_lock ); vlc_mutex_unlock( &p_aout->input_fifos_lock );
} }
static inline void aout_lock_output_fifo( aout_instance_t *p_aout ) static inline void aout_lock_output_fifo( aout_instance_t *p_aout )
{ {
aout_lock( OUTPUT_FIFO_LOCK );
vlc_mutex_lock( &p_aout->output_fifo_lock ); vlc_mutex_lock( &p_aout->output_fifo_lock );
} }
static inline void aout_unlock_output_fifo( aout_instance_t *p_aout ) static inline void aout_unlock_output_fifo( aout_instance_t *p_aout )
{ {
aout_unlock( OUTPUT_FIFO_LOCK );
vlc_mutex_unlock( &p_aout->output_fifo_lock ); vlc_mutex_unlock( &p_aout->output_fifo_lock );
} }
static inline void aout_lock_input( aout_instance_t *p_aout, aout_input_t * p_input ) static inline void aout_lock_input( aout_instance_t *p_aout, aout_input_t * p_input )
{ {
(void)p_aout; (void)p_aout;
aout_lock( INPUT_LOCK );
vlc_mutex_lock( &p_input->lock ); vlc_mutex_lock( &p_input->lock );
} }
static inline void aout_unlock_input( aout_instance_t *p_aout, aout_input_t * p_input ) static inline void aout_unlock_input( aout_instance_t *p_aout, aout_input_t * p_input )
{ {
(void)p_aout; (void)p_aout;
aout_unlock( INPUT_LOCK );
vlc_mutex_unlock( &p_input->lock ); vlc_mutex_unlock( &p_input->lock );
} }
/* Helpers */
/** /**
* This function will safely mark aout input to be restarted as soon as * This function will safely mark aout input to be restarted as soon as
* possible to take configuration changes into account */ * possible to take configuration changes into account */
......
...@@ -114,6 +114,54 @@ static void aout_Destructor( vlc_object_t * p_this ) ...@@ -114,6 +114,54 @@ static void aout_Destructor( vlc_object_t * p_this )
vlc_mutex_destroy( &p_aout->output_fifo_lock ); vlc_mutex_destroy( &p_aout->output_fifo_lock );
} }
/* Lock ordering rules:
*
* Mixer Input IFIFO OFIFO (< Inner lock)
* Mixer No! N/A Yes Yes
* Input N/A No! Yes N/A
* In FIFOs No! No! No! No!
* Out FIFOs No! N/A Yes No!
* (^ Outer lock)
*/
#ifdef AOUT_DEBUG
/* Lock debugging */
static __thread unsigned aout_locks = 0;
void aout_lock (unsigned i)
{
unsigned allowed;
switch (i)
{
case MIXER_LOCK:
allowed = 0;
break;
case INPUT_LOCK:
allowed = 0;
break;
case OUTPUT_FIFO_LOCK:
allowed = MIXER_LOCK;
break;
case INPUT_FIFO_LOCK:
allowed = MIXER_LOCK|INPUT_LOCK|OUTPUT_FIFO_LOCK;
break;
}
if (aout_locks & ~allowed)
{
fprintf (stderr, "Illegal audio lock transition (%x -> %x)\n",
aout_locks, aout_locks|i);
vlc_backtrace ();
//abort ();
}
aout_locks |= i;
}
void aout_unlock (unsigned i)
{
assert (aout_locks & i);
aout_locks &= ~i;
}
#endif
/* /*
* Formats management (internal and external) * Formats management (internal and external)
......
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