Skip to content

Commit

Permalink
[AE] Fix potential engine deadlock after sink de-inits
Browse files Browse the repository at this point in the history
  • Loading branch information
DDDamian committed Sep 2, 2012
1 parent 24a7147 commit eb50bb2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
1 change: 1 addition & 0 deletions xbmc/cores/AudioEngine/AESinkFactory.cpp
Expand Up @@ -84,6 +84,7 @@ void CAESinkFactory::ParseDevice(std::string &device, std::string &driver)
} \
sink->Deinitialize(); \
delete sink; \
sink = NULL; \
}

IAESink *CAESinkFactory::Create(std::string &device, AEAudioFormat &desiredFormat, bool rawPassthrough)
Expand Down
14 changes: 9 additions & 5 deletions xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp
Expand Up @@ -672,7 +672,7 @@ void CSoftAE::PauseStream(CSoftAEStream *stream)
stream->m_paused = true;
streamLock.Leave();

InternalOpenSink();
OpenSink();
}

void CSoftAE::ResumeStream(CSoftAEStream *stream)
Expand All @@ -683,7 +683,7 @@ void CSoftAE::ResumeStream(CSoftAEStream *stream)
streamLock.Leave();

m_streamsPlaying = true;
InternalOpenSink();
OpenSink();
}

void CSoftAE::Stop()
Expand Down Expand Up @@ -721,7 +721,7 @@ IAEStream *CSoftAE::MakeStream(enum AEDataFormat dataFormat, unsigned int sample
m_newStreams.push_back(stream);
streamLock.Leave();

InternalOpenSink();
OpenSink();
return stream;
}

Expand Down Expand Up @@ -813,7 +813,7 @@ IAEStream *CSoftAE::FreeStream(IAEStream *stream)

/* if it was the master stream we need to reopen before deletion */
if (m_masterStream == stream)
InternalOpenSink();
OpenSink();

delete (CSoftAEStream*)stream;
return NULL;
Expand Down Expand Up @@ -938,6 +938,8 @@ void CSoftAE::Run()
m_wake.WaitMSec(SOFTAE_IDLE_WAIT_MSEC);
}

m_wake.Reset();

bool restart = false;

if ((this->*m_outputStageFn)(hasAudio) > 0)
Expand Down Expand Up @@ -1136,7 +1138,9 @@ int CSoftAE::RunRawOutputStage(bool hasAudio)
data = m_converted;
}

int wroteFrames = m_sink->AddPackets((uint8_t *)data, m_sinkFormat.m_frames, hasAudio);
int wroteFrames = 0;
if (m_sink)
wroteFrames = m_sink->AddPackets((uint8_t *)data, m_sinkFormat.m_frames, hasAudio);

/* Return value of INT_MAX signals error in sink - restart */
if (wroteFrames == INT_MAX)
Expand Down
20 changes: 14 additions & 6 deletions xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp
Expand Up @@ -276,7 +276,7 @@ bool CAESinkWASAPI::Initialize(AEAudioFormat &format, std::string &device)

void CAESinkWASAPI::Deinitialize()
{
if (!m_initialized & !m_isDirty)
if (!m_initialized && !m_isDirty)
return;

if (m_running)
Expand All @@ -292,10 +292,13 @@ void CAESinkWASAPI::Deinitialize()
}
m_running = false;

CloseHandle(m_needDataEvent);

Sleep((DWORD)(m_sinkLatency * 1.1 * 1000.0)); //let buffers drain

SAFE_RELEASE(m_pRenderClient);
SAFE_RELEASE(m_pAudioClient);
SAFE_RELEASE(m_pDevice);
CloseHandle(m_needDataEvent);

m_initialized = false;
}
Expand Down Expand Up @@ -424,14 +427,19 @@ unsigned int CAESinkWASAPI::AddPackets(uint8_t *data, unsigned int frames, bool
/* Wait for Audio Driver to tell us it's got a buffer available */
DWORD eventAudioCallback = WaitForSingleObject(m_needDataEvent, 1100);

if (eventAudioCallback != WAIT_OBJECT_0)
if (eventAudioCallback != WAIT_OBJECT_0 || !&buf)
{
// Event handle timed out - flag sink as dirty for re-initializing
CLog::Log(LOGERROR, __FUNCTION__": Endpoint Buffer timed out");
m_isDirty = true; //flag new device or re-init needed
Deinitialize();
if (g_advancedSettings.m_streamSilence)
{
m_isDirty = true; //flag new device or re-init needed
Deinitialize();
m_running = false;
return INT_MAX;
}
m_running = false;
return INT_MAX;
return 0;
}

if (!m_running)
Expand Down
5 changes: 3 additions & 2 deletions xbmc/cores/AudioEngine/Utils/AEBuffer.h
Expand Up @@ -134,9 +134,10 @@ class CAEBuffer
memcpy(dst, m_buffer, size);
// we can just reset m_bufferPos
// if there is nothing else inside.
if (m_bufferPos != size)
if ((m_bufferPos != size) && size <= m_bufferPos)
memmove(m_buffer, m_buffer + size, m_bufferSize - size);
m_bufferPos -= size;
if (size <= m_bufferPos)
m_bufferPos -= size;
}

/* cursor methods */
Expand Down

0 comments on commit eb50bb2

Please sign in to comment.