cec: don't hold a lock when sending an active source message. fixes potential deadlock
authorLars Op den Kamp <lars@opdenkamp.eu>
Wed, 11 Jan 2012 00:27:49 +0000 (01:27 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Wed, 11 Jan 2012 00:27:49 +0000 (01:27 +0100)
src/lib/CECProcessor.cpp

index 68e8fbf8ff9e2e4777054401f2b44d4aa53b496d..02c1e96498b1295af7025c828d9f3c4812bf28ef 100644 (file)
@@ -527,12 +527,16 @@ bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort,
     else if (iPhysicalAddress % 0x10 == 0)
       iPhysicalAddress += iPort;
 
-    SetPhysicalAddress(iPhysicalAddress);
     bReturn = true;
   }
 
   if (!bReturn)
     m_controller->AddLog(CEC_LOG_ERROR, "failed to set the physical address");
+  else
+  {
+    lock.Leave();
+    SetPhysicalAddress(iPhysicalAddress);
+  }
 
   return bReturn;
 }
@@ -601,23 +605,33 @@ bool CCECProcessor::SetMenuState(cec_menu_state state, bool bSendUpdate /* = tru
 
 bool CCECProcessor::SetPhysicalAddress(uint16_t iPhysicalAddress, bool bSendUpdate /* = true */)
 {
-  bool bWasActiveSource(false);
-  CLockObject lock(&m_mutex);
-  if (!m_logicalAddresses.IsEmpty())
+  bool bSendActiveView(false);
+  bool bReturn(false);
+
   {
-    for (uint8_t iPtr = 0; iPtr < 15; iPtr++)
-      if (m_logicalAddresses[iPtr])
-      {
-        bWasActiveSource |= m_busDevices[iPtr]->IsActiveSource();
-        m_busDevices[iPtr]->SetInactiveSource();
-        m_busDevices[iPtr]->SetPhysicalAddress(iPhysicalAddress);
-        if (bSendUpdate)
-          m_busDevices[iPtr]->TransmitPhysicalAddress();
-      }
+    CLockObject lock(&m_mutex);
+    if (!m_logicalAddresses.IsEmpty())
+    {
+      bool bWasActiveSource(false);
+      for (uint8_t iPtr = 0; iPtr < 15; iPtr++)
+        if (m_logicalAddresses[iPtr])
+        {
+          bWasActiveSource |= m_busDevices[iPtr]->IsActiveSource();
+          m_busDevices[iPtr]->SetInactiveSource();
+          m_busDevices[iPtr]->SetPhysicalAddress(iPhysicalAddress);
+          if (bSendUpdate)
+            m_busDevices[iPtr]->TransmitPhysicalAddress();
+        }
 
-    return bWasActiveSource && bSendUpdate ? SetActiveView() : true;
+      bSendActiveView = bWasActiveSource && bSendUpdate;
+      bReturn = true;
+    }
   }
-  return false;
+
+  if (bSendActiveView)
+    SetActiveView();
+
+  return bReturn;
 }
 
 bool CCECProcessor::SwitchMonitoring(bool bEnable)