Ticket #11306: slave_shutdown_deadlock_v3.patch

File slave_shutdown_deadlock_v3.patch, 23.9 KB (added by Tomi Orava <tomi.orava@…>, 8 years ago)

Updated slave backend deadlock patch v3

  • mythtv/programs/mythbackend/encoderlink.cpp

    diff --git a/mythtv/programs/mythbackend/encoderlink.cpp b/mythtv/programs/mythbackend/encoderlink.cpp
    index 2c7bc76..24113fa 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;
     108    disconnected = false;
     109}
     110
     111void EncoderLink::Disconnect()
     112{
     113  disconnected = true;
     114  if (IsFallingAsleep())
     115      SetSleepStatus(sStatus_Asleep);
     116  else
     117      SetSleepStatus(sStatus_Undefined);
     118
     119  if (sock)
     120      sock->DecrRef();
    113121}
    114122
    115123/** \fn EncoderLink::SetSleepStatus(SleepStatus)
    void EncoderLink::SetSleepStatus(SleepStatus newStatus) 
    128136 */
    129137bool EncoderLink::IsBusy(TunedInputInfo *busy_input, int time_buffer)
    130138{
     139    if (disconnected)
     140        return false;
     141
    131142    if (local)
    132143        return tv->IsBusy(busy_input, time_buffer);
    133144
     145    QMutexLocker locker(&sockLock);
    134146    if (sock)
    135147        return sock->IsBusy(m_capturecardnum, busy_input, time_buffer);
    136148
    bool EncoderLink::IsBusyRecording(void) 
    149161{
    150162    bool retval = false;
    151163
     164    if (disconnected)
     165        return false;
     166
    152167    TVState state = GetState();
    153168
    154169    if (state == kState_RecordingOnly || state == kState_WatchingRecording ||
    TVState EncoderLink::GetState(void) 
    174189    if (local)
    175190        retval = tv->GetState();
    176191    else if (sock)
    177         retval = (TVState)sock->GetEncoderState(m_capturecardnum);
     192    {
     193        QMutexLocker locker(&sockLock);
     194        if (sock)
     195            retval = (TVState)sock->GetEncoderState(m_capturecardnum);
     196    }
    178197    else
    179198        LOG(VB_GENERAL, LOG_ERR, QString("Broken for card: %1")
    180199            .arg(m_capturecardnum));
    TVState EncoderLink::GetState(void) 
    186205 *  \brief Returns the flag state of the recorder.
    187206 *  \sa TVRec::GetFlags(void) const, \ref recorder_subsystem
    188207 */
    189 uint EncoderLink::GetFlags(void) const
     208uint EncoderLink::GetFlags(void)
    190209{
    191210    uint retval = 0;
    192211
    193     if (!IsConnected())
     212    if (disconnected)
    194213        return retval;
    195214
    196215    if (local)
    197216        retval = tv->GetFlags();
    198217    else if (sock)
    199         retval = sock->GetEncoderState(m_capturecardnum);
     218    {
     219        QMutexLocker locker(&sockLock);
     220        if (sock)
     221            retval = sock->GetEncoderState(m_capturecardnum);
     222    }
    200223    else
    201224        LOG(VB_GENERAL, LOG_ERR, LOC + "GetFlags failed");
    202225
    uint EncoderLink::GetFlags(void) const 
    210233 */
    211234bool EncoderLink::IsRecording(const ProgramInfo *rec)
    212235{
     236    if (disconnected)
     237        return false;
    213238    return (rec->GetChanID() == chanid &&
    214239            rec->GetRecordingStartTime() == startRecordingTime);
    215240}
    bool EncoderLink::MatchesRecording(const ProgramInfo *rec) 
    227252    bool retval = false;
    228253    ProgramInfo *tvrec = NULL;
    229254
     255    if (disconnected)
     256        return false;
     257
    230258    if (local)
    231259    {
    232260        while (kState_ChangingState == GetState())
    bool EncoderLink::MatchesRecording(const ProgramInfo *rec) 
    243271    }
    244272    else
    245273    {
     274        QMutexLocker locker(&sockLock);
    246275        if (sock)
    247276            retval = sock->EncoderIsRecording(m_capturecardnum, rec);
    248277    }
    bool EncoderLink::MatchesRecording(const ProgramInfo *rec) 
    261290void EncoderLink::RecordPending(const ProgramInfo *rec, int secsleft,
    262291                                bool hasLater)
    263292{
     293    if (disconnected)
     294        return;
     295
    264296    if (local)
    265297        tv->RecordPending(rec, secsleft, hasLater);
    266     else if (sock)
    267         sock->RecordPending(m_capturecardnum, rec, secsleft, hasLater);
     298    else
     299    {
     300        QMutexLocker locker(&sockLock);
     301        if (sock)
     302            sock->RecordPending(m_capturecardnum, rec, secsleft, hasLater);
     303   }
    268304}
    269305
    270306/** \fn EncoderLink::WouldConflict(const ProgramInfo*)
    bool EncoderLink::WouldConflict(const ProgramInfo *rec) 
    286322/// Checks if program is stored locally
    287323bool EncoderLink::CheckFile(ProgramInfo *pginfo)
    288324{
     325    if (disconnected)
     326        return false;
     327
     328    QMutexLocker locker(&sockLock);
    289329    if (sock)
    290330        return sock->CheckFile(pginfo);
    291331
    bool EncoderLink::CheckFile(ProgramInfo *pginfo) 
    300340 */
    301341void EncoderLink::GetDiskSpace(QStringList &o_strlist)
    302342{
     343    if (disconnected)
     344        return;
     345
     346    QMutexLocker locker(&sockLock);
    303347    if (sock)
    304348        sock->GetDiskSpace(o_strlist);
    305349}
    void EncoderLink::GetDiskSpace(QStringList &o_strlist) 
    312356 */
    313357long long EncoderLink::GetMaxBitrate()
    314358{
     359    if (disconnected)
     360        return -1;
     361
    315362    if (local)
    316363        return tv->GetMaxBitrate();
    317     else if (sock)
    318         return sock->GetMaxBitrate(m_capturecardnum);
    319 
     364    else
     365    {
     366        QMutexLocker locker(&sockLock);
     367        if (sock)
     368            return sock->GetMaxBitrate(m_capturecardnum);
     369    }
    320370    return -1;
    321371}
    322372
    int EncoderLink::SetSignalMonitoringRate(int rate, int notifyFrontend) 
    338388{
    339389    if (local)
    340390        return tv->SetSignalMonitoringRate(rate, notifyFrontend);
    341     else if (sock)
    342         return sock->SetSignalMonitoringRate(m_capturecardnum, rate,
    343                                              notifyFrontend);
     391    else
     392    {
     393        QMutexLocker locker(&sockLock);
     394        if (sock)
     395            return sock->SetSignalMonitoringRate(m_capturecardnum, rate,
     396                                                 notifyFrontend);
     397    }
    344398    return -1;
    345399}
    346400
    int EncoderLink::SetSignalMonitoringRate(int rate, int notifyFrontend) 
    348402 */
    349403bool EncoderLink::GoToSleep(void)
    350404{
    351     if (IsLocal() || !sock)
     405    if (disconnected)
    352406        return false;
    353407
     408    if (IsLocal())
     409        return false;
     410
     411    QMutexLocker locker(&sockLock);
     412    if (!sock)
     413        return false;
     414
     415    if (sock->getBlockShutdown())
     416    {
     417        LOG(VB_GENERAL, LOG_NOTICE,
     418            QString("EncoderLink::GoToSleep() Socket shutdown is currently blocked!"));
     419        return false;
     420    }
     421
    354422    lastSleepTime = MythDate::current();
    355423
    356424    return sock->GoToSleep();
    bool EncoderLink::GoToSleep(void) 
    362430 */
    363431int EncoderLink::LockTuner()
    364432{
     433    if (disconnected)
     434        return -2;
     435
    365436    if (locked)
    366437        return -2;
    367438
    RecStatusType EncoderLink::StartRecording(const ProgramInfo *rec) 
    380451{
    381452    RecStatusType retval = rsAborted;
    382453
     454    if (disconnected)
     455        return retval;
     456
    383457    endRecordingTime = rec->GetRecordingEndTime();
    384458    startRecordingTime = rec->GetRecordingStartTime();
    385459    chanid = rec->GetChanID();
    386460
    387461    if (local)
    388462        retval = tv->StartRecording(rec);
    389     else if (sock)
    390         retval = sock->StartRecording(m_capturecardnum, rec);
    391463    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));
     464    {
     465        QMutexLocker locker(&sockLock);
     466        if (sock)
     467            retval = sock->StartRecording(m_capturecardnum, rec);
     468        else
     469            LOG(VB_GENERAL, LOG_ERR,
     470                QString("Wanted to start recording on recorder %1,\n\t\t\t"
     471                        "but the backend is not there anymore\n")
     472                    .arg(m_capturecardnum));
     473    }
    396474
    397475    if (retval != rsRecording && retval != rsTuning)
    398476    {
    RecStatusType EncoderLink::GetRecordingStatus(void) 
    408486{
    409487    RecStatusType retval = rsAborted;
    410488
     489    if (disconnected)
     490        return retval;
     491
    411492    if (local)
    412493        retval = tv->GetRecordingStatus();
    413     else if (sock)
    414         retval = sock->GetRecordingStatus(m_capturecardnum);
    415494    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));
     495    {
     496        QMutexLocker locker(&sockLock);
     497        if (sock)
     498            retval = sock->GetRecordingStatus(m_capturecardnum);
     499        else
     500            LOG(VB_GENERAL, LOG_ERR,
     501                QString("Wanted to get status on recorder %1,\n\t\t\t"
     502                        "but the backend is not there anymore\n")
     503                    .arg(m_capturecardnum));
     504    }
    420505
    421506    if (retval != rsRecording && retval != rsTuning)
    422507    {
    ProgramInfo *EncoderLink::GetRecording(void) 
    438523{
    439524    ProgramInfo *info = NULL;
    440525
     526    if (disconnected)
     527        return info;
     528
    441529    if (local)
    442530        info = tv->GetRecording();
    443     else if (sock)
    444         info = sock->GetRecording(m_capturecardnum);
     531    else
     532    {
     533        QMutexLocker locker(&sockLock);
     534        if (sock)
     535            info = sock->GetRecording(m_capturecardnum);
     536    }
    445537
    446538    return info;
    447539}
    ProgramInfo *EncoderLink::GetRecording(void) 
    453545 */
    454546void EncoderLink::StopRecording(bool killFile)
    455547{
     548    if (disconnected)
     549        return;
     550
    456551    endRecordingTime = MythDate::current().addDays(-2);
    457552    startRecordingTime = endRecordingTime;
    458553    chanid = 0;
    void EncoderLink::StopRecording(bool killFile) 
    471566 */
    472567void EncoderLink::FinishRecording(void)
    473568{
     569    if (disconnected)
     570        return;
     571
    474572    if (local)
    475573    {
    476574        tv->FinishRecording();
    bool EncoderLink::IsReallyRecording(void) 
    505603 */
    506604float EncoderLink::GetFramerate(void)
    507605{
     606    if (disconnected)
     607        return -1;
     608
    508609    if (local)
    509610        return tv->GetFramerate();
    510611
    float EncoderLink::GetFramerate(void) 
    521622 */
    522623long long EncoderLink::GetFramesWritten(void)
    523624{
     625    if (disconnected)
     626        return -1;
     627
    524628    if (local)
    525629        return tv->GetFramesWritten();
    526630
    long long EncoderLink::GetFramesWritten(void) 
    536640 */
    537641long long EncoderLink::GetFilePosition(void)
    538642{
     643    if (disconnected)
     644        return -1;
     645
    539646    if (local)
    540647        return tv->GetFilePosition();
    541648
    long long EncoderLink::GetFilePosition(void) 
    551658 */
    552659int64_t EncoderLink::GetKeyframePosition(uint64_t desired)
    553660{
     661    if (disconnected)
     662        return -1;
     663
    554664    if (local)
    555665        return tv->GetKeyframePosition(desired);
    556666
    int64_t EncoderLink::GetKeyframePosition(uint64_t desired) 
    561671bool EncoderLink::GetKeyframePositions(
    562672    int64_t start, int64_t end, frm_pos_map_t &map)
    563673{
     674    if (disconnected)
     675        return false;
     676
    564677    if (!local)
    565678    {
    566679        LOG(VB_GENERAL, LOG_ERR,
    bool EncoderLink::GetKeyframePositions( 
    578691 */
    579692void EncoderLink::FrontendReady(void)
    580693{
     694    if (disconnected)
     695        return;
     696
    581697    if (local)
    582698        tv->FrontendReady();
    583699    else
    void EncoderLink::FrontendReady(void) 
    594710 */
    595711void EncoderLink::CancelNextRecording(bool cancel)
    596712{
     713    if (disconnected)
     714        return;
     715
    597716    if (local)
    598717        tv->CancelNextRecording(cancel);
    599718    else
    600         sock->CancelNextRecording(m_capturecardnum, cancel);
     719    {
     720        QMutexLocker locker(&sockLock);
     721        if (sock)
     722            sock->CancelNextRecording(m_capturecardnum, cancel);
     723    }
    601724}
    602725
    603726/** \fn EncoderLink::SpawnLiveTV(LiveTVChain*, bool, QString)
    void EncoderLink::CancelNextRecording(bool cancel) 
    613736 */
    614737void EncoderLink::SpawnLiveTV(LiveTVChain *chain, bool pip, QString startchan)
    615738{
     739    if (disconnected)
     740        return;
     741
    616742    if (local)
    617743        tv->SpawnLiveTV(chain, pip, startchan);
    618744    else
    void EncoderLink::SpawnLiveTV(LiveTVChain *chain, bool pip, QString startchan) 
    624750 */
    625751QString EncoderLink::GetChainID(void)
    626752{
     753    if (disconnected)
     754        return "";
     755
    627756    if (local)
    628757        return tv->GetChainID();
    629758
    QString EncoderLink::GetChainID(void) 
    638767 */
    639768void EncoderLink::StopLiveTV(void)
    640769{
     770    if (disconnected)
     771        return;
     772
    641773    if (local)
    642774        tv->StopLiveTV();
    643775    else
    void EncoderLink::StopLiveTV(void) 
    652784 */
    653785void EncoderLink::PauseRecorder(void)
    654786{
     787    if (disconnected)
     788        return;
     789
    655790    if (local)
    656791        tv->PauseRecorder();
    657792    else
    void EncoderLink::PauseRecorder(void) 
    665800 */
    666801void EncoderLink::SetLiveRecording(int recording)
    667802{
     803    if (disconnected)
     804        return;
     805
    668806    if (local)
    669807        tv->SetLiveRecording(recording);
    670808    else
    void EncoderLink::SetLiveRecording(int recording) 
    677815 */
    678816void EncoderLink::SetNextLiveTVDir(QString dir)
    679817{
     818    if (disconnected)
     819        return;
     820
    680821    if (local)
    681822        tv->SetNextLiveTVDir(dir);
    682823    else
    683         sock->SetNextLiveTVDir(m_capturecardnum, dir);
     824    {
     825        QMutexLocker locker(&sockLock);
     826        if (sock)
     827            sock->SetNextLiveTVDir(m_capturecardnum, dir);
     828    }
    684829}
    685830
    686831/** \fn EncoderLink::GetFreeInputs(const vector<uint>&) const
    void EncoderLink::SetNextLiveTVDir(QString dir) 
    689834 *  \sa TVRec::GetFreeInputs(const vector<uint>&) const
    690835 */
    691836vector<InputInfo> EncoderLink::GetFreeInputs(
    692     const vector<uint> &excluded_cardids) const
     837    const vector<uint> &excluded_cardids)
    693838{
    694839    vector<InputInfo> list;
    695840
     841    if (disconnected)
     842        return list;
     843
    696844    if (local)
    697845        list = tv->GetFreeInputs(excluded_cardids);
    698846    else
    699         list = sock->GetFreeInputs(m_capturecardnum, excluded_cardids);
     847    {
     848        QMutexLocker locker(&sockLock);
     849        if (sock)
     850            list = sock->GetFreeInputs(m_capturecardnum, excluded_cardids);
     851    }
    700852
    701853    return list;
    702854}
    vector<InputInfo> EncoderLink::GetFreeInputs( 
    709861 */
    710862QString EncoderLink::GetInput(void) const
    711863{
     864    if (disconnected)
     865        return QString();
     866
    712867    if (local)
    713868        return tv->GetInput();
    714869
    QString EncoderLink::GetInput(void) const 
    728883 */
    729884QString EncoderLink::SetInput(QString input)
    730885{
     886    if (disconnected)
     887        return QString();
     888
    731889    if (local)
    732890        return tv->SetInput(input);
    733891
    QString EncoderLink::SetInput(QString input) 
    742900 */
    743901void EncoderLink::ToggleChannelFavorite(QString changroup)
    744902{
     903    if (disconnected)
     904        return;
     905
    745906    if (local)
    746907        tv->ToggleChannelFavorite(changroup);
    747908    else
    void EncoderLink::ToggleChannelFavorite(QString changroup) 
    757918 */
    758919void EncoderLink::ChangeChannel(ChannelChangeDirection channeldirection)
    759920{
     921    if (disconnected)
     922        return;
     923
    760924    if (local)
    761925        tv->ChangeChannel(channeldirection);
    762926    else
    void EncoderLink::ChangeChannel(ChannelChangeDirection channeldirection) 
    772936 */
    773937void EncoderLink::SetChannel(const QString &name)
    774938{
     939    if (disconnected)
     940        return;
     941
    775942    if (local)
    776943        tv->SetChannel(name);
    777944    else
    void EncoderLink::SetChannel(const QString &name) 
    788955 */
    789956int EncoderLink::GetPictureAttribute(PictureAttribute attr)
    790957{
     958    if (disconnected)
     959        return -1;
     960
    791961    if (!local)
    792962    {
    793963        LOG(VB_GENERAL, LOG_ERR,
    int EncoderLink::ChangePictureAttribute(PictureAdjustType type, 
    810980                                        PictureAttribute  attr,
    811981                                        bool              direction)
    812982{
     983    if (disconnected)
     984        return -1;
     985
    813986    if (!local)
    814987    {
    815988        LOG(VB_GENERAL, LOG_ERR,
    int EncoderLink::ChangePictureAttribute(PictureAdjustType type, 
    8311004 */
    8321005bool EncoderLink::CheckChannel(const QString &name)
    8331006{
     1007    if (disconnected)
     1008        return false;
     1009
    8341010    if (local)
    8351011        return tv->CheckChannel(name);
    8361012
    bool EncoderLink::CheckChannel(const QString &name) 
    8491025 */
    8501026bool EncoderLink::ShouldSwitchToAnotherCard(const QString &channelid)
    8511027{
     1028    if (disconnected)
     1029        return false;
     1030
    8521031    if (local)
    8531032        return tv->ShouldSwitchToAnotherCard(channelid);
    8541033
    bool EncoderLink::CheckChannelPrefix( 
    8701049    bool          &is_extra_char_useful,
    8711050    QString       &needed_spacer)
    8721051{
     1052    if (disconnected)
     1053        return false;
     1054
    8731055    if (local)
    8741056    {
    8751057        return tv->CheckChannelPrefix(
    void EncoderLink::GetNextProgram(BrowseDirection direction, 
    8971079                                 QString &channelname, uint    &_chanid,
    8981080                                 QString &seriesid,    QString &programid)
    8991081{
     1082    if (disconnected)
     1083        return;
     1084
    9001085    if (local)
    9011086    {
    9021087        tv->GetNextProgram(direction,
    bool EncoderLink::GetChannelInfo(uint &chanid, uint &sourceid, 
    9121097                                 QString &callsign, QString &channum,
    9131098                                 QString &channame, QString &xmltv) const
    9141099{
     1100    if (disconnected)
     1101        return false;
     1102
    9151103    if (!local)
    9161104    {
    9171105        LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetChannelInfo");
    bool EncoderLink::SetChannelInfo(uint chanid, uint sourceid, 
    9271115                                 QString callsign, QString channum,
    9281116                                 QString channame, QString xmltv)
    9291117{
     1118    if (disconnected)
     1119        return false;
     1120
    9301121    if (!local)
    9311122    {
    9321123        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..a116e25 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=50;
     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        return false;
    82109
    83110    {
    84         QMutexLocker locker(&sockLock);
    85111        expectingreply = true;
    86112
    87113        sock->writeStringList(strlist);
    bool PlaybackSock::IsBusy(int capturecardnum, InputInfo *busy_input, 
    322348{
    323349    QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
    324350
     351    QMutexLocker locker(&sockLock);
     352    if (disconnected)
     353        return true;
     354
    325355    strlist << "IS_BUSY";
    326356    strlist << QString::number(time_buffer);
    327357
  • 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; }