Ticket #6305: condwait_usage.patch

File condwait_usage.patch, 4.4 KB (added by tomimo@…, 15 years ago)

A simple example of the fix I used for the described problem (full fix being prepared)

  • libs/libmythtv/recorderbase.cpp

     
    3131      audiodevice("/dev/dsp"), videodevice("/dev/video"), vbidevice("/dev/vbi"),
    3232      vbimode(0), ntsc(true), ntsc_framerate(true), video_frame_rate(29.97),
    3333      m_videoAspect(0), m_videoHeight(0), m_videoWidth(0), curRecording(NULL),
    34       request_pause(false), paused(false), nextRingBuffer(NULL), nextRecording(NULL),
    35       positionMapType(MARK_GOP_BYFRAME), positionMapLock()
     34      request_pause(false), paused(false),
     35      nextRingBuffer(NULL), nextRecording(NULL),
     36      positionMapType(MARK_GOP_BYFRAME), positionMapLock(),
     37      pauseWaitSignal(false), unpauseWaitSignal(false)
    3638{
    3739    QMutexLocker locker(&avcodeclock);
    3840    avcodec_init(); // init CRC's
     
    167169    MythTimer t;
    168170    t.start();
    169171
    170     // Qt4 requires a QMutex as a parameter...
    171     // not sure if this is the best solution.  Mutex Must be locked before wait.
    172     QMutex mutex;
    173     mutex.lock();
    174 
    175172    while (true)
    176173    {
    177174        int wait = timeout - t.elapsed();
     
    181178        else if (IsPaused())
    182179            return true;
    183180
    184         pauseWait.wait(&mutex, wait);
     181        pauseWaitMutex.lock();
     182        if (pauseWaitSignal == false)
     183            pauseWait.wait(&pauseWaitMutex, wait);
     184        pauseWaitSignal = false;
     185        pauseWaitMutex.unlock();
    185186    }
    186187}
    187188
     
    198199        if (!paused)
    199200        {
    200201            paused = true;
    201             pauseWait.wakeAll();
     202            triggerPauseWait();
     203
    202204            if (tvrec)
    203205                tvrec->RecorderPaused();
    204206        }
    205207
    206         // Qt4 requires a QMutex as a parameter...
    207         // not sure if this is the best solution.  Mutex Must be locked before wait.
    208         QMutex mutex;
    209         mutex.lock();
    210 
    211         unpauseWait.wait(&mutex, timeout);
     208        unpauseWaitMutex.lock();
     209        if (unpauseWaitSignal == false)
     210           unpauseWait.wait(&unpauseWaitMutex, timeout);
     211        unpauseWaitSignal = false;
     212        unpauseWaitMutex.unlock();
    212213    }
    213214    if (!request_pause)
    214215        paused = false;
    215216    return paused;
    216217}
    217218
     219void RecorderBase::triggerPauseWait(void)
     220{
     221    pauseWaitMutex.lock();
     222    pauseWaitSignal = true;
     223    pauseWait.wakeAll();
     224    pauseWaitMutex.unlock();
     225}
     226
     227bool RecorderBase::catchPauseWait(unsigned long timeout)
     228{
     229    bool ret = true;
     230
     231    pauseWaitMutex.lock();
     232    if (pauseWaitSignal == false)
     233        ret = pauseWait.wait(&pauseWaitMutex, timeout);
     234    pauseWaitSignal = false;
     235    pauseWaitMutex.unlock();
     236    return ret;
     237}
     238
     239void RecorderBase::triggerUnPauseWait(void)
     240{
     241    unpauseWaitMutex.lock();
     242    unpauseWaitSignal = true;
     243    unpauseWait.wakeAll();
     244    unpauseWaitMutex.unlock();
     245}
     246
     247bool RecorderBase::catchUnPauseWait(unsigned long timeout)
     248{
     249    bool ret = true;
     250
     251    unpauseWaitMutex.lock();
     252    if (unpauseWaitSignal == false)
     253        ret = unpauseWait.wait(&unpauseWaitMutex, timeout);
     254    unpauseWaitSignal = false;
     255    unpauseWaitMutex.unlock();
     256    return ret;
     257}
     258
    218259void RecorderBase::CheckForRingBufferSwitch(void)
    219260{
    220261    nextRingBufferLock.lock();
  • libs/libmythtv/recorderbase.h

     
    252252     */
    253253    void ResolutionChange(uint width, uint height, long long frame);
    254254
     255    void triggerPauseWait(void);
     256    bool catchPauseWait(unsigned long timeout = ULONG_MAX);
     257
     258    void triggerUnPauseWait(void);
     259    bool catchUnPauseWait(unsigned long timeout = ULONG_MAX);
     260
     261
    255262    TVRec         *tvrec;
    256263    RingBuffer    *ringBuffer;
    257264    bool           weMadeBuffer;
     
    276283    // For handling pausing
    277284    bool           request_pause;
    278285    bool           paused;
    279     QWaitCondition pauseWait;
    280     QWaitCondition unpauseWait;
    281286
    282287    // For RingBuffer switching
    283288    QMutex         nextRingBufferLock;
     
    290295    PosMap         positionMap;
    291296    PosMap         positionMapDelta;
    292297
     298
     299  private:
     300
     301    QWaitCondition pauseWait;
     302    QMutex         pauseWaitMutex;
     303    bool           pauseWaitSignal;
     304
     305    QWaitCondition unpauseWait;
     306    QMutex         unpauseWaitMutex;
     307    bool           unpauseWaitSignal;
    293308};
    294309
    295310#endif