Skip to content

Commit bd88e48

Browse files
committed
Put channel changing script handling back to MythSystem
Fixes #9905 It seems that the merge of mythtv-rec2 branch that happened in May effectively reverted the change of this section of code to use the new MythSystem support. See 9b22460 This reimplements the use of MythSystem rather than QProcess while leaving as much of the rest alone as possible. It also removes a now unneeded thread. Also cleaned up a stray include of QProcess in the grabber settings.
1 parent d5a069e commit bd88e48

File tree

3 files changed

+70
-143
lines changed

3 files changed

+70
-143
lines changed

mythtv/libs/libmythtv/channelbase.cpp

Lines changed: 61 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ using namespace std;
1515

1616
// Qt headers
1717
#include <QCoreApplication>
18-
#include <QProcess>
1918

2019
// MythTV headers
2120
#include "firewirechannel.h"
@@ -43,24 +42,17 @@ using namespace std;
4342
ChannelBase::ChannelBase(TVRec *parent) :
4443
m_pParent(parent), m_curchannelname(""),
4544
m_currentInputID(-1), m_commfree(false), m_cardid(0),
46-
m_process_thread(NULL), m_process(NULL), m_process_status(0)
45+
m_system(NULL), m_system_status(0)
4746
{
4847
}
4948

5049
ChannelBase::~ChannelBase(void)
5150
{
5251
ClearInputMap();
5352

54-
QMutexLocker locker(&m_process_lock);
55-
if (m_process_thread)
56-
{
57-
// better to a risk zombie than risk blocking forever..
58-
KillScript(500);
59-
m_process_thread->exit(0);
60-
if (m_process_thread->wait())
61-
delete m_process_thread;
62-
m_process_thread = NULL;
63-
}
53+
QMutexLocker locker(&m_system_lock);
54+
if (m_system)
55+
KillScript();
6456
}
6557

6658
bool ChannelBase::Init(QString &inputname, QString &startchannel, bool setchan)
@@ -631,47 +623,38 @@ DBChanList ChannelBase::GetChannels(const QString &inputname) const
631623
return GetChannels(inputid);
632624
}
633625

634-
/// \note m_process_lock must be held when this is called
635-
bool ChannelBase::KillScript(uint timeout_ms)
626+
/// \note m_system_lock must be held when this is called
627+
bool ChannelBase::KillScript(void)
636628
{
637-
if (!m_process)
629+
if (!m_system)
638630
return true;
639631

640-
if (m_process->state() != QProcess::NotRunning)
641-
{
642-
m_process->terminate();
643-
if (!m_process->waitForFinished(max(timeout_ms/2,1U)))
644-
{
645-
m_process->kill();
646-
if (!m_process->waitForFinished(max(timeout_ms/2,1U)))
647-
return false;
648-
}
649-
}
632+
m_system->Term(true);
650633

651-
delete m_process;
652-
m_process = NULL;
634+
delete m_system;
635+
m_system = NULL;
653636
return true;
654637
}
655638

656-
/// \note m_process_lock must NOT be held when this is called
639+
/// \note m_system_lock must NOT be held when this is called
657640
void ChannelBase::HandleScript(const QString &freqid)
658641
{
659-
QMutexLocker locker(&m_process_lock);
642+
QMutexLocker locker(&m_system_lock);
660643

661644
bool ok = true;
662-
m_process_status = 0; // unknown
645+
m_system_status = 0; // unknown
663646

664647
InputMap::const_iterator it = m_inputs.find(m_currentInputID);
665648
if (it == m_inputs.end())
666649
{
667-
m_process_status = 2; // failed
650+
m_system_status = 2; // failed
668651
HandleScriptEnd(true);
669652
return;
670653
}
671654

672655
if ((*it)->externalChanger.isEmpty())
673656
{
674-
m_process_status = 3; // success
657+
m_system_status = 3; // success
675658
HandleScriptEnd(true);
676659
return;
677660
}
@@ -682,30 +665,30 @@ void ChannelBase::HandleScript(const QString &freqid)
682665
"A channel changer is set, but the freqid field is empty."
683666
"\n\t\t\tWe will return success to ease setup pains, "
684667
"but no script is will actually run.");
685-
m_process_status = 3; // success
668+
m_system_status = 3; // success
686669
HandleScriptEnd(true);
687670
return;
688671
}
689672

690673
// It's possible we simply never reaped the process, check status first.
691-
if (m_process)
674+
if (m_system)
692675
GetScriptStatus(true);
693676

694677
// If it's still running, try killing it
695-
if (m_process)
696-
ok = KillScript(50);
678+
if (m_system)
679+
ok = KillScript();
697680

698-
// The GetScriptStatus() call above can reset m_process_status with
681+
// The GetScriptStatus() call above can reset m_system_status with
699682
// the exit status of the last channel change script invocation, so
700683
// we must set it to pending here.
701-
m_process_status = 1; // pending
684+
m_system_status = 1; // pending
702685

703686
if (!ok)
704687
{
705688
LOG(VB_GENERAL, LOG_ERR, LOC +
706689
"Can not execute channel changer, previous call to script "
707690
"is still running.");
708-
m_process_status = 2; // failed
691+
m_system_status = 2; // failed
709692
HandleScriptEnd(ok);
710693
}
711694
else
@@ -714,88 +697,80 @@ void ChannelBase::HandleScript(const QString &freqid)
714697
if (!ok)
715698
{
716699
LOG(VB_GENERAL, LOG_ERR, LOC + "Can not execute channel changer.");
717-
m_process_status = 2; // failed
700+
m_system_status = 2; // failed
718701
HandleScriptEnd(ok);
719702
}
720703
}
721704
}
722705

723-
bool ChannelBase::ChangeExternalChannel(
724-
const QString &changer, const QString &freqid)
706+
/// \note m_system_lock must be held when this is called
707+
bool ChannelBase::ChangeExternalChannel(const QString &changer,
708+
const QString &freqid)
725709
{
726-
if (m_process)
710+
if (m_system)
727711
return false;
728712

729713
if (changer.isEmpty() || freqid.isEmpty())
730714
return false;
731715

732-
QString command = QString("/bin/sh -c \"%1 %2\"").arg(changer).arg(freqid);
716+
QString command = QString("%1 %2").arg(changer).arg(freqid);
733717
LOG(VB_CHANNEL, LOG_INFO, LOC +
734718
QString("Running command: %1").arg(command));
735719

736-
if (!m_process_thread)
737-
{
738-
m_process_thread = new ProcessThread();
739-
m_process_thread->start();
740-
}
741-
742-
m_process = m_process_thread->CreateProcess(command);
720+
m_system = new MythSystem(command, kMSRunShell);
721+
m_system->Run(30);
743722

744723
return true;
745724
}
746725

747726
uint ChannelBase::GetScriptStatus(bool holding_lock)
748727
{
728+
if (!m_system)
729+
return m_system_status;
730+
749731
if (!holding_lock)
750-
m_process_lock.lock();
732+
m_system_lock.lock();
751733

752-
if (m_process && m_process->state() == QProcess::NotRunning)
734+
m_system_status = m_system->Wait();
735+
if (m_system_status != GENERIC_EXIT_RUNNING &&
736+
m_system_status != GENERIC_EXIT_START)
753737
{
754-
if (m_process->exitStatus() != QProcess::CrashExit &&
755-
m_process->exitCode() == 0)
756-
{
757-
m_process_status = 3; // success
758-
}
759-
else
760-
{
761-
m_process_status = 2; // failed
762-
}
738+
delete m_system;
739+
m_system = NULL;
763740

764-
delete m_process;
765-
m_process = NULL;
741+
HandleScriptEnd(m_system_status == GENERIC_EXIT_OK);
742+
}
766743

767-
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("GetScriptStatus() %1")
768-
.arg(m_process_status));
744+
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("GetScriptStatus() %1")
745+
.arg(m_system_status));
769746

770-
HandleScriptEnd(3 == m_process_status);
771-
}
772-
else
747+
uint ret;
748+
switch(m_system_status)
773749
{
774-
QString ps = "NULL";
775-
if (m_process != NULL)
776-
{
777-
int s = m_process->state();
778-
ps = QString::number(s);
779-
switch (s)
780-
{
781-
case QProcess::Running: ps = "running"; break;
782-
case QProcess::NotRunning: ps = "not running"; break;
783-
case QProcess::Starting: ps = "starting"; break;
784-
}
785-
}
786-
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("GetScriptStatus() %1 (ps %2)")
787-
.arg(m_process_status).arg(ps));
750+
case GENERIC_EXIT_OK:
751+
ret = 3; // success
752+
break;
753+
case GENERIC_EXIT_RUNNING:
754+
case GENERIC_EXIT_START:
755+
ret = 1; // pending
756+
break;
757+
default:
758+
ret = 2; // fail
759+
break;
788760
}
789761

790-
uint ret = m_process_status;
762+
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("GetScriptStatus() %1 -> %2")
763+
.arg(m_system_status). arg(ret));
764+
765+
m_system_status = ret;
791766

792767
if (!holding_lock)
793-
m_process_lock.unlock();
768+
m_system_lock.unlock();
794769

795770
return ret;
796771
}
797772

798-
/// \note m_process_lock must be held when this is called
773+
/// \note m_system_lock must be held when this is called
799774
void ChannelBase::HandleScriptEnd(bool ok)
800775
{
801776
LOG(VB_CHANNEL, LOG_INFO, LOC + QString("Channel change script %1")
@@ -1221,31 +1196,3 @@ ChannelBase *ChannelBase::CreateChannel(
12211196
return channel;
12221197
}
12231198

1224-
bool ProcessThread::event(QEvent *e)
1225-
{
1226-
if (MythEvent::MythEventMessage == e->type())
1227-
{
1228-
MythEvent *me = static_cast<MythEvent*>(e);
1229-
if (me->Message() == "CreateProcess")
1230-
{
1231-
QMutexLocker locker(&m_lock);
1232-
m_proc = new QProcess();
1233-
m_proc->start(me->ExtraData(0));
1234-
m_wait.wakeOne();
1235-
return true;
1236-
}
1237-
}
1238-
1239-
return QThread::event(e);
1240-
}
1241-
1242-
QProcess *ProcessThread::CreateProcess(const QString &command)
1243-
{
1244-
QMutexLocker locker(&m_lock);
1245-
QStringList cmd(command);
1246-
QCoreApplication::postEvent(this, new MythEvent("CreateProcess", cmd));
1247-
m_wait.wait(&m_lock);
1248-
QProcess *ret = m_proc;
1249-
m_proc = NULL;
1250-
return ret;
1251-
}

mythtv/libs/libmythtv/channelbase.h

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@
1717

1818
class FireWireDBOptions;
1919
class GeneralDBOptions;
20-
class ProcessThread;
2120
class DVBDBOptions;
2221
class ChannelBase;
23-
class QProcess;
2422
class TVRec;
2523

2624
/** \class ChannelBase
@@ -149,13 +147,13 @@ class ChannelBase
149147
static void StoreDefaultInput(uint cardid, const QString &input);
150148

151149
protected:
152-
bool KillScript(uint timeout_ms);
150+
bool KillScript(void);
153151
void HandleScript(const QString &freqid);
154152
virtual void HandleScriptEnd(bool ok);
155153
uint GetScriptStatus(bool holding_lock = false);
156154

157-
bool ChangeExternalChannel(
158-
const QString &changer, const QString &newchan);
155+
bool ChangeExternalChannel(const QString &changer,
156+
const QString &newchan);
159157

160158
TVRec *m_pParent;
161159
QString m_curchannelname;
@@ -165,30 +163,13 @@ class ChannelBase
165163
InputMap m_inputs;
166164
DBChanList m_allchannels; ///< channels across all inputs
167165

168-
QMutex m_process_lock;
169-
ProcessThread *m_process_thread;
170-
QProcess *m_process;
171-
/// 0 == unknown, 1 == pending, 2 == failed, 4 == success
172-
uint m_process_status;
166+
QMutex m_system_lock;
167+
MythSystem *m_system;
168+
/// These get mapped from the GENERIC_EXIT_* to these values for use
169+
/// with the signalmonitor code.
170+
/// 0 == unknown, 1 == pending, 2 == failed, 3 == success
171+
uint m_system_status;
173172
};
174173

175-
/** \brief ChannelBase helper class
176-
* This is only needed because ChangeExternalChannel is called
177-
* outside of a QThread event thread. If TVRec were converted to
178-
* use QThread w/event thread this could be replaced by
179-
* m_process = new QProcess();
180-
* m_process->start(command);
181-
*/
182-
class ProcessThread : public QThread
183-
{
184-
public:
185-
ProcessThread() { QObject::moveToThread(this); }
186-
virtual void run(void) { exec(); }
187-
virtual bool event(QEvent*);
188-
QProcess *CreateProcess(const QString&);
189-
QMutex m_lock;
190-
QWaitCondition m_wait;
191-
QProcess *m_proc;
192-
};
193174

194175
#endif

mythtv/programs/mythfrontend/grabbersettings.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
// qt
44
#include <QString>
5-
#include <QProcess>
65
#include <QString>
76
#include <QStringList>
87

0 commit comments

Comments
 (0)