Ticket #11238: 0001-Added-SafeConnectToMasterServer-to-CoreContext-to-pr.patch

File 0001-Added-SafeConnectToMasterServer-to-CoreContext-to-pr.patch, 6.1 KB (added by peper03@…, 13 years ago)
  • mythtv/libs/libmythbase/mythcorecontext.cpp

    From cba520a9d9c98b6715e57cc558ecc9e3a4749ecd Mon Sep 17 00:00:00 2001
    From: Richard <peper03@yahoo.com>
    Date: Fri, 16 Nov 2012 00:03:39 +0100
    Subject: [PATCH] Added 'SafeConnectToMasterServer' to CoreContext to provide
     a defined, thread-safe way to connect to the master server.
    
    ---
     mythtv/libs/libmythbase/mythcorecontext.cpp        |   81 ++++++++++++++++++++
     mythtv/libs/libmythbase/mythcorecontext.h          |    6 ++
     .../mythfrontend/backendconnectionmanager.cpp      |    2 +-
     3 files changed, 88 insertions(+), 1 deletion(-)
    
    diff --git a/mythtv/libs/libmythbase/mythcorecontext.cpp b/mythtv/libs/libmythbase/mythcorecontext.cpp
    index 1e15dfb..873db89 100644
    a b class MythCoreContextPrivate : public QObject  
    8787    MythScheduler *m_scheduler;
    8888
    8989    bool m_blockingClient;
     90
     91    QMap<QObject *, QByteArray> m_playbackClients;
     92    QMutex m_playbackLock;
    9093};
    9194
    9295MythCoreContextPrivate::MythCoreContextPrivate(MythCoreContext *lparent,
    bool MythCoreContext::SetupCommandSocket(MythSocket *serverSock,  
    283286    return true;
    284287}
    285288
     289// Connects to master server safely (i.e. by taking m_sockLock)
     290bool MythCoreContext::SafeConnectToMasterServer(bool openEventSocket)
     291{
     292    QMutexLocker locker(&d->m_sockLock);
     293    if (!d->m_serverSock)
     294    {
     295        bool blockingClient = GetNumSetting("idleTimeoutSecs",0) > 0;
     296        ConnectToMasterServer(blockingClient, openEventSocket);
     297    }
     298}
     299
    286300// Assumes that either m_sockLock is held, or the app is still single
    287301// threaded (i.e. during startup).
    288302bool MythCoreContext::ConnectToMasterServer(bool blockingClient,
    void MythCoreContext::WaitUntilSignals(const char *signal1, ...)  
    13641378    eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
    13651379}
    13661380
     1381/**
     1382 * \fn void MythCoreContext::RegisterForPlayback(QObject *sender, const char *method)
     1383 * Register sender for TVPlaybackAboutToStart signal. Method will be called upon
     1384 * the signal being emitted.
     1385 * sender must call MythCoreContext::UnregisterForPlayback upon deletion
     1386 */
     1387void MythCoreContext::RegisterForPlayback(QObject *sender, const char *method)
     1388{
     1389    QMutexLocker lock(&d->m_playbackLock);
     1390
     1391    if (!d->m_playbackClients.contains(sender))
     1392    {
     1393        d->m_playbackClients.insert(sender, QByteArray(method));
     1394        connect(this, SIGNAL(TVPlaybackAboutToStart()),
     1395                sender, method,
     1396                Qt::BlockingQueuedConnection);
     1397    }
     1398}
     1399
     1400/**
     1401 * \fn void MythCoreContext::UnregisterForPlayback(QObject *sender)
     1402 * Unregister sender from being called when TVPlaybackAboutToStart signal
     1403 * is emitted
     1404 */
     1405void MythCoreContext::UnregisterForPlayback(QObject *sender)
     1406{
     1407    QMutexLocker lock(&d->m_playbackLock);
     1408
     1409    if (d->m_playbackClients.contains(sender))
     1410    {
     1411        QByteArray ba = d->m_playbackClients.value(sender);
     1412        const char *method = ba.constData();
     1413        disconnect(this, SIGNAL(TVPlaybackAboutToStart()),
     1414                   sender, method);
     1415        d->m_playbackClients.remove(sender);
     1416    }
     1417}
     1418
     1419/**
     1420 * \fn void MythCoreContext::WantingPlayback(QObject *sender)
     1421 * All the objects that have registered using MythCoreContext::RegisterForPlayback
     1422 * but sender will be called. The objet's registered method will be called
     1423 * in a blocking fashion, each of them being called one after the other
     1424 */
     1425void MythCoreContext::WantingPlayback(QObject *sender)
     1426{
     1427    QMutexLocker lock(&d->m_playbackLock);
     1428    bool found = false;
     1429    QByteArray ba;
     1430    const char *method;
     1431
     1432    if (d->m_playbackClients.contains(sender))
     1433    {
     1434        found = true;
     1435        ba = d->m_playbackClients.value(sender);
     1436        method = ba.constData();
     1437        disconnect(this, SIGNAL(TVPlaybackAboutToStart()), sender, method);
     1438    }
     1439    emit TVPlaybackAboutToStart();
     1440    if (found)
     1441    {
     1442        connect(this, SIGNAL(TVPlaybackAboutToStart()),
     1443                sender, method,
     1444                Qt::BlockingQueuedConnection);
     1445    }
     1446}
     1447
    13671448/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • mythtv/libs/libmythbase/mythcorecontext.h

    diff --git a/mythtv/libs/libmythbase/mythcorecontext.h b/mythtv/libs/libmythbase/mythcorecontext.h
    index 5cfbc01..0bd98ce 100644
    a b class MBASE_PUBLIC MythCoreContext : public QObject, public MythObservable, publ  
    5959    void SetEventSocket(MythSocket *eventSock);
    6060    void SetScheduler(MythScheduler *sched);
    6161
     62    bool SafeConnectToMasterServer(bool openEventSocket = true);
    6263    bool ConnectToMasterServer(bool blockingClient = true,
    6364                               bool openEventSocket = true);
    6465
    class MBASE_PUBLIC MythCoreContext : public QObject, public MythObservable, publ  
    169170    QString GetLanguageAndVariant(void);
    170171    void ResetLanguage(void);
    171172
     173    void RegisterForPlayback(QObject *sender, const char *method);
     174    void UnregisterForPlayback(QObject *sender);
     175    void WantingPlayback(QObject *sender);
     176
    172177    // signal related methods
    173178    void WaitUntilSignals(const char *signal1, ...);
    174179    void emitTVPlaybackStarted(void)            { emit TVPlaybackStarted(); }
    class MBASE_PUBLIC MythCoreContext : public QObject, public MythObservable, publ  
    185190    void TVPlaybackPaused(void);
    186191    void TVPlaybackUnpaused(void);
    187192    void TVPlaybackAborted(void);
     193    void TVPlaybackAboutToStart(void);
    188194
    189195  private:
    190196    MythCoreContextPrivate *d;
  • mythtv/programs/mythfrontend/backendconnectionmanager.cpp

    diff --git a/mythtv/programs/mythfrontend/backendconnectionmanager.cpp b/mythtv/programs/mythfrontend/backendconnectionmanager.cpp
    index 5843e48..8545912 100644
    a b class Reconnect : public QRunnable  
    2525
    2626    virtual void run(void)
    2727    {
    28         if (gCoreContext->GetMasterHostPrefix().isEmpty())
     28        if (gCoreContext->SafeConnectToMasterServer())
    2929            gCoreContext->dispatch(MythEvent(QString("RECONNECT_FAILURE")));
    3030        else
    3131            gCoreContext->dispatch(MythEvent(QString("RECONNECT_SUCCESS")));