Ticket #5481: conditional.patch

File conditional.patch, 3.6 KB (added by tomimo@…, 16 years ago)

Fixes an occasional deadlock in Mainserver::ProcessRequestThread?

  • programs/mythbackend/mainserver.h

     
    182182
    183183    QMutex deletelock;
    184184    QMutex threadPoolLock;
     185    bool poolSignal;
    185186    QWaitCondition threadPoolCond;
    186187    vector<ProcessRequestThread *> threadPool;
    187188
  • programs/mythbackend/mainserver.cpp

     
    107107class ProcessRequestThread : public QThread
    108108{
    109109  public:
    110     ProcessRequestThread(MainServer *ms) { parent = ms; }
     110    ProcessRequestThread(MainServer *ms) {
     111        parent = ms;
     112        signalled = false;
     113        socket = NULL;
     114    }
    111115   
    112116    void setup(MythSocket *sock)
    113117    {
    114118        lock.lock();
    115119        socket = sock;
    116120        socket->UpRef();
     121        signalled = true;
    117122        waitCond.wakeOne();
    118123        lock.unlock();
    119124    }
     
    122127    {
    123128        lock.lock();
    124129        threadlives = false;
     130        signalled = true;
    125131        waitCond.wakeOne();
    126132        lock.unlock();
    127133    }
    128134
    129135    virtual void run()
    130136    {
     137        lock.lock();
    131138        threadlives = true;
     139        lock.unlock();
    132140
    133         lock.lock();
    134 
    135         // Signal back to the thread that created this one in case it is
    136         // waiting to find out that it is up and running.
    137         waitCond.wakeOne();
    138 
    139141        while (1)
    140142        {
     143            lock.lock();
     144            if (signalled == false) {
    141145            waitCond.wait(&lock);
     146            }
     147            signalled = false;
    142148
    143             if (!threadlives)
     149            if (!socket) {
     150                lock.unlock();
     151                continue;
     152            }
     153
     154            if (!threadlives) {
     155                socket->DownRef();
     156                socket = NULL;
     157                lock.unlock();
    144158                break;
     159            }
    145160
    146             if (!socket)
    147                 continue;
    148 
    149161            parent->ProcessRequest(socket);
    150162            socket->DownRef();
    151163            socket = NULL;
    152164            parent->MarkUnused(this);
    153         }
    154 
    155165        lock.unlock();
    156166    }
     167    }
    157168
    158169    QMutex lock;
    159170    QWaitCondition waitCond;
     171    bool signalled;
    160172
    161173  private:
    162174    MainServer *parent;
     
    176188    ismaster = master;
    177189    masterServer = NULL;
    178190
     191    poolSignal = false;
     192
    179193    encoderList = tvList;
    180194    AutoExpire::Update(true);
    181195
    182196    for (int i = 0; i < PRT_STARTUP_THREAD_COUNT; i++)
    183197    {
    184198        ProcessRequestThread *prt = new ProcessRequestThread(this);
    185         prt->lock.lock();
    186199        prt->start();
    187         prt->waitCond.wait(&prt->lock);
    188         prt->lock.unlock();
    189200        threadPool.push_back(prt);
    190201    }
    191202
     
    260271    if (threadPool.empty())
    261272    {
    262273        VERBOSE(VB_IMPORTANT, "Waiting for a process request thread..");
     274        if (poolSignal == false) {
    263275        threadPoolCond.wait(&threadPoolLock, PRT_TIMEOUT);
    264276    }
     277        poolSignal = false;
     278    }
    265279    if (!threadPool.empty())
    266280    {
    267281        prt = threadPool.back();
     
    271285    {
    272286        VERBOSE(VB_IMPORTANT, "Adding a new process request thread");
    273287        prt = new ProcessRequestThread(this);
    274         prt->lock.lock();
    275288        prt->start();
    276         prt->waitCond.wait(&prt->lock);
    277         prt->lock.unlock();
    278289    }
    279290    threadPoolLock.unlock();
    280291
     
    643654{
    644655    threadPoolLock.lock();
    645656    threadPool.push_back(prt);
     657    poolSignal = true;
     658    threadPoolCond.wakeOne();
    646659    threadPoolLock.unlock();
    647660}
    648661