From: Lars Op den Kamp Date: Thu, 16 Feb 2012 09:44:27 +0000 (+0100) Subject: cec: ensure that the ackmask is always set to 0 when closing the connection and that... X-Git-Tag: upstream/2.2.0~1^2~35^2~26 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=f9e01dac894ab26e63aaa38a8df5cba237195b76;p=deb_libcec.git cec: ensure that the ackmask is always set to 0 when closing the connection and that the call doesn't block the Close() call --- diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 98be0c4..f9d2134 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -136,6 +136,8 @@ CCECProcessor::~CCECProcessor(void) void CCECProcessor::Close(void) { + StopThread(false); + SetInitialised(false); StopThread(); CLockObject lock(m_mutex); @@ -867,8 +869,11 @@ bool CCECProcessor::Transmit(const cec_command &data) CLockObject lock(m_mutex); LogOutput(data); m_iLastTransmission = GetTimeMs(); - if (!m_communication) + if (!m_communication || !IsInitialised()) + { + CLibCEC::AddLog(CEC_LOG_ERROR, "cannot transmit command: connection closed"); return false; + } uint8_t iMaxTries = m_busDevices[data.initiator]->GetHandler()->GetTransmitRetries() + 1; retVal = m_communication->Write(data, iMaxTries, m_iLineTimeout, m_iRetryLineTimeout); } diff --git a/src/lib/adapter/USBCECAdapterCommunication.cpp b/src/lib/adapter/USBCECAdapterCommunication.cpp index 96571cc..2d85972 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.cpp +++ b/src/lib/adapter/USBCECAdapterCommunication.cpp @@ -173,12 +173,6 @@ bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32 void CUSBCECAdapterCommunication::Close(void) { - { - CLockObject lock(m_mutex); - m_bHasData = true; - m_rcvCondition.Broadcast(); - } - SetAckMask(0); StopThread(); } @@ -205,10 +199,14 @@ void *CUSBCECAdapterCommunication::Process(void) } } + /* notify all threads that are waiting on messages to be sent */ CCECAdapterMessage *msg(NULL); - if (m_outBuffer.Pop(msg)) + while (m_outBuffer.Pop(msg)) msg->event.Broadcast(); + /* set the ackmask to 0 before closing the connection */ + SetAckMaskInternal(0, true); + if (m_port) { delete m_port; @@ -253,7 +251,7 @@ bool CUSBCECAdapterCommunication::Write(CCECAdapterMessage *data) { data->state = ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT; m_outBuffer.Push(data); - data->event.Wait(); + data->event.Wait(5000); if ((data->expectControllerAck && data->state != ADAPTER_MESSAGE_STATE_SENT_ACKED) || (!data->expectControllerAck && data->state != ADAPTER_MESSAGE_STATE_SENT)) @@ -485,6 +483,11 @@ bool CUSBCECAdapterCommunication::SetLineTimeout(uint8_t iTimeout) } bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask) +{ + return SetAckMaskInternal(iMask, false); +} + +bool CUSBCECAdapterCommunication::SetAckMaskInternal(uint16_t iMask, bool bWriteDirectly /* = false */) { bool bReturn(false); CLibCEC::AddLog(CEC_LOG_DEBUG, "setting ackmask to %2x", iMask); @@ -498,7 +501,9 @@ bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask) output->PushBack(MSGEND); output->isTransmission = false; - if ((bReturn = Write(output)) == false) + if (bWriteDirectly) + SendMessageToAdapter(output); + else if ((bReturn = Write(output)) == false) CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the ackmask"); delete output; @@ -677,6 +682,13 @@ bool CUSBCECAdapterCommunication::ReadFromDevice(uint32_t iTimeout, size_t iSize void CUSBCECAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg) { CLockObject adapterLock(m_mutex); + if (!m_port->IsOpen()) + { + CLibCEC::AddLog(CEC_LOG_ERROR, "error writing to serial port: the connection is closed"); + msg->state = ADAPTER_MESSAGE_STATE_ERROR; + return; + } + if (msg->tries == 1) SetLineTimeout(msg->lineTimeout); else diff --git a/src/lib/adapter/USBCECAdapterCommunication.h b/src/lib/adapter/USBCECAdapterCommunication.h index fc9e16c..22c7db9 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.h +++ b/src/lib/adapter/USBCECAdapterCommunication.h @@ -72,6 +72,8 @@ namespace CEC void *Process(void); private: + bool SetAckMaskInternal(uint16_t iMask, bool bWriteDirectly = false); + bool CheckAdapter(uint32_t iTimeoutMs = 10000); bool Write(CCECAdapterMessage *data); bool Read(CCECAdapterMessage &msg, uint32_t iTimeout = 1000);