cec: moved the timed ping to a separate thread. bugzid: 654
[deb_libcec.git] / src / lib / adapter / USBCECAdapterCommunication.cpp
index 8f3bb7f0bef62dde35165454f35b4c13061ee122..ab26d84550f30f010113f12a0228cc55cb330219 100644 (file)
@@ -42,24 +42,6 @@ using namespace PLATFORM;
 
 #define CEC_ADAPTER_PING_TIMEOUT 15000
 
-void *CUSBCECAdapterProcessor::Process(void)
-{
-  cec_command command;
-  while (!IsStopped())
-  {
-    if (m_inBuffer.Pop(command))
-      m_callback->OnCommandReceived(command);
-    Sleep(5);
-  }
-
-  return NULL;
-}
-
-void CUSBCECAdapterProcessor::AddCommand(cec_command command)
-{
-  m_inBuffer.Push(command);
-}
-
 CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(CCECProcessor *processor, const char *strPort, uint16_t iBaudRate /* = 38400 */) :
     m_port(NULL),
     m_processor(processor),
@@ -69,8 +51,8 @@ CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(CCECProcessor *processo
     m_lastDestination(CECDEVICE_UNKNOWN),
     m_bNextIsEscaped(false),
     m_bGotStart(false),
-    m_messageProcessor(NULL),
-    m_bInitialised(false)
+    m_bInitialised(false),
+    m_pingThread(NULL)
 {
   for (unsigned int iPtr = 0; iPtr < 15; iPtr++)
     m_bWaitingForAck[iPtr] = false;
@@ -206,7 +188,8 @@ bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32
   }
   else if (bStartListening)
   {
-    if (CreateThread())
+    m_pingThread = new CAdapterPingThread(this, CEC_ADAPTER_PING_TIMEOUT);
+    if (CreateThread() && m_pingThread->CreateThread())
     {
       CLibCEC::AddLog(CEC_LOG_DEBUG, "communication thread started");
       return true;
@@ -230,54 +213,33 @@ bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32
 
 void CUSBCECAdapterCommunication::Close(void)
 {
+  if (m_pingThread)
+    m_pingThread->StopThread(0);
+  delete m_pingThread;
+  m_pingThread = NULL;
   StopThread(0);
 }
 
 void *CUSBCECAdapterCommunication::Process(void)
 {
-  m_messageProcessor = new CUSBCECAdapterProcessor(m_callback);
-  m_messageProcessor->CreateThread();
-
   cec_command command;
   command.Clear();
   bool bCommandReceived(false);
-  CTimeout pingTimeout(CEC_ADAPTER_PING_TIMEOUT);
   while (!IsStopped())
   {
     {
       CLockObject lock(m_mutex);
-      ReadFromDevice(50);
+      ReadFromDevice(5);
       bCommandReceived = m_callback && Read(command, 0) && m_bInitialised;
     }
 
     /* push the next command to the callback method if there is one */
     if (!IsStopped() && bCommandReceived)
-      m_messageProcessor->AddCommand(command);
-
-    /* ping the adapter every 15 seconds */
-    if (pingTimeout.TimeLeft() == 0)
-    {
-      pingTimeout.Init(CEC_ADAPTER_PING_TIMEOUT);
-      PingAdapter();
-    }
+      m_callback->OnCommandReceived(command);
 
-    if (!IsStopped())
-    {
-      Sleep(5);
-      WriteNextCommand();
-    }
+    Sleep(5);
   }
 
-  /* stop the message processor */
-  m_messageProcessor->StopThread();
-  delete m_messageProcessor;
-  m_messageProcessor = NULL;
-
-  /* notify all threads that are waiting on messages to be sent */
-  CCECAdapterMessage *msg(NULL);
-  while (m_outBuffer.Pop(msg))
-    msg->event.Broadcast();
-
   /* set the ackmask to 0 before closing the connection */
   SetAckMaskInternal(0, true);
 
@@ -334,8 +296,7 @@ cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &
 bool CUSBCECAdapterCommunication::Write(CCECAdapterMessage *data)
 {
   data->state = ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT;
-  m_outBuffer.Push(data);
-  data->event.Wait(5000);
+  SendMessageToAdapter(data);
 
   if ((data->expectControllerAck && data->state != ADAPTER_MESSAGE_STATE_SENT_ACKED) ||
       (!data->expectControllerAck && data->state != ADAPTER_MESSAGE_STATE_SENT))
@@ -411,7 +372,6 @@ bool CUSBCECAdapterCommunication::StartBootloader(void)
 
 bool CUSBCECAdapterCommunication::PingAdapter(void)
 {
-  CLockObject lock(m_mutex);
   CLibCEC::AddLog(CEC_LOG_DEBUG, "sending ping");
 
   CCECAdapterMessage params;
@@ -989,14 +949,6 @@ void CUSBCECAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg)
         CLibCEC::AddLog(CEC_LOG_DEBUG, "did not receive ack");
     }
   }
-  msg->event.Signal();
-}
-
-void CUSBCECAdapterCommunication::WriteNextCommand(void)
-{
-  CCECAdapterMessage *msg(NULL);
-  if (m_outBuffer.Pop(msg))
-    SendMessageToAdapter(msg);
 }
 
 CStdString CUSBCECAdapterCommunication::GetPortName(void)
@@ -1056,7 +1008,6 @@ cec_datapacket CUSBCECAdapterCommunication::GetSetting(cec_adapter_messagecode m
     return retVal;
   }
 
-  Sleep(250); // TODO ReadFromDevice() isn't waiting for the timeout to pass on win32
   ReadFromDevice(CEC_DEFAULT_TRANSMIT_WAIT, iResponseLength + 3 /* start + msgcode + iResponseLength + end */);
   CCECAdapterMessage input;
   if (Read(input, 0))
@@ -1076,3 +1027,18 @@ cec_datapacket CUSBCECAdapterCommunication::GetSetting(cec_adapter_messagecode m
 
   return retVal;
 }
+
+void *CAdapterPingThread::Process(void)
+{
+  while (!IsStopped())
+  {
+    if (m_timeout.TimeLeft() == 0)
+    {
+      m_timeout.Init(CEC_ADAPTER_PING_TIMEOUT);
+      m_com->PingAdapter();
+    }
+
+    Sleep(500);
+  }
+  return NULL;
+}