From f99bc83187bb0daa81bc58a4559ff9832a8dad9f Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Thu, 29 Sep 2011 23:27:28 +0200 Subject: [PATCH] cec: add a Close() method to the interface --- include/CECExportsC.h | 12 +++++----- include/CECExportsCpp.h | 5 ++++ src/lib/CECParser.cpp | 51 +++++++++++++++++++++++++++++++++++----- src/lib/CECParser.h | 2 ++ src/lib/CECParserC.cpp | 18 ++++++++------ src/lib/util/threads.cpp | 2 ++ 6 files changed, 71 insertions(+), 19 deletions(-) diff --git a/include/CECExportsC.h b/include/CECExportsC.h index 5d278f4..8d91fe2 100644 --- a/include/CECExportsC.h +++ b/include/CECExportsC.h @@ -52,12 +52,6 @@ extern DECLSPEC bool cec_init(const char *strDeviceName, CEC::cec_logical_addres extern DECLSPEC bool cec_init(const char *strDeviceName, cec_logical_address iLogicalAddress = CECDEVICE_PLAYBACKDEVICE1, int iPhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS); #endif -/*! - * @brief Close the CEC adapter connection. - * @return True when the device was closed, false otherwise. - */ -extern DECLSPEC bool cec_close(void); - /*! * @brief Open a connection to the CEC adapter. * @param strPort The path to the port. @@ -66,6 +60,12 @@ extern DECLSPEC bool cec_close(void); */ extern DECLSPEC bool cec_open(const char *strPort, int iTimeout); +/*! + * @brief Close the connection to the CEC adapter. + * @param iTimeout Timeout in ms + */ +extern DECLSPEC bool cec_close(int iTimeout); + /*! * @brief Ping the CEC adapter. * @return True when the ping was succesful, false otherwise. diff --git a/include/CECExportsCpp.h b/include/CECExportsCpp.h index fd4ea9f..ac00190 100644 --- a/include/CECExportsCpp.h +++ b/include/CECExportsCpp.h @@ -41,6 +41,11 @@ namespace CEC */ virtual bool Open(const char *strPort, int iTimeoutMs = 10000) = 0; + /*! + * @see cec_close + */ + virtual bool Close(int iTimeoutMs = 2000) = 0; + /*! * @see cec_find_devices */ diff --git a/src/lib/CECParser.cpp b/src/lib/CECParser.cpp index 547d626..dad7a0d 100644 --- a/src/lib/CECParser.cpp +++ b/src/lib/CECParser.cpp @@ -67,8 +67,7 @@ CCECParser::CCECParser(const char *strDeviceName, cec_logical_address iLogicalAd CCECParser::~CCECParser(void) { - m_bRunning = false; - pthread_join(m_thread, NULL); + Close(0); m_serialport->Close(); delete m_serialport; } @@ -112,6 +111,24 @@ bool CCECParser::Open(const char *strPort, int iTimeoutMs /* = 10000 */) return bReturn; } +bool CCECParser::Close(int iTimeoutMs /* = 2000 */) +{ + m_bRunning = false; + bool bExit(false); + if (iTimeoutMs > 0) + { + bExit = m_exitCondition.Wait(&m_mutex, iTimeoutMs); + m_mutex.Unlock(); + } + else + { + pthread_join(m_thread, NULL); + bExit = true; + } + + return bExit; +} + void *CCECParser::ThreadHandler(CCECParser *parser) { if (parser) @@ -145,11 +162,15 @@ bool CCECParser::Process(void) AddLog(CEC_LOG_DEBUG, "reader thread terminated"); m_bRunning = false; + m_exitCondition.Signal(); return true; } bool CCECParser::Ping(void) { + if (!m_bRunning) + return false; + AddLog(CEC_LOG_DEBUG, "sending ping"); cec_frame output; output.push_back(MSGSTART); @@ -170,6 +191,9 @@ bool CCECParser::Ping(void) bool CCECParser::StartBootloader(void) { + if (!m_bRunning) + return false; + AddLog(CEC_LOG_DEBUG, "starting the bootloader"); cec_frame output; output.push_back(MSGSTART); @@ -193,6 +217,9 @@ uint8_t CCECParser::GetSourceDestination(cec_logical_address destination /* = CE bool CCECParser::PowerOffDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */) { + if (!m_bRunning) + return false; + CStdString strLog; strLog.Format("powering off devices with logical address %d", (int8_t)address); AddLog(CEC_LOG_DEBUG, strLog.c_str()); @@ -204,6 +231,9 @@ bool CCECParser::PowerOffDevices(cec_logical_address address /* = CECDEVICE_BROA bool CCECParser::PowerOnDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */) { + if (!m_bRunning) + return false; + CStdString strLog; strLog.Format("powering on devices with logical address %d", (int8_t)address); AddLog(CEC_LOG_DEBUG, strLog.c_str()); @@ -215,6 +245,9 @@ bool CCECParser::PowerOnDevices(cec_logical_address address /* = CECDEVICE_BROAD bool CCECParser::StandbyDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */) { + if (!m_bRunning) + return false; + CStdString strLog; strLog.Format("putting all devices with logical address %d in standby mode", (int8_t)address); AddLog(CEC_LOG_DEBUG, strLog.c_str()); @@ -226,6 +259,9 @@ bool CCECParser::StandbyDevices(cec_logical_address address /* = CECDEVICE_BROAD bool CCECParser::SetActiveView(void) { + if (!m_bRunning) + return false; + AddLog(CEC_LOG_DEBUG, "setting active view"); cec_frame frame; frame.push_back(GetSourceDestination(CECDEVICE_BROADCAST)); @@ -237,6 +273,9 @@ bool CCECParser::SetActiveView(void) bool CCECParser::SetInactiveView(void) { + if (!m_bRunning) + return false; + AddLog(CEC_LOG_DEBUG, "setting inactive view"); cec_frame frame; frame.push_back(GetSourceDestination(CECDEVICE_BROADCAST)); @@ -248,17 +287,17 @@ bool CCECParser::SetInactiveView(void) bool CCECParser::GetNextLogMessage(cec_log_message *message) { - return m_logBuffer.Pop(*message); + return m_bRunning ? m_logBuffer.Pop(*message) : false; } bool CCECParser::GetNextKeypress(cec_keypress *key) { - return m_keyBuffer.Pop(*key); + return m_bRunning ? m_keyBuffer.Pop(*key) : false; } bool CCECParser::GetNextCommand(cec_command *command) { - return m_commandBuffer.Pop(*command); + return m_bRunning ? m_commandBuffer.Pop(*command) : false; } //@} @@ -517,7 +556,7 @@ bool CCECParser::ReadFromDevice(int iTimeout) void CCECParser::ProcessMessages(void) { cec_frame msg; - while (GetMessage(msg)) + while (m_bRunning && GetMessage(msg)) ParseMessage(msg); } diff --git a/src/lib/CECParser.h b/src/lib/CECParser.h index 1eca99c..be95855 100644 --- a/src/lib/CECParser.h +++ b/src/lib/CECParser.h @@ -52,6 +52,7 @@ namespace CEC virtual ~CCECParser(void); virtual bool Open(const char *strPort, int iTimeout = 10000); + virtual bool Close(int iTimeoutMs = 2000); virtual int FindDevices(std::vector &deviceList, const char *strDevicePath = NULL); virtual bool Ping(void); virtual bool StartBootloader(void); @@ -116,6 +117,7 @@ namespace CEC std::string m_strDeviceName; pthread_t m_thread; CMutex m_mutex; + CCondition m_exitCondition; bool m_bRunning; }; }; diff --git a/src/lib/CECParserC.cpp b/src/lib/CECParserC.cpp index a4841a0..b21f1c0 100644 --- a/src/lib/CECParserC.cpp +++ b/src/lib/CECParserC.cpp @@ -47,13 +47,6 @@ bool cec_init(const char *strDeviceName, cec_logical_address iLogicalAddress /* return (cec_parser != NULL); } -bool cec_close(void) -{ - delete cec_parser; - cec_parser = NULL; - return true; -} - bool cec_open(const char *strPort, int iTimeout) { if (cec_parser) @@ -61,6 +54,17 @@ bool cec_open(const char *strPort, int iTimeout) return false; } +bool cec_close(int iTimeout) +{ + bool bReturn = false; + if (cec_parser) + bReturn = cec_parser->Close(iTimeout); + + delete cec_parser; + cec_parser = NULL; + return bReturn; +} + bool cec_ping(void) { if (cec_parser) diff --git a/src/lib/util/threads.cpp b/src/lib/util/threads.cpp index 3bfc1bd..3e40c2b 100644 --- a/src/lib/util/threads.cpp +++ b/src/lib/util/threads.cpp @@ -115,6 +115,8 @@ bool CCondition::Wait(CMutex *mutex, int64_t iTimeout) abstime.tv_sec = now.tv_sec + (time_t)(iTimeout / 1000); abstime.tv_nsec = (long)((iTimeout % (unsigned long)1000) * (unsigned long)1000000); m_bSignaled = (pthread_cond_timedwait(&m_cond, &mutex->m_mutex, &abstime) == 0); + if (!m_bSignaled) + pthread_mutex_unlock(&mutex->m_mutex); } bool bReturn = m_bSignaled; -- 2.34.1