Skip to content
Browse files

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.
  • Loading branch information...
1 parent 1cf65bc commit 3a5f78862a5be39e02ee549551d59e9c40fa575d @daniel-kristjansson daniel-kristjansson committed Jul 16, 2011
Showing with 41 additions and 6 deletions.
  1. +34 −6 mythtv/programs/mythbackend/mainserver.cpp
  2. +7 −0 mythtv/programs/mythbackend/mainserver.h
View
40 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: */
View
7 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);

0 comments on commit 3a5f788

Please sign in to comment.
Something went wrong with that request. Please try again.