summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kristjansson <danielk@cuymedia.net>2011-07-16 21:15:09 (GMT)
committer Daniel Kristjansson <danielk@cuymedia.net>2011-08-12 18:06:13 (GMT)
commit3a5f78862a5be39e02ee549551d59e9c40fa575d (patch)
tree48ce6e3ac60635b758d1b1ab7286adfcdff5ae42
parent1cf65bccbd186fcfdb8d55e31232a8cfe6fdb1a3 (diff)
Fixes #9885. Fixes deadlock when a slave backend disconnect is first seen from within the Scheduler thread. Patch by Ian Dall.
This has been running in master for 4 weeks without reports of regression.
-rw-r--r--mythtv/programs/mythbackend/mainserver.cpp40
-rw-r--r--mythtv/programs/mythbackend/mainserver.h7
2 files changed, 41 insertions, 6 deletions
diff --git a/mythtv/programs/mythbackend/mainserver.cpp b/mythtv/programs/mythbackend/mainserver.cpp
index 209d5e0..b224db4 100644
--- a/mythtv/programs/mythbackend/mainserver.cpp
+++ b/mythtv/programs/mythbackend/mainserver.cpp
@@ -994,6 +994,9 @@ void MainServer::customEvent(QEvent *e)
if (me->Message() == "LOCAL_RECONNECT_TO_MASTER")
masterServerReconnect->start(kMasterServerReconnectTimeout);
+ if (me->Message() == "LOCAL_SLAVE_BACKEND_ENCODERS_OFFLINE")
+ HandleSlaveDisconnectedEvent(*me);
+
if (me->Message().left(6) == "LOCAL_")
return;
@@ -5537,13 +5540,10 @@ void MainServer::connectionClosed(MythSocket *socket)
VERBOSE(VB_IMPORTANT, "Playback sock still exists?");
sockListLock.unlock();
- for (list<uint>::iterator p = disconnectedSlaves.begin() ;
- p != disconnectedSlaves.end() ; p++) {
- if (m_sched) m_sched->SlaveDisconnected(*p);
- }
- if (m_sched && needsReschedule)
- m_sched->Reschedule(0);
+ // Since we may already be holding the scheduler lock
+ // delay handling the disconnect until a little later. #9885
+ SendSlaveDisconnectedEvent(disconnectedSlaves, needsReschedule);
pbs->DownRef();
return;
@@ -5959,4 +5959,32 @@ void MainServer::ShutSlaveBackendsDown(QString &haltcmd)
sockListLock.unlock();
}
+void MainServer::HandleSlaveDisconnectedEvent(const MythEvent &event)
+{
+ if (event.ExtraDataCount() > 0 && m_sched)
+ {
+ bool needsReschedule = event.ExtraData(0).toUInt();
+ for (int i = 1; i < event.ExtraDataCount(); i++)
+ m_sched->SlaveDisconnected(event.ExtraData(i).toUInt());
+
+ if (needsReschedule)
+ m_sched->Reschedule(0);
+ }
+}
+
+void MainServer::SendSlaveDisconnectedEvent(
+ const list<uint> &cardids, bool needsReschedule)
+{
+ QStringList extraData;
+ extraData.push_back(
+ QString::number(static_cast<uint>(needsReschedule)));
+
+ list<uint>::const_iterator it;
+ for (it = cardids.begin(); it != cardids.end(); ++it)
+ extraData.push_back(QString::number(*it));
+
+ MythEvent me("LOCAL_SLAVE_BACKEND_ENCODERS_OFFLINE", extraData);
+ gCoreContext->dispatch(me);
+}
+
/* vim: set expandtab tabstop=4 shiftwidth=4: */
diff --git a/mythtv/programs/mythbackend/mainserver.h b/mythtv/programs/mythbackend/mainserver.h
index 22d8800..f0044a7 100644
--- a/mythtv/programs/mythbackend/mainserver.h
+++ b/mythtv/programs/mythbackend/mainserver.h
@@ -2,12 +2,16 @@
#define MAINSERVER_H_
#include <QReadWriteLock>
+#include <QStringList>
+#include <QThreadPool>
+#include <QRunnable>
#include <QEvent>
#include <QMutex>
#include <QHash>
#include <QMap>
#include <vector>
+#include <list>
using namespace std;
#include "tv.h"
@@ -167,8 +171,11 @@ class MainServer : public QObject, public MythSocketCBs
void HandleQueryTimeZone(PlaybackSock *pbs);
void HandleBlockShutdown(bool blockShutdown, PlaybackSock *pbs);
void HandleDownloadFile(const QStringList &command, PlaybackSock *pbs);
+ void HandleSlaveDisconnectedEvent(const MythEvent &event);
void SendResponse(MythSocket *pbs, QStringList &commands);
+ void SendSlaveDisconnectedEvent(const list<uint> &offlineEncoderIDs,
+ bool needsReschedule);
void getGuideDataThrough(QDateTime &GuideDataThrough);