Ticket #11306: slave_shutdown_deadlock_v2.patch

File slave_shutdown_deadlock_v2.patch, 24.0 KB (added by tomi.orava@…, 8 years ago)

An extremely dirty hack around the slave shutdown deadlock v2

  • mythtv/programs/mythbackend/encoderlink.cpp

    diff --git a/mythtv/programs/mythbackend/encoderlink.cpp b/mythtv/programs/mythbackend/encoderlink.cpp
    index 2c7bc76..95cf662 100644
    a b EncoderLink::EncoderLink(int capturecardnum, PlaybackSock *lsock, 
    4141                         QString lhostname)
    4242    : m_capturecardnum(capturecardnum), sock(lsock), hostname(lhostname),
    4343      freeDiskSpaceKB(-1), tv(NULL), local(false), locked(false),
     44      disconnected(false),
    4445      sleepStatus(sStatus_Undefined), chanid(0)
    4546{
    4647    endRecordingTime = MythDate::current().addDays(-2);
    EncoderLink::EncoderLink(int capturecardnum, PlaybackSock *lsock, 
    5051    lastSleepTime   = MythDate::current();
    5152    lastWakeTime    = MythDate::current();
    5253
     54    QMutexLocker locker(&sockLock);
    5355    if (sock)
    5456        sock->IncrRef();
    5557}
    EncoderLink::EncoderLink(int capturecardnum, PlaybackSock *lsock, 
    6062EncoderLink::EncoderLink(int capturecardnum, TVRec *ltv)
    6163    : m_capturecardnum(capturecardnum), sock(NULL),
    6264      freeDiskSpaceKB(-1), tv(ltv), local(true), locked(false),
     65      disconnected(false),
    6366      sleepStatus(sStatus_Undefined), chanid(0)
    6467{
    6568    endRecordingTime = MythDate::current().addDays(-2);
    EncoderLink::~EncoderLink(void) 
    8184        delete tv;
    8285        tv = NULL;
    8386    }
     87    disconnected = true;
    8488}
    8589
    8690/** \fn EncoderLink::SetSocket(PlaybackSock *lsock)
    EncoderLink::~EncoderLink(void) 
    9094 */
    9195void EncoderLink::SetSocket(PlaybackSock *lsock)
    9296{
     97    QMutexLocker locker(&sockLock);
    9398    if (lsock)
    9499    {
    95100        lsock->IncrRef();
    void EncoderLink::SetSocket(PlaybackSock *lsock) 
    99104        else
    100105            SetSleepStatus(sStatus_Awake);
    101106    }
    102     else
    103     {
    104         if (IsFallingAsleep())
    105             SetSleepStatus(sStatus_Asleep);
    106         else
    107             SetSleepStatus(sStatus_Undefined);
    108     }
    109 
    110     if (sock)
    111         sock->DecrRef();
    112107    sock = lsock;
    113108}
    114109
     110void EncoderLink::Disconnect()
     111{
     112  disconnected = true;
     113  if (IsFallingAsleep())
     114      SetSleepStatus(sStatus_Asleep);
     115  else
     116      SetSleepStatus(sStatus_Undefined);
     117
     118  if (sock)
     119      sock->DecrRef();
     120}
     121
    115122/** \fn EncoderLink::SetSleepStatus(SleepStatus)
    116123 *  \brief Sets the sleep status of a recorder
    117124 */
    void EncoderLink::SetSleepStatus(SleepStatus newStatus) 
    128135 */
    129136bool EncoderLink::IsBusy(TunedInputInfo *busy_input, int time_buffer)
    130137{
     138    if (disconnected)
     139        return false;
     140
    131141    if (local)
    132142        return tv->IsBusy(busy_input, time_buffer);
    133143
     144    QMutexLocker locker(&sockLock);
    134145    if (sock)
    135146        return sock->IsBusy(m_capturecardnum, busy_input, time_buffer);
    136147
    bool EncoderLink::IsBusyRecording(void) 
    149160{
    150161    bool retval = false;
    151162
     163    if (disconnected)
     164        return false;
     165
    152166    TVState state = GetState();
    153167
    154168    if (state == kState_RecordingOnly || state == kState_WatchingRecording ||
    TVState EncoderLink::GetState(void) 
    174188    if (local)
    175189        retval = tv->GetState();
    176190    else if (sock)
    177         retval = (TVState)sock->GetEncoderState(m_capturecardnum);
     191    {
     192        QMutexLocker locker(&sockLock);
     193        if (sock)
     194            retval = (TVState)sock->GetEncoderState(m_capturecardnum);
     195    }
    178196    else
    179197        LOG(VB_GENERAL, LOG_ERR, QString("Broken for card: %1")
    180198            .arg(m_capturecardnum));
    TVState EncoderLink::GetState(void) 
    186204 *  \brief Returns the flag state of the recorder.
    187205 *  \sa TVRec::GetFlags(void) const, \ref recorder_subsystem
    188206 */
    189 uint EncoderLink::GetFlags(void) const
     207uint EncoderLink::GetFlags(void)
    190208{
    191209    uint retval = 0;
    192210
    193     if (!IsConnected())
     211    if (disconnected)
    194212        return retval;
    195213
    196214    if (local)
    197215        retval = tv->GetFlags();
    198216    else if (sock)
    199         retval = sock->GetEncoderState(m_capturecardnum);
     217    {
     218        QMutexLocker locker(&sockLock);
     219        if (sock)
     220            retval = sock->GetEncoderState(m_capturecardnum);
     221    }
    200222    else
    201223        LOG(VB_GENERAL, LOG_ERR, LOC + "GetFlags failed");
    202224
    uint EncoderLink::GetFlags(void) const 
    210232 */
    211233bool EncoderLink::IsRecording(const ProgramInfo *rec)
    212234{
     235    if (disconnected)
     236        return false;
    213237    return (rec->GetChanID() == chanid &&
    214238            rec->GetRecordingStartTime() == startRecordingTime);
    215239}
    bool EncoderLink::MatchesRecording(const ProgramInfo *rec) 
    227251    bool retval = false;
    228252    ProgramInfo *tvrec = NULL;
    229253
     254    if (disconnected)
     255        return false;
     256
    230257    if (local)
    231258    {
    232259        while (kState_ChangingState == GetState())
    bool EncoderLink::MatchesRecording(const ProgramInfo *rec) 
    243270    }
    244271    else
    245272    {
     273        QMutexLocker locker(&sockLock);
    246274        if (sock)
    247275            retval = sock->EncoderIsRecording(m_capturecardnum, rec);
    248276    }
    bool EncoderLink::MatchesRecording(const ProgramInfo *rec) 
    261289void EncoderLink::RecordPending(const ProgramInfo *rec, int secsleft,
    262290                                bool hasLater)
    263291{
     292    if (disconnected)
     293        return;
     294
    264295    if (local)
    265296        tv->RecordPending(rec, secsleft, hasLater);
    266     else if (sock)
    267         sock->RecordPending(m_capturecardnum, rec, secsleft, hasLater);
     297    else
     298    {
     299        QMutexLocker locker(&sockLock);
     300        if (sock)
     301            sock->RecordPending(m_capturecardnum, rec, secsleft, hasLater);
     302   }
    268303}
    269304
    270305/** \fn EncoderLink::WouldConflict(const ProgramInfo*)
    bool EncoderLink::WouldConflict(const ProgramInfo *rec) 
    286321/// Checks if program is stored locally
    287322bool EncoderLink::CheckFile(ProgramInfo *pginfo)
    288323{
     324    if (disconnected)
     325        return false;
     326
     327    QMutexLocker locker(&sockLock);
    289328    if (sock)
    290329        return sock->CheckFile(pginfo);
    291330
    bool EncoderLink::CheckFile(ProgramInfo *pginfo) 
    300339 */
    301340void EncoderLink::GetDiskSpace(QStringList &o_strlist)
    302341{
     342    if (disconnected)
     343        return;
     344
     345    QMutexLocker locker(&sockLock);
    303346    if (sock)
    304347        sock->GetDiskSpace(o_strlist);
    305348}
    void EncoderLink::GetDiskSpace(QStringList &o_strlist) 
    312355 */
    313356long long EncoderLink::GetMaxBitrate()
    314357{
     358    if (disconnected)
     359        return -1;
     360
    315361    if (local)
    316362        return tv->GetMaxBitrate();
    317     else if (sock)
    318         return sock->GetMaxBitrate(m_capturecardnum);
    319 
     363    else
     364    {
     365        QMutexLocker locker(&sockLock);
     366        if (sock)
     367            return sock->GetMaxBitrate(m_capturecardnum);
     368    }
    320369    return -1;
    321370}
    322371
    int EncoderLink::SetSignalMonitoringRate(int rate, int notifyFrontend) 
    338387{
    339388    if (local)
    340389        return tv->SetSignalMonitoringRate(rate, notifyFrontend);
    341     else if (sock)
    342         return sock->SetSignalMonitoringRate(m_capturecardnum, rate,
    343                                              notifyFrontend);
     390    else
     391    {
     392        QMutexLocker locker(&sockLock);
     393        if (sock)
     394            return sock->SetSignalMonitoringRate(m_capturecardnum, rate,
     395                                                 notifyFrontend);
     396    }
    344397    return -1;
    345398}
    346399
    int EncoderLink::SetSignalMonitoringRate(int rate, int notifyFrontend) 
    348401 */
    349402bool EncoderLink::GoToSleep(void)
    350403{
    351     if (IsLocal() || !sock)
     404    if (disconnected)
    352405        return false;
    353406
     407    if (IsLocal())
     408        return false;
     409
     410    QMutexLocker locker(&sockLock);
     411    if (!sock)
     412        return false;
     413
     414    if (sock->getBlockShutdown())
     415    {
     416        LOG(VB_GENERAL, LOG_NOTICE,
     417            QString("EncoderLink::GoToSleep() Socket shutdown is currently blocked!"));
     418        return false;
     419    }
     420
    354421    lastSleepTime = MythDate::current();
    355422
    356423    return sock->GoToSleep();
    bool EncoderLink::GoToSleep(void) 
    362429 */
    363430int EncoderLink::LockTuner()
    364431{
     432    if (disconnected)
     433        return -2;
     434
    365435    if (locked)
    366436        return -2;
    367437
    RecStatusType EncoderLink::StartRecording(const ProgramInfo *rec) 
    380450{
    381451    RecStatusType retval = rsAborted;
    382452
     453    if (disconnected)
     454        return retval;
     455
    383456    endRecordingTime = rec->GetRecordingEndTime();
    384457    startRecordingTime = rec->GetRecordingStartTime();
    385458    chanid = rec->GetChanID();
    386459
    387460    if (local)
    388461        retval = tv->StartRecording(rec);
    389     else if (sock)
    390         retval = sock->StartRecording(m_capturecardnum, rec);
    391462    else
    392         LOG(VB_GENERAL, LOG_ERR,
    393             QString("Wanted to start recording on recorder %1,\n\t\t\t"
    394                     "but the backend is not there anymore\n")
    395                 .arg(m_capturecardnum));
     463    {
     464        QMutexLocker locker(&sockLock);
     465        if (sock)
     466            retval = sock->StartRecording(m_capturecardnum, rec);
     467        else
     468            LOG(VB_GENERAL, LOG_ERR,
     469                QString("Wanted to start recording on recorder %1,\n\t\t\t"
     470                        "but the backend is not there anymore\n")
     471                    .arg(m_capturecardnum));
     472    }
    396473
    397474    if (retval != rsRecording && retval != rsTuning)
    398475    {
    RecStatusType EncoderLink::GetRecordingStatus(void) 
    408485{
    409486    RecStatusType retval = rsAborted;
    410487
     488    if (disconnected)
     489        return retval;
     490
    411491    if (local)
    412492        retval = tv->GetRecordingStatus();
    413     else if (sock)
    414         retval = sock->GetRecordingStatus(m_capturecardnum);
    415493    else
    416         LOG(VB_GENERAL, LOG_ERR,
    417             QString("Wanted to get status on recorder %1,\n\t\t\t"
    418                     "but the backend is not there anymore\n")
    419                 .arg(m_capturecardnum));
     494    {
     495        QMutexLocker locker(&sockLock);
     496        if (sock)
     497            retval = sock->GetRecordingStatus(m_capturecardnum);
     498        else
     499            LOG(VB_GENERAL, LOG_ERR,
     500                QString("Wanted to get status on recorder %1,\n\t\t\t"
     501                        "but the backend is not there anymore\n")
     502                    .arg(m_capturecardnum));
     503    }
    420504
    421505    if (retval != rsRecording && retval != rsTuning)
    422506    {
    ProgramInfo *EncoderLink::GetRecording(void) 
    438522{
    439523    ProgramInfo *info = NULL;
    440524
     525    if (disconnected)
     526        return info;
     527
    441528    if (local)
    442529        info = tv->GetRecording();
    443     else if (sock)
    444         info = sock->GetRecording(m_capturecardnum);
     530    else
     531    {
     532        QMutexLocker locker(&sockLock);
     533        if (sock)
     534            info = sock->GetRecording(m_capturecardnum);
     535    }
    445536
    446537    return info;
    447538}
    ProgramInfo *EncoderLink::GetRecording(void) 
    453544 */
    454545void EncoderLink::StopRecording(bool killFile)
    455546{
     547    if (disconnected)
     548        return;
     549
    456550    endRecordingTime = MythDate::current().addDays(-2);
    457551    startRecordingTime = endRecordingTime;
    458552    chanid = 0;
    void EncoderLink::StopRecording(bool killFile) 
    471565 */
    472566void EncoderLink::FinishRecording(void)
    473567{
     568    if (disconnected)
     569        return;
     570
    474571    if (local)
    475572    {
    476573        tv->FinishRecording();
    bool EncoderLink::IsReallyRecording(void) 
    505602 */
    506603float EncoderLink::GetFramerate(void)
    507604{
     605    if (disconnected)
     606        return -1;
     607
    508608    if (local)
    509609        return tv->GetFramerate();
    510610
    float EncoderLink::GetFramerate(void) 
    521621 */
    522622long long EncoderLink::GetFramesWritten(void)
    523623{
     624    if (disconnected)
     625        return -1;
     626
    524627    if (local)
    525628        return tv->GetFramesWritten();
    526629
    long long EncoderLink::GetFramesWritten(void) 
    536639 */
    537640long long EncoderLink::GetFilePosition(void)
    538641{
     642    if (disconnected)
     643        return -1;
     644
    539645    if (local)
    540646        return tv->GetFilePosition();
    541647
    long long EncoderLink::GetFilePosition(void) 
    551657 */
    552658int64_t EncoderLink::GetKeyframePosition(uint64_t desired)
    553659{
     660    if (disconnected)
     661        return -1;
     662
    554663    if (local)
    555664        return tv->GetKeyframePosition(desired);
    556665
    int64_t EncoderLink::GetKeyframePosition(uint64_t desired) 
    561670bool EncoderLink::GetKeyframePositions(
    562671    int64_t start, int64_t end, frm_pos_map_t &map)
    563672{
     673    if (disconnected)
     674        return false;
     675
    564676    if (!local)
    565677    {
    566678        LOG(VB_GENERAL, LOG_ERR,
    bool EncoderLink::GetKeyframePositions( 
    578690 */
    579691void EncoderLink::FrontendReady(void)
    580692{
     693    if (disconnected)
     694        return;
     695
    581696    if (local)
    582697        tv->FrontendReady();
    583698    else
    void EncoderLink::FrontendReady(void) 
    594709 */
    595710void EncoderLink::CancelNextRecording(bool cancel)
    596711{
     712    if (disconnected)
     713        return;
     714
    597715    if (local)
    598716        tv->CancelNextRecording(cancel);
    599717    else
    600         sock->CancelNextRecording(m_capturecardnum, cancel);
     718    {
     719        QMutexLocker locker(&sockLock);
     720        if (sock)
     721            sock->CancelNextRecording(m_capturecardnum, cancel);
     722    }
    601723}
    602724
    603725/** \fn EncoderLink::SpawnLiveTV(LiveTVChain*, bool, QString)
    void EncoderLink::CancelNextRecording(bool cancel) 
    613735 */
    614736void EncoderLink::SpawnLiveTV(LiveTVChain *chain, bool pip, QString startchan)
    615737{
     738    if (disconnected)
     739        return;
     740
    616741    if (local)
    617742        tv->SpawnLiveTV(chain, pip, startchan);
    618743    else
    void EncoderLink::SpawnLiveTV(LiveTVChain *chain, bool pip, QString startchan) 
    624749 */
    625750QString EncoderLink::GetChainID(void)
    626751{
     752    if (disconnected)
     753        return "";
     754
    627755    if (local)
    628756        return tv->GetChainID();
    629757
    QString EncoderLink::GetChainID(void) 
    638766 */
    639767void EncoderLink::StopLiveTV(void)
    640768{
     769    if (disconnected)
     770        return;
     771
    641772    if (local)
    642773        tv->StopLiveTV();
    643774    else
    void EncoderLink::StopLiveTV(void) 
    652783 */
    653784void EncoderLink::PauseRecorder(void)
    654785{
     786    if (disconnected)
     787        return;
     788
    655789    if (local)
    656790        tv->PauseRecorder();
    657791    else
    void EncoderLink::PauseRecorder(void) 
    665799 */
    666800void EncoderLink::SetLiveRecording(int recording)
    667801{
     802    if (disconnected)
     803        return;
     804
    668805    if (local)
    669806        tv->SetLiveRecording(recording);
    670807    else
    void EncoderLink::SetLiveRecording(int recording) 
    677814 */
    678815void EncoderLink::SetNextLiveTVDir(QString dir)
    679816{
     817    if (disconnected)
     818        return;
     819
    680820    if (local)
    681821        tv->SetNextLiveTVDir(dir);
    682822    else
    683         sock->SetNextLiveTVDir(m_capturecardnum, dir);
     823    {
     824        QMutexLocker locker(&sockLock);
     825        if (sock)
     826            sock->SetNextLiveTVDir(m_capturecardnum, dir);
     827    }
    684828}
    685829
    686830/** \fn EncoderLink::GetFreeInputs(const vector<uint>&) const
    void EncoderLink::SetNextLiveTVDir(QString dir) 
    689833 *  \sa TVRec::GetFreeInputs(const vector<uint>&) const
    690834 */
    691835vector<InputInfo> EncoderLink::GetFreeInputs(
    692     const vector<uint> &excluded_cardids) const
     836    const vector<uint> &excluded_cardids)
    693837{
    694838    vector<InputInfo> list;
    695839
     840    if (disconnected)
     841        return list;
     842
    696843    if (local)
    697844        list = tv->GetFreeInputs(excluded_cardids);
    698845    else
    699         list = sock->GetFreeInputs(m_capturecardnum, excluded_cardids);
     846    {
     847        QMutexLocker locker(&sockLock);
     848        if (sock)
     849            list = sock->GetFreeInputs(m_capturecardnum, excluded_cardids);
     850    }
    700851
    701852    return list;
    702853}
    vector<InputInfo> EncoderLink::GetFreeInputs( 
    709860 */
    710861QString EncoderLink::GetInput(void) const
    711862{
     863    if (disconnected)
     864        return QString();
     865
    712866    if (local)
    713867        return tv->GetInput();
    714868
    QString EncoderLink::GetInput(void) const 
    728882 */
    729883QString EncoderLink::SetInput(QString input)
    730884{
     885    if (disconnected)
     886        return QString();
     887
    731888    if (local)
    732889        return tv->SetInput(input);
    733890
    QString EncoderLink::SetInput(QString input) 
    742899 */
    743900void EncoderLink::ToggleChannelFavorite(QString changroup)
    744901{
     902    if (disconnected)
     903        return;
     904
    745905    if (local)
    746906        tv->ToggleChannelFavorite(changroup);
    747907    else
    void EncoderLink::ToggleChannelFavorite(QString changroup) 
    757917 */
    758918void EncoderLink::ChangeChannel(ChannelChangeDirection channeldirection)
    759919{
     920    if (disconnected)
     921        return;
     922
    760923    if (local)
    761924        tv->ChangeChannel(channeldirection);
    762925    else
    void EncoderLink::ChangeChannel(ChannelChangeDirection channeldirection) 
    772935 */
    773936void EncoderLink::SetChannel(const QString &name)
    774937{
     938    if (disconnected)
     939        return;
     940
    775941    if (local)
    776942        tv->SetChannel(name);
    777943    else
    void EncoderLink::SetChannel(const QString &name) 
    788954 */
    789955int EncoderLink::GetPictureAttribute(PictureAttribute attr)
    790956{
     957    if (disconnected)
     958        return -1;
     959
    791960    if (!local)
    792961    {
    793962        LOG(VB_GENERAL, LOG_ERR,
    int EncoderLink::ChangePictureAttribute(PictureAdjustType type, 
    810979                                        PictureAttribute  attr,
    811980                                        bool              direction)
    812981{
     982    if (disconnected)
     983        return -1;
     984
    813985    if (!local)
    814986    {
    815987        LOG(VB_GENERAL, LOG_ERR,
    int EncoderLink::ChangePictureAttribute(PictureAdjustType type, 
    8311003 */
    8321004bool EncoderLink::CheckChannel(const QString &name)
    8331005{
     1006    if (disconnected)
     1007        return false;
     1008
    8341009    if (local)
    8351010        return tv->CheckChannel(name);
    8361011
    bool EncoderLink::CheckChannel(const QString &name) 
    8491024 */
    8501025bool EncoderLink::ShouldSwitchToAnotherCard(const QString &channelid)
    8511026{
     1027    if (disconnected)
     1028        return false;
     1029
    8521030    if (local)
    8531031        return tv->ShouldSwitchToAnotherCard(channelid);
    8541032
    bool EncoderLink::CheckChannelPrefix( 
    8701048    bool          &is_extra_char_useful,
    8711049    QString       &needed_spacer)
    8721050{
     1051    if (disconnected)
     1052        return false;
     1053
    8731054    if (local)
    8741055    {
    8751056        return tv->CheckChannelPrefix(
    void EncoderLink::GetNextProgram(BrowseDirection direction, 
    8971078                                 QString &channelname, uint    &_chanid,
    8981079                                 QString &seriesid,    QString &programid)
    8991080{
     1081    if (disconnected)
     1082        return;
     1083
    9001084    if (local)
    9011085    {
    9021086        tv->GetNextProgram(direction,
    bool EncoderLink::GetChannelInfo(uint &chanid, uint &sourceid, 
    9121096                                 QString &callsign, QString &channum,
    9131097                                 QString &channame, QString &xmltv) const
    9141098{
     1099    if (disconnected)
     1100        return false;
     1101
    9151102    if (!local)
    9161103    {
    9171104        LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetChannelInfo");
    bool EncoderLink::SetChannelInfo(uint chanid, uint sourceid, 
    9271114                                 QString callsign, QString channum,
    9281115                                 QString channame, QString xmltv)
    9291116{
     1117    if (disconnected)
     1118        return false;
     1119
    9301120    if (!local)
    9311121    {
    9321122        LOG(VB_GENERAL, LOG_ERR, "Should be local only query: SetChannelInfo");
  • mythtv/programs/mythbackend/encoderlink.h

    diff --git a/mythtv/programs/mythbackend/encoderlink.h b/mythtv/programs/mythbackend/encoderlink.h
    index 09eaae1..2729eee 100644
    a b  
    33
    44#include <QString>
    55#include <QMap>
     6#include <QMutex>
    67
    78#include "tv.h"
    89#include "programinfo.h"
    class EncoderLink 
    2324
    2425    /// \brief Used to set the socket for a non-local EncoderLink.
    2526    void SetSocket(PlaybackSock *lsock);
     27
     28    void Disconnect();
     29
    2630    /// \brief Returns the socket, if set, for a non-local EncoderLink.
    2731    PlaybackSock *GetSocket(void) { return sock; }
    2832
    class EncoderLink 
    4246    /// \brief Returns true for a local EncoderLink.
    4347    bool IsLocal(void) const { return local; }
    4448    /// \brief Returns true if the EncoderLink instance is usable.
    45     bool IsConnected(void) const { return (IsLocal() || sock!=NULL); }
     49    bool IsConnected(void) { bool value;
     50                             if (disconnected)
     51                                 return false;
     52                             value = IsLocal();
     53                             if (value)
     54                                 return value;
     55                             if (sock)
     56                                 return true;
     57                             return false;
     58                           }
    4659    /// \brief Returns true if the encoder is awake.
    4760    bool IsAwake(void) const { return (sleepStatus == sStatus_Awake); }
    4861    /// \brief Returns true if the encoder is asleep.
    class EncoderLink 
    8295    bool IsBusyRecording(void);
    8396
    8497    TVState GetState();
    85     uint GetFlags(void) const;
     98    uint GetFlags(void);
    8699    bool IsRecording(const ProgramInfo *rec); // scheduler call only.
    87100
    88101    bool MatchesRecording(const ProgramInfo *rec);
    class EncoderLink 
    108121    void PauseRecorder(void);
    109122    void SetLiveRecording(int);
    110123    void SetNextLiveTVDir(QString dir);
    111     vector<InputInfo> GetFreeInputs(const vector<uint> &excluded_cards) const;
     124    vector<InputInfo> GetFreeInputs(const vector<uint> &excluded_cards);
    112125    QString GetInput(void) const;
    113126    QString SetInput(QString);
    114127    void ToggleChannelFavorite(QString);
    class EncoderLink 
    138151  private:
    139152    int m_capturecardnum;
    140153
     154    QMutex sockLock;
     155
    141156    PlaybackSock *sock;
     157
    142158    QString hostname;
    143159
    144160    long long freeDiskSpaceKB;
    class EncoderLink 
    147163
    148164    bool local;
    149165    bool locked;
     166    bool disconnected;
    150167
    151168    SleepStatus sleepStatus;
    152169    QDateTime sleepStatusTime;
  • mythtv/programs/mythbackend/mainserver.cpp

    diff --git a/mythtv/programs/mythbackend/mainserver.cpp b/mythtv/programs/mythbackend/mainserver.cpp
    index ba1fbc5..e4c5fd2 100644
    a b void MainServer::connectionClosed(MythSocket *socket) 
    57495749                        if (!elink->IsFallingAsleep())
    57505750                            isFallingAsleep = false;
    57515751
    5752                         elink->SetSocket(NULL);
     5752                        // elink->SetSocket(NULL);
     5753                        elink->Disconnect();
    57535754                        if (m_sched)
    57545755                            disconnectedSlaves.push_back(elink->GetCardID());
    57555756                    }
  • mythtv/programs/mythbackend/playbacksock.cpp

    diff --git a/mythtv/programs/mythbackend/playbacksock.cpp b/mythtv/programs/mythbackend/playbacksock.cpp
    index 30b76063..36bd6fc 100644
    a b using namespace std; 
    1717PlaybackSock::PlaybackSock(
    1818    MainServer *parent, MythSocket *lsock,
    1919    QString lhostname, PlaybackSockEventsMode eventsMode) :
    20     ReferenceCounter("PlaybackSock")
     20    ReferenceCounter("PlaybackSock"),
     21    sockLock(QMutex::Recursive)
    2122{
    2223    m_parent = parent;
    2324    QString localhostname = gCoreContext->GetHostName();
    bool PlaybackSock::SendReceiveStringList( 
    7778{
    7879    bool ok = false;
    7980
     81    QMutexLocker locker(&sockLock);
     82
     83    if (!sock)
     84        return false;
     85
    8086    sock->IncrRef();
    81     sock->Lock();
     87
     88    bool status = false;
     89    unsigned int loop=10;
     90    status = sock->TryLock(false);
     91    while ((status == false) && (loop > 0))
     92    {
     93        --loop;
     94        locker.unlock();
     95        usleep(10000);
     96        status = sock->TryLock(false);
     97    }
     98    if (status == false)
     99    {
     100        sock->DecrRef();
     101        return false;
     102
     103    }
     104
     105    locker.relock();
     106
     107    if (!sock)
     108    {
     109        sock->DecrRef();
     110        return false;
     111    }
    82112
    83113    {
    84         QMutexLocker locker(&sockLock);
    85114        expectingreply = true;
    86115
    87116        sock->writeStringList(strlist);
    bool PlaybackSock::IsBusy(int capturecardnum, InputInfo *busy_input, 
    322351{
    323352    QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
    324353
     354    QMutexLocker locker(&sockLock);
     355    if (disconnected)
     356        return true;
     357
    325358    strlist << "IS_BUSY";
    326359    strlist << QString::number(time_buffer);
    327360
  • mythtv/programs/mythbackend/playbacksock.h

    diff --git a/mythtv/programs/mythbackend/playbacksock.h b/mythtv/programs/mythbackend/playbacksock.h
    index c273604..a74d43b 100644
    a b class PlaybackSock : public ReferenceCounter 
    3131                 QString lhostname, PlaybackSockEventsMode eventsMode);
    3232    virtual ~PlaybackSock();
    3333
    34     void SetDisconnected(void) { disconnected = true; }
     34    void SetDisconnected(void) { QMutexLocker locker(&sockLock); disconnected = true; }
    3535    bool IsDisconnected(void) const { return disconnected; }
    3636
    3737    MythSocket *getSocket(void) const { return sock; }