Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[osxsink] - fix deadloop in drain #4383

Merged
merged 2 commits into from

3 participants

@Memphiz
Owner

When cables are unplugged or tv is powered down the device vanishes and we might end up in an endless loop when the Engine tries to drain the sink.

This was confirmed fixing some tv poweroff/cable unplug issues as described here:

http://forum.xbmc.org/showthread.php?tid=185395

@Memphiz Memphiz added the Gotham label
@Memphiz
Owner

both PRs updated with the suggestions from @jmarshallnz

@jmarshallnz
Owner

jenkins build this please

@jmarshallnz jmarshallnz merged commit 59e9f7f into from
@jmarshallnz jmarshallnz removed the Gotham label
@FernetMenta

@fritsch just noticed: you should reset the ringbuffer after the while loop. it may have timed out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
16 xbmc/cores/AudioEngine/Sinks/AESinkDARWINIOS.cpp
@@ -244,7 +244,7 @@ unsigned int CAAudioUnitSink::write(uint8_t *data, unsigned int frames)
// we are using a timer here for beeing sure for timeouts
// condvar can be woken spuriously as signaled
XbmcThreads::EndTime timer(timeout);
- condVar.wait(lock, timeout);
+ condVar.wait(mutex, timeout);
if (!m_started && timer.IsTimePast())
return INT_MAX;
}
@@ -259,11 +259,21 @@ unsigned int CAAudioUnitSink::write(uint8_t *data, unsigned int frames)
void CAAudioUnitSink::drain()
{
unsigned int bytes = m_buffer->GetReadSize();
- while (bytes)
+ unsigned int totalBytes = bytes;
+ int maxNumTimeouts = 3;
+ unsigned int timeout = 900 * bytes / (m_sampleRate * m_frameSize);
+ while (bytes && maxNumTimeouts > 0)
{
CSingleLock lock(mutex);
- condVar.wait(mutex, 900 * bytes / (m_sampleRate * m_frameSize));
+ XbmcThreads::EndTime timer(timeout);
+ condVar.wait(mutex, timeout);
+
bytes = m_buffer->GetReadSize();
+ // if we timeout and don't
+ // consum bytes - decrease maxNumTimeouts
+ if (timer.IsTimePast() && bytes == totalBytes)
+ maxNumTimeouts--;
+ totalBytes = bytes;
}
}
View
16 xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.cpp
@@ -632,7 +632,7 @@ unsigned int CAESinkDARWINOSX::AddPackets(uint8_t *data, unsigned int frames, bo
// we are using a timer here for beeing sure for timeouts
// condvar can be woken spuriously as signaled
XbmcThreads::EndTime timer(timeout);
- condVar.wait(lock, timeout);
+ condVar.wait(mutex, timeout);
if (!m_started && timer.IsTimePast())
return INT_MAX;
}
@@ -647,11 +647,21 @@ unsigned int CAESinkDARWINOSX::AddPackets(uint8_t *data, unsigned int frames, bo
void CAESinkDARWINOSX::Drain()
{
int bytes = m_buffer->GetReadSize();
- while (bytes)
+ int totalBytes = bytes;
+ int maxNumTimeouts = 3;
+ unsigned int timeout = 900 * bytes / (m_format.m_sampleRate * m_format.m_frameSize);
+ while (bytes && maxNumTimeouts > 0)
{
CSingleLock lock(mutex);
- condVar.wait(mutex, 900 * bytes / (m_format.m_sampleRate * m_format.m_frameSize));
+ XbmcThreads::EndTime timer(timeout);
+ condVar.wait(mutex, timeout);
+
bytes = m_buffer->GetReadSize();
+ // if we timeout and don't
+ // consum bytes - decrease maxNumTimeouts
+ if (timer.IsTimePast() && bytes == totalBytes)
+ maxNumTimeouts--;
+ totalBytes = bytes;
}
}
Something went wrong with that request. Please try again.