Fix deadlock during content examination.
authorCarl Hetherington <cth@carlh.net>
Tue, 28 Jan 2020 22:23:47 +0000 (23:23 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 16 Feb 2020 20:23:42 +0000 (21:23 +0100)
commit4b38c8f429407ec09609236fc7b2349459536571
tree5b68a09ead560205e2dd3aaed4e81f50fbde959b
parentc259c459f5d326e7c42806b41de06c71ad4a3ad8
Fix deadlock during content examination.

Before this fix, the following situation could happen in threads
A and B:

A: Some DONE signal happens; this triggers setup_pieces which
   takes a lock on the player mutex.

B: FFmpegContent::examine takes a lock on the content mutex.
B: FFmpegContent::examine adds a stream
B: That causes STREAMS PENDING to be emitted.
B: This tries to take a lock on the player mutex so it can update _suspended

A: setup_pieces tries to access some content information, hence
   tries to take a lock on the content mutex.

Now B is holding the CL and awaiting the PL and A is holding
the PL and awaiting the CL.

It feels like the root cause of this is that while setup_pieces
is happening another change (which would itself cause setup_pieces)
is announced, and this isn't dealt with properly.

There are two steps here; _suspended is protected with an atomic
rather than using _mutex, and also it can cope with being updated
recursively.

Backported from df48c75c38dd788835a93540aea243a2dac4bb10 in v2.15.x
src/lib/player.cc
src/lib/player.h