aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfritsch <peter.fruehberger@gmail.com>2013-02-06 09:03:34 +0100
committerfritsch <peter.fruehberger@gmail.com>2013-02-09 17:17:15 +0100
commitfa9b89e73da173d4621c7b49e0b9464a268731ca (patch)
tree784b654d183cb538c32f923b8d3e5b1da8233270
parent370ac3d7dc0abf34b54e4cdc0502d775d8f7e607 (diff)
AE: Wait until we are in a safe state before further deinitializing the sink
-rw-r--r--xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp39
-rw-r--r--xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h1
2 files changed, 31 insertions, 9 deletions
diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp
index ae8a0e4b9d..343758c709 100644
--- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp
+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp
@@ -1006,11 +1006,18 @@ bool CSoftAE::Suspend()
// This is the only place m_realSuspend gets set true.
// If you find another one - please call for help.
// First thing when rewriting: kill this flag and make it generic again.
+ m_saveSuspend.Reset();
m_realSuspend = true;
+ // wait until we are looping in ProcessSuspend()
+ m_saveSuspend.Wait();
m_sink->Drain();
m_sink->Deinitialize();
delete m_sink;
m_sink = NULL;
+ // signal anybody, that the sink is closed now
+ // this should help us not to run into deadlocks
+ if(m_closeSink)
+ m_closeEvent.Set();
}
// The device list is now empty and must be reenumerated afterwards.
m_sinkInfoList.clear();
@@ -1086,6 +1093,13 @@ void CSoftAE::Run()
if (m_reOpen || restart || !m_sink)
{
CLog::Log(LOGDEBUG, "CSoftAE::Run - Sink restart flagged");
+ // ProcessSuspending() cannot guarantee that we get our sink back softresumed
+ if(m_sink && m_softSuspend)
+ {
+ m_sink->SoftResume();
+ m_softSuspend = false;
+ CLog::Log(LOGDEBUG, "CSoftAE::Run - Soft resumed the sink outside");
+ }
InternalOpenSink();
m_isSuspended = false; // exit Suspend state
}
@@ -1510,22 +1524,29 @@ inline void CSoftAE::ProcessSuspend()
}
sinkLock.Leave();
}
-
- // make sure that a outer thread does not have to wait forever
- if(m_closeSink)
- {
- InternalCloseSink();
- }
+ // Signal that the realSuspend can go on now.
+ // Idea: Outer thread calls Suspend() - but
+ // because of AddPackets does not care about locks, we must make
+ // sure, that our school bus (AE::Run) is currently driving through
+ // some gas station, before we move away the sink.
+ if(m_realSuspend)
+ m_saveSuspend.Set();
/* idle for platform-defined time */
m_wake.WaitMSec(SOFTAE_IDLE_WAIT_MSEC);
- /* check if we need to resume for stream or sound */
+ /* check if we need to resume for stream or sound or somebody wants to open us
+ * the suspend checks are only there to:
+ * a) not run out of softSuspend directly when we are sleeping
+ * b) nail(!) the thread during real Suspend into this method
+ * Note: It is not enough to check the streams buffer, cause it might not be filled yet
+ * We have to check after ProcessSuspending() if the sink is still in softsleep and resume it
+ */
if (!m_realSuspend && !m_isSuspended && (!m_playingStreams.empty() || !m_playing_sounds.empty()))
{
- m_reOpen = !m_sink->SoftResume(); // sink returns false if it requires reinit
+ m_reOpen = m_reOpen || !m_sink->SoftResume(); // sink returns false if it requires reinit
sinkIsSuspended = false; //sink processing data
- m_softSuspend = false; //break suspend loop
+ m_softSuspend = false; //break suspend loop (under some conditions)
CLog::Log(LOGDEBUG, "Resumed the Sink");
break;
}
diff --git a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h
index f3787c96bb..9d6399e640 100644
--- a/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h
+++ b/xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.h
@@ -145,6 +145,7 @@ private:
CEvent m_reOpenEvent;
CEvent m_wake;
CEvent m_closeEvent;
+ CEvent m_saveSuspend;
CCriticalSection m_runningLock; /* released when the thread exits */
CCriticalSection m_streamLock; /* m_streams lock */