bug 1166107 release internal drain monitor before calling Flush() r=gerald

The DrainComplete() caught with mWaitForInternalDrain still won't necessarily
be from the internal Drain(), but all we need is that one DrainComplete() is
caught for the internal Drain() because one more will be generated if there is
a Drain() in progress.

What protecting mWaitForInternalDrain access with the monitor provides here is
that the compiler won't use its address for storage of other data meaningless
in the context of mWaitForInternalDrain and so, for example, two
DrainComplete() calls won't unintentionally think that they are both for one
internal drain.
And TSan warnings.
This commit is contained in:
Karl Tomlinson 2015-05-25 08:52:30 +12:00
parent 0f158b319f
commit 29634532f0

View File

@ -163,16 +163,15 @@ void
SharedDecoderManager::SetIdle(MediaDataDecoder* aProxy) SharedDecoderManager::SetIdle(MediaDataDecoder* aProxy)
{ {
if (aProxy && mActiveProxy == aProxy) { if (aProxy && mActiveProxy == aProxy) {
MonitorAutoLock mon(mMonitor);
mWaitForInternalDrain = true;
nsresult rv;
{ {
// We don't want to hold the lock while calling Drain() has some MonitorAutoLock mon(mMonitor);
mWaitForInternalDrain = true;
// We don't want to hold the lock while calling Drain() as some
// platform implementations call DrainComplete() immediately. // platform implementations call DrainComplete() immediately.
MonitorAutoUnlock mon(mMonitor);
rv = mActiveProxy->Drain();
} }
nsresult rv = mActiveProxy->Drain();
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
MonitorAutoLock mon(mMonitor);
while (mWaitForInternalDrain) { while (mWaitForInternalDrain) {
mon.Wait(); mon.Wait();
} }