aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <kai.sommerfeld@gmx.com>2016-12-29 11:48:16 +0100
committerGitHub <noreply@github.com>2016-12-29 11:48:16 +0100
commit4a03004caab7dcf04a609d789baa135d995cf921 (patch)
tree6a1b80a3cf35bb25dfda3ac2656992e407ff11dd
parent6257e42c9e75bf1a9d26046258d7636f5c890cf2 (diff)
parent0efc8e793d9a0a8cc85685a7f06f3b7bab7d62f7 (diff)
Merge pull request #11284 from ksooo/krypton-pvr-fix-thread-reusage-crash
[PVR] Krypton: Fix PVR Manager crash on startup
-rw-r--r--xbmc/pvr/PVRManager.cpp12
-rw-r--r--xbmc/pvr/PVRManager.h2
-rw-r--r--xbmc/threads/Thread.cpp2
3 files changed, 13 insertions, 3 deletions
diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp
index 66ec738383..aa0782102c 100644
--- a/xbmc/pvr/PVRManager.cpp
+++ b/xbmc/pvr/PVRManager.cpp
@@ -391,6 +391,12 @@ void CPVRManager::Reinit()
void CPVRManager::Start()
{
+ CSingleLock initLock(m_startStopMutex);
+
+ // Note: Stop() must not be called while holding pvr manager's mutex. Stop() calls
+ // StopThread() which can deadlock if the worker thread tries to acquire pvr manager's
+ // lock while StopThread() is waiting for the worker to exit. Thus, we introduce another
+ // lock here (m_startStopMutex), which only gets hold while starting/restarting pvr manager.
Stop();
CSingleLock lock(m_critSection);
@@ -412,8 +418,10 @@ void CPVRManager::Start()
void CPVRManager::Stop(void)
{
+ CSingleLock initLock(m_startStopMutex);
+
/* check whether the pvrmanager is loaded */
- if (IsStopping() || IsStopped())
+ if (IsStopped())
return;
SetState(ManagerStateStopping);
@@ -442,7 +450,7 @@ void CPVRManager::Stop(void)
/* close database */
const CPVRDatabasePtr database(GetTVDatabase());
- if (database->IsOpen())
+ if (database && database->IsOpen())
database->Close();
SetState(ManagerStateStopped);
diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h
index 05c30fc4b8..67c7c1fe18 100644
--- a/xbmc/pvr/PVRManager.h
+++ b/xbmc/pvr/PVRManager.h
@@ -706,6 +706,8 @@ private:
ManagerState m_managerState;
std::unique_ptr<CStopWatch> m_parentalTimer;
+ CCriticalSection m_startStopMutex; // mutex for protecting pvr manager's start/restart/stop sequence */
+
std::atomic_bool m_isChannelPreview;
CEventSource<PVREvent> m_events;
};
diff --git a/xbmc/threads/Thread.cpp b/xbmc/threads/Thread.cpp
index ea03bb246d..b77ce8f90c 100644
--- a/xbmc/threads/Thread.cpp
+++ b/xbmc/threads/Thread.cpp
@@ -85,7 +85,7 @@ void CThread::Create(bool bAutoDelete, unsigned stacksize)
{
if (m_ThreadId != 0)
{
- LOG(LOGERROR, "%s - fatal error creating thread- old thread id not null", __FUNCTION__);
+ LOG(LOGERROR, "%s - fatal error creating thread %s - old thread id not null", __FUNCTION__, m_ThreadName.c_str());
exit(1);
}
m_iLastTime = XbmcThreads::SystemClockMillis() * 10000;