Ticket #3433: 3433-v1.patch

File 3433-v1.patch, 8.0 KB (added by pholmes@…, 13 years ago)

Patch for FrontEnd? lockup

  • libs/libmythtv/osdtypeteletext.cpp

     
    6868
    6969      m_transparent(false),             m_revealHidden(false),
    7070      m_displaying(false),              m_osd(osd),
    71       m_header_changed(false),          m_page_changed(false)
     71      m_header_changed(false),          m_page_changed(false),
     72      m_osd_changed(false)
    7273{
    7374    m_unbiasedrect  = bias(m_displayrect, wmult, hmult);
    7475
     
    8990 */
    9091void OSDTypeTeletext::Reset(void)
    9192{
    92     QMutexLocker locker(&m_lock);
     93    OSDTypeTeletext::OSDUpdateLocker locker(this);
    9394
    9495    for (uint mag = 0; mag < 8; mag++)
    9596    {
     
    129130                                    const unsigned char* buf,
    130131                                    int vbimode, int lang, int flags)
    131132{
    132     QMutexLocker locker(&m_lock);
     133    OSDTypeTeletext::OSDUpdateLocker locker(this);
    133134
    134135    int magazine = MAGAZINE(page);
    135136    if (magazine < 1 || magazine > 8)
     
    189190        for (uint j = 8; j < 40; j++)
    190191            ttpage->data[0][j] = m_bitswap[buf[j]];
    191192    }
    192     else 
     193    else
    193194    {
    194195        memcpy(ttpage->data[0]+0, buf, 40);
    195196    }
    196    
    197     if ( !(ttpage->flags & TP_INTERRUPTED_SEQ)) 
     197
     198    if ( !(ttpage->flags & TP_INTERRUPTED_SEQ))
    198199    {
    199200        memcpy(m_header, ttpage->data[0], 40);
    200201        HeaderUpdated(ttpage->data[0],ttpage->lang);
     
    204205/** \fn OSDTypeTeletext::AddTeletextData(int,int,const unsigned char*,int)
    205206 *  \brief Adds Teletext Data from TeletextDecoder
    206207 */
    207 void OSDTypeTeletext::AddTeletextData(int magazine, int row, 
     208void OSDTypeTeletext::AddTeletextData(int magazine, int row,
    208209                                      const unsigned char* buf, int vbimode)
    209210{
    210     QMutexLocker locker(&m_lock);
     211    OSDTypeTeletext::OSDUpdateLocker locker(this);
    211212
    212213    int b1, b2, b3, err;
    213214
     
    227228            {
    228229                for (uint j = 0; j < 40; j++)
    229230                    ttpage->data[row][j] = m_bitswap[buf[j]];
    230             } 
    231             else 
     231            }
     232            else
    232233            {
    233234                memcpy(ttpage->data[row], buf, 40);
    234235            }
     
    322323        return;
    323324
    324325    m_page_changed = true;
    325     m_osd->UpdateTeletext();
     326    m_osd_changed = true;
     327// note: We cannot call UpdateTeletext from here since it will try to get the
     328//       osdlock. The problem with this is that the OSD::Display might already
     329//       be active and have called our Draw function and hence is pending the
     330//       m_lock being freed. Since the OSD::Display uses the osdlock, our call
     331//       to the UpdateTeletext would result in a semaphore deadlock.
     332//    m_osd->UpdateTeletext();
    326333}
    327334
    328335/** \fn OSDTypeTeletext::HeaderUpdated(unsigned char*,int)
    329336 *  \brief Updates the header (given in page with language lang)
    330  * 
     337 *
    331338 *  \param page Pointer to the header which should be displayed
    332339 *  \param lang Language of the header
    333340 *
     
    359366 *
    360367 *  \param page Page number
    361368 *  \param direction find page before or after the given page
    362  *  \return TeletextPage (NULL if not found) 
     369 *  \return TeletextPage (NULL if not found)
    363370 */
    364371const TeletextPage *OSDTypeTeletext::FindPageInternal(
    365372    int page, int direction) const
     
    412419 *  \param subpage Subpage number (if set to -1, find the first subpage)
    413420 *  \param direction find page before or after the given page
    414421 *         (only if Subpage is not -1)
    415  *  \return TeletextSubPage (NULL if not found) 
     422 *  \return TeletextSubPage (NULL if not found)
    416423 */
    417424const TeletextSubPage *OSDTypeTeletext::FindSubPageInternal(
    418425    int page, int subpage, int direction) const
     
    479486 */
    480487void OSDTypeTeletext::KeyPress(uint key)
    481488{
    482     QMutexLocker locker(&m_lock);
     489    OSDTypeTeletext::OSDUpdateLocker locker(this);
    483490
    484491    int newPage = m_curpage;
    485492    int newSubPage = m_cursubpage;
     
    523530            newSubPage = -1;
    524531            m_curpage_showheader = true;
    525532            break;
    526         } 
     533        }
    527534
    528535        case TTKey::kPrevPage:
    529536        {
     
    665672 */
    666673void OSDTypeTeletext::SetPage(int page, int subpage)
    667674{
    668     QMutexLocker locker(&m_lock);
     675    OSDTypeTeletext::OSDUpdateLocker locker(this);
    669676
    670677    if (page < 0x100 || page > 0x899)
    671678        return;
     
    796803}
    797804
    798805/** \fn OSDTypeTeletext::DrawCharacter(OSDSurface*,int,int,QChar,int) const
    799  *  \brief Draws a character at posistion x, y 
     806 *  \brief Draws a character at posistion x, y
    800807 *
    801808 *  \param x X position (40 cols)
    802809 *  \param y Y position (25 rows)
     
    11091116
    11101117void OSDTypeTeletext::Reinit(float wmult, float hmult)
    11111118{
    1112     QMutexLocker locker(&m_lock);
     1119    OSDTypeTeletext::OSDUpdateLocker locker(this);
    11131120
    11141121    m_displayrect = bias(m_unbiasedrect, wmult, hmult);
    11151122    m_tt_colspace = m_displayrect.width()  / kTeletextColumns;
     
    12321239    }
    12331240}
    12341241
     1242/*
     1243 ****************************************************************************
     1244 *
     1245 * OSDUpdateLocker - helper class to the OSDTypeTeletext.
     1246 *                   This class is used to lock the m_lock semaphore when
     1247 *                   there is a chance that the locked code will result in the
     1248 *                   OSD::UpdateTeletext() function being called. It's purpose
     1249 *                   is to lock the semaphore and once the locked code has
     1250 *                   finished to check for a request to call OSD::UpdateTeletext().
     1251 *                   If required, the m_lock is released and the required call made
     1252 *
     1253 *                   This is to overcome the possible semaphore deadlock as follows:
     1254 *
     1255 *      -Teletext data arrives -> locks m_lock
     1256 *      -While the teletext data is being processed the XMV request an OSD update display
     1257 *      -The OSD update display will lock the osdlock
     1258 *      -The OSD update can results in the Teletext:Draw function being call and hence the
     1259 *       OSD update is now waiting on m_lock being released to continue it's drawing process
     1260 *      -If the processing of the teletext data result in the function OSD::UpdateTeletext
     1261 *       being called, this function will try to get the osdlock.
     1262 *      -This results in the classic semaphore deadlock and hence all OSD update cease.
     1263 *
     1264 *****************************************************************************
     1265 */
     1266OSDTypeTeletext::OSDUpdateLocker::OSDUpdateLocker(OSDTypeTeletext *parent)
     1267                                 :parent(parent)
     1268{
     1269    parent->m_lock.lock();
     1270}
     1271
     1272OSDTypeTeletext::OSDUpdateLocker::~OSDUpdateLocker(void)
     1273{
     1274    if (parent->m_osd_changed == true)                                      // see if the osd has to be requested to redraw
     1275    {
     1276        parent->m_osd_changed = false;                                      // clear the flag
     1277        parent->m_lock.unlock();                                                    // and remove the m_lock
     1278        parent->m_osd->UpdateTeletext();                                            // now it is safe to do the OSD update
     1279        return;
     1280    }
     1281    parent->m_lock.unlock();                                                // normal exit. Will result in the m_lock being released.
     1282}
     1283
  • libs/libmythtv/osdtypeteletext.h

     
    170170    const TeletextPage    *FindPageInternal(int,int) const;
    171171
    172172  private:
     173    class OSDUpdateLocker
     174    {
     175        public:
     176            OSDUpdateLocker(OSDTypeTeletext *parent);
     177            ~OSDUpdateLocker(void);
     178        private:
     179            OSDTypeTeletext *parent;
     180    };
     181
    173182    QMutex       m_lock;
     183
    174184    QRect        m_displayrect;
    175185    QRect        m_unbiasedrect;
    176186
     
    209219    uint8_t      m_header[40];
    210220    mutable bool m_header_changed;
    211221    mutable bool m_page_changed;
     222    mutable bool m_osd_changed;
    212223
    213224    TeletextMagazine m_magazines[8];
    214225    unsigned char    m_bitswap[256];