Index: libs/libmythtv/osdtypeteletext.cpp
===================================================================
--- libs/libmythtv/osdtypeteletext.cpp	(revision 13437)
+++ libs/libmythtv/osdtypeteletext.cpp	(working copy)
@@ -68,7 +68,8 @@
 
       m_transparent(false),             m_revealHidden(false),
       m_displaying(false),              m_osd(osd),
-      m_header_changed(false),          m_page_changed(false)
+      m_header_changed(false),          m_page_changed(false),
+      m_osd_changed(false)
 {
     m_unbiasedrect  = bias(m_displayrect, wmult, hmult);
 
@@ -89,7 +90,7 @@
  */
 void OSDTypeTeletext::Reset(void)
 {
-    QMutexLocker locker(&m_lock);
+    OSDTypeTeletext::OSDUpdateLocker locker(this);
 
     for (uint mag = 0; mag < 8; mag++)
     {
@@ -129,7 +130,7 @@
                                     const unsigned char* buf,
                                     int vbimode, int lang, int flags)
 {
-    QMutexLocker locker(&m_lock);
+    OSDTypeTeletext::OSDUpdateLocker locker(this);
 
     int magazine = MAGAZINE(page);
     if (magazine < 1 || magazine > 8)
@@ -189,12 +190,12 @@
         for (uint j = 8; j < 40; j++)
             ttpage->data[0][j] = m_bitswap[buf[j]];
     }
-    else 
+    else
     {
         memcpy(ttpage->data[0]+0, buf, 40);
     }
-    
-    if ( !(ttpage->flags & TP_INTERRUPTED_SEQ)) 
+
+    if ( !(ttpage->flags & TP_INTERRUPTED_SEQ))
     {
         memcpy(m_header, ttpage->data[0], 40);
         HeaderUpdated(ttpage->data[0],ttpage->lang);
@@ -204,10 +205,10 @@
 /** \fn OSDTypeTeletext::AddTeletextData(int,int,const unsigned char*,int)
  *  \brief Adds Teletext Data from TeletextDecoder
  */
-void OSDTypeTeletext::AddTeletextData(int magazine, int row, 
+void OSDTypeTeletext::AddTeletextData(int magazine, int row,
                                       const unsigned char* buf, int vbimode)
 {
-    QMutexLocker locker(&m_lock);
+    OSDTypeTeletext::OSDUpdateLocker locker(this);
 
     int b1, b2, b3, err;
 
@@ -227,8 +228,8 @@
             {
                 for (uint j = 0; j < 40; j++)
                     ttpage->data[row][j] = m_bitswap[buf[j]];
-            } 
-            else 
+            }
+            else
             {
                 memcpy(ttpage->data[row], buf, 40);
             }
@@ -322,12 +323,18 @@
         return;
 
     m_page_changed = true;
-    m_osd->UpdateTeletext();
+    m_osd_changed = true;
+// note: We cannot call UpdateTeletext from here since it will try to get the
+//       osdlock. The problem with this is that the OSD::Display might already
+//       be active and have called our Draw function and hence is pending the
+//       m_lock being freed. Since the OSD::Display uses the osdlock, our call
+//       to the UpdateTeletext would result in a semaphore deadlock.
+//    m_osd->UpdateTeletext();
 }
 
 /** \fn OSDTypeTeletext::HeaderUpdated(unsigned char*,int)
  *  \brief Updates the header (given in page with language lang)
- * 
+ *
  *  \param page Pointer to the header which should be displayed
  *  \param lang Language of the header
  *
@@ -359,7 +366,7 @@
  *
  *  \param page Page number
  *  \param direction find page before or after the given page
- *  \return TeletextPage (NULL if not found) 
+ *  \return TeletextPage (NULL if not found)
  */
 const TeletextPage *OSDTypeTeletext::FindPageInternal(
     int page, int direction) const
@@ -412,7 +419,7 @@
  *  \param subpage Subpage number (if set to -1, find the first subpage)
  *  \param direction find page before or after the given page
  *         (only if Subpage is not -1)
- *  \return TeletextSubPage (NULL if not found) 
+ *  \return TeletextSubPage (NULL if not found)
  */
 const TeletextSubPage *OSDTypeTeletext::FindSubPageInternal(
     int page, int subpage, int direction) const
@@ -479,7 +486,7 @@
  */
 void OSDTypeTeletext::KeyPress(uint key)
 {
-    QMutexLocker locker(&m_lock);
+    OSDTypeTeletext::OSDUpdateLocker locker(this);
 
     int newPage = m_curpage;
     int newSubPage = m_cursubpage;
@@ -523,7 +530,7 @@
             newSubPage = -1;
             m_curpage_showheader = true;
             break;
-        } 
+        }
 
         case TTKey::kPrevPage:
         {
@@ -665,7 +672,7 @@
  */
 void OSDTypeTeletext::SetPage(int page, int subpage)
 {
-    QMutexLocker locker(&m_lock);
+    OSDTypeTeletext::OSDUpdateLocker locker(this);
 
     if (page < 0x100 || page > 0x899)
         return;
@@ -796,7 +803,7 @@
 }
 
 /** \fn OSDTypeTeletext::DrawCharacter(OSDSurface*,int,int,QChar,int) const
- *  \brief Draws a character at posistion x, y 
+ *  \brief Draws a character at posistion x, y
  *
  *  \param x X position (40 cols)
  *  \param y Y position (25 rows)
@@ -1109,7 +1116,7 @@
 
 void OSDTypeTeletext::Reinit(float wmult, float hmult)
 {
-    QMutexLocker locker(&m_lock);
+    OSDTypeTeletext::OSDUpdateLocker locker(this);
 
     m_displayrect = bias(m_unbiasedrect, wmult, hmult);
     m_tt_colspace = m_displayrect.width()  / kTeletextColumns;
@@ -1232,3 +1239,45 @@
     }
 }
 
+/*
+ ****************************************************************************
+ *
+ * OSDUpdateLocker - helper class to the OSDTypeTeletext.
+ *                   This class is used to lock the m_lock semaphore when
+ *                   there is a chance that the locked code will result in the
+ *                   OSD::UpdateTeletext() function being called. It's purpose
+ *                   is to lock the semaphore and once the locked code has
+ *                   finished to check for a request to call OSD::UpdateTeletext().
+ *                   If required, the m_lock is released and the required call made
+ *
+ *                   This is to overcome the possible semaphore deadlock as follows:
+ *
+ *      -Teletext data arrives -> locks m_lock
+ *      -While the teletext data is being processed the XMV request an OSD update display
+ *      -The OSD update display will lock the osdlock
+ *      -The OSD update can results in the Teletext:Draw function being call and hence the
+ *       OSD update is now waiting on m_lock being released to continue it's drawing process
+ *      -If the processing of the teletext data result in the function OSD::UpdateTeletext
+ *       being called, this function will try to get the osdlock.
+ *      -This results in the classic semaphore deadlock and hence all OSD update cease.
+ *
+ *****************************************************************************
+ */
+OSDTypeTeletext::OSDUpdateLocker::OSDUpdateLocker(OSDTypeTeletext *parent)
+                                 :parent(parent)
+{
+    parent->m_lock.lock();
+}
+
+OSDTypeTeletext::OSDUpdateLocker::~OSDUpdateLocker(void)
+{
+    if (parent->m_osd_changed == true)                                      // see if the osd has to be requested to redraw
+    {
+        parent->m_osd_changed = false;                                      // clear the flag
+        parent->m_lock.unlock();                                                    // and remove the m_lock
+        parent->m_osd->UpdateTeletext();                                            // now it is safe to do the OSD update
+        return;
+    }
+    parent->m_lock.unlock();                                                // normal exit. Will result in the m_lock being released.
+}
+
Index: libs/libmythtv/osdtypeteletext.h
===================================================================
--- libs/libmythtv/osdtypeteletext.h	(revision 13437)
+++ libs/libmythtv/osdtypeteletext.h	(working copy)
@@ -170,7 +170,17 @@
     const TeletextPage    *FindPageInternal(int,int) const;
 
   private:
+    class OSDUpdateLocker
+    {
+        public:
+            OSDUpdateLocker(OSDTypeTeletext *parent);
+            ~OSDUpdateLocker(void);
+        private:
+            OSDTypeTeletext *parent;
+    };
+
     QMutex       m_lock;
+
     QRect        m_displayrect;
     QRect        m_unbiasedrect;
 
@@ -209,6 +219,7 @@
     uint8_t      m_header[40];
     mutable bool m_header_changed;
     mutable bool m_page_changed;
+    mutable bool m_osd_changed;
 
     TeletextMagazine m_magazines[8];
     unsigned char    m_bitswap[256];
