1 #pragma once 2 /* 3 * This file is part of the libCEC(R) library. 4 * 5 * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited. All rights reserved. 6 * libCEC(R) is an original work, containing original code. 7 * 8 * libCEC(R) is a trademark of Pulse-Eight Limited. 9 * 10 * This program is dual-licensed; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 23 * 02110-1301 USA 24 * 25 * 26 * Alternatively, you can license this library under a commercial license, 27 * please contact Pulse-Eight Licensing for more information. 28 * 29 * For more information contact: 30 * Pulse-Eight Licensing <license@pulse-eight.com> 31 * http://www.pulse-eight.com/ 32 * http://www.pulse-eight.net/ 33 */ 34 35 #include "env.h" 36 #include "p8-platform/threads/mutex.h" 37 #include "p8-platform/util/buffer.h" 38 39 namespace CEC 40 { 41 // a buffer that priotises the input from the TV. 42 // if we need more than this, we'll have to change it into a priority_queue 43 class CCECInputBuffer 44 { 45 public: CCECInputBuffer(void)46 CCECInputBuffer(void) : m_bHasData(false) {} ~CCECInputBuffer(void)47 virtual ~CCECInputBuffer(void) 48 { 49 Broadcast(); 50 } 51 Broadcast(void)52 void Broadcast(void) 53 { 54 P8PLATFORM::CLockObject lock(m_mutex); 55 m_bHasData = true; 56 m_condition.Broadcast(); 57 } 58 Push(const cec_command & command)59 bool Push(const cec_command &command) 60 { 61 bool bReturn(false); 62 P8PLATFORM::CLockObject lock(m_mutex); 63 if (command.initiator == CECDEVICE_TV) 64 bReturn = m_tvInBuffer.Push(command); 65 else 66 bReturn = m_inBuffer.Push(command); 67 68 m_bHasData |= bReturn; 69 if (m_bHasData) 70 m_condition.Signal(); 71 72 return bReturn; 73 } 74 Pop(cec_command & command,uint16_t iTimeout)75 bool Pop(cec_command &command, uint16_t iTimeout) 76 { 77 bool bReturn(false); 78 P8PLATFORM::CLockObject lock(m_mutex); 79 if (m_tvInBuffer.IsEmpty() && m_inBuffer.IsEmpty() && 80 !m_condition.Wait(m_mutex, m_bHasData, iTimeout)) 81 return bReturn; 82 83 if (m_tvInBuffer.Pop(command)) 84 bReturn = true; 85 else if (m_inBuffer.Pop(command)) 86 bReturn = true; 87 88 m_bHasData = !m_tvInBuffer.IsEmpty() || !m_inBuffer.IsEmpty(); 89 return bReturn; 90 } 91 92 private: 93 P8PLATFORM::CMutex m_mutex; 94 P8PLATFORM::CCondition<volatile bool> m_condition; 95 volatile bool m_bHasData; 96 P8PLATFORM::SyncedBuffer<cec_command> m_tvInBuffer; 97 P8PLATFORM::SyncedBuffer<cec_command> m_inBuffer; 98 }; 99 }; 100