Skip to content
Snippets Groups Projects
Commit 7dcc370d authored by Alexandre Janniaux's avatar Alexandre Janniaux Committed by Steve Lhomme
Browse files

input: decoder: remove incorrectly ordered locking


The input decoder component is made of three different states:

 - Lock A:
   The input_decoder itself, loading the decoder and protected against
   concurrent usage of the decoder through p_owner->lock.

 - Lock B:
   The decoder implementation, that might create internal lock or
   synchronization object to process decoding asynchronously.

 - Lock C:
   The decoder implementation output, or the "owner" part viewed by the
   decoder implementation, which needs to be protected against access
   from the decoder and access from the input_decoder and is protected
   through the fifo lock, also protecting the fifo in which input data
   is pushed.

Because the decoder implementation is protected by the p_owner->lock (or
here, lock A), we can never lock A from the decoder implementation,
which is what the previous code was doing.

Likewise, since the decoder implementation will use the output to queue
picture and signal state changes, it must take Lock C and thus the
output part can never take either A or B.

Instead, we enforce the order:

                  Lock A -> Lock B -> Lock C:

Which means that:

 - The decoder implementation can lock the input decoder output (C) to
   push new changes.

 - The input_decoder can lock its output (C) directly to affect what
   state the decoder implementation will see when queueing changes.

 - The input_decoder will only lock A to protect the decoder_t object
   from being used concurrently.

This fixes deadlock in specific conditions where an asynchronous decoder
implementation would queue a picture with Lock B taken, trying to lock A
while the input_decoder client would have locked A already and would try
to flush the decoder implementation, taking lock B at the same time.

In practice, lock A is not really "useful" given that most of the
decoder_t methods are called from the decoder thread (owned by the input
decoder implementation), lock B is hidden in this part of the code, and
most of the "input decoder" is protected by the fifo lock, which then
must not be taken when calling decoder_t function to avoid reentrance of
the lock.

Co-authored-by: default avatarThomas Guillem <thomas@gllm.f>
parent e5b48bc7
No related branches found
No related tags found
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment