Ticket #5591: ThreadedFileWriter-deadlock.patch

File ThreadedFileWriter-deadlock.patch, 3.1 KB (added by jppoet@…, 16 years ago)

Fix deadlock in ThreadedFileWriter::Write()

  • libs/libmythtv/ThreadedFileWriter.cpp

     
    210210    if (count == 0)
    211211        return 0;
    212212
    213     bool first = true;
     213    uint bytes, remaining, iobound_cnt = 0;
     214    bool first;
    214215
     216    if (count > tfw_buf_size)
     217    {
     218        VERBOSE(VB_IMPORTANT, LOC +
     219                QString("WARNING: count(%1), tfw_buf_size(%2)")
     220                .arg(count).arg(tfw_buf_size));
     221    }
     222
    215223    // Qt4 requires a QMutex as a parameter...
    216224    // not sure if this is the best solution.  Mutex Must be locked before wait.
    217225    QMutex mutex;
    218226    mutex.lock();
    219227
    220     while (count > BufFree())
     228    for (remaining = count; remaining; )
    221229    {
    222         if (first)
     230        first = true;
     231
     232        bytes = BufFree() < remaining ? BufFree() : remaining;
     233
     234        while (BufFree() == 0)
    223235        {
    224             VERBOSE(VB_IMPORTANT, LOC_ERR + "Write() -- IOBOUND begin " +
    225                     QString("cnt(%1) free(%2)").arg(count).arg(BufFree()));
    226             first = false;
     236            if (first)
     237            {
     238                ++iobound_cnt;
     239                VERBOSE(VB_IMPORTANT, LOC_ERR + "Write() -- IOBOUND begin " +
     240                        QString("bytes(%1) free(%2) size(%3) cnt(%4)")
     241                        .arg(bytes).arg(BufFree())
     242                        .arg(tfw_buf_size).arg(iobound_cnt));
     243                first = false;
     244            }
     245           
     246            bufferWroteData.wait(&mutex, 10000);
    227247        }
     248        if (!first)
     249            VERBOSE(VB_IMPORTANT, LOC_ERR + "Write() -- IOBOUND end");
     250       
     251        if (no_writes)
     252            return 0;
     253       
     254        if ((wpos + bytes) > tfw_buf_size)
     255        {
     256            int first_chunk_size = tfw_buf_size - wpos;
     257            int second_chunk_size = bytes - first_chunk_size;
     258            memcpy(buf + wpos, data, first_chunk_size );
     259            memcpy(buf, (char *)data + first_chunk_size, second_chunk_size );
     260        }
     261        else
     262        {
     263            memcpy(buf + wpos, data, bytes);
     264        }
    228265
    229         bufferWroteData.wait(&mutex, 100);
    230     }
    231     if (!first)
    232         VERBOSE(VB_IMPORTANT, LOC_ERR + "Write() -- IOBOUND end");
     266        buflock.lock();
     267        wpos = (wpos + bytes) % tfw_buf_size;
     268        buflock.unlock();
    233269
    234     if (no_writes)
    235         return 0;
     270        bufferHasData.wakeAll();
    236271
    237     if ((wpos + count) > tfw_buf_size)
    238     {
    239         int first_chunk_size = tfw_buf_size - wpos;
    240         int second_chunk_size = count - first_chunk_size;
    241         memcpy(buf + wpos, data, first_chunk_size );
    242         memcpy(buf, (char *)data + first_chunk_size, second_chunk_size );
     272        remaining -= bytes;
     273        if (remaining)
     274            bufferWroteData.wait(&mutex, 10000);
    243275    }
    244     else
    245     {
    246         memcpy(buf + wpos, data, count);
    247     }
    248276
    249     buflock.lock();
    250     wpos = (wpos + count) % tfw_buf_size;
    251     buflock.unlock();
    252 
    253     bufferHasData.wakeAll();
    254 
    255277    return count;
    256278}
    257279
     
    464486    QMutexLocker locker(&buflock);
    465487    return ((wpos >= rpos) ? (rpos + tfw_buf_size) : rpos) - wpos - 1;
    466488}
    467