Skip to content

Commit

Permalink
Refs #9885. Fixes deadlock when a slave backend disconnect is first s…
Browse files Browse the repository at this point in the history
…een from within the Scheduler thread. Patch by Ian Dall.

Keeping ticket open since this should be backported to 0.24-fixes.
  • Loading branch information
daniel-kristjansson committed Jul 16, 2011
1 parent 98348b5 commit 1fae22a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
42 changes: 35 additions & 7 deletions mythtv/programs/mythbackend/mainserver.cpp
Expand Up @@ -1020,6 +1020,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;

Expand Down Expand Up @@ -5580,7 +5583,7 @@ void MainServer::connectionClosed(MythSocket *socket)
}
else if (sock == socket)
{
list<uint> disconnectedSlaves;
QList<uint> disconnectedSlaves;
bool needsReschedule = false;

if (ismaster && pbs->isSlaveBackend())
Expand Down Expand Up @@ -5659,13 +5662,10 @@ void MainServer::connectionClosed(MythSocket *socket)
LOG(VB_GENERAL, LOG_ERR, "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;
Expand Down Expand Up @@ -6083,4 +6083,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 QList<uint> &cardids, bool needsReschedule)
{
QStringList extraData;
extraData.push_back(
QString::number(static_cast<uint>(needsReschedule)));

QList<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: */
4 changes: 4 additions & 0 deletions mythtv/programs/mythbackend/mainserver.h
Expand Up @@ -2,6 +2,7 @@
#define MAINSERVER_H_

#include <QReadWriteLock>
#include <QStringList>
#include <QThreadPool>
#include <QRunnable>
#include <QEvent>
Expand Down Expand Up @@ -211,8 +212,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 QList<uint> &offlineEncoderIDs,
bool needsReschedule);

void getGuideDataThrough(QDateTime &GuideDataThrough);

Expand Down

0 comments on commit 1fae22a

Please sign in to comment.