From 943ccd62c55b3236bec3b96bb69af25adba86721 Mon Sep 17 00:00:00 2001 From: Christian Linke Date: Tue, 9 May 2017 04:04:53 -0700 Subject: clang minor findings Signed-off-by: Christian Linke --- AudioManagerUtilities/include/CAmDltWrapper.h | 2 +- AudioManagerUtilities/src/CAmDltWrapper.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/AudioManagerUtilities/include/CAmDltWrapper.h b/AudioManagerUtilities/include/CAmDltWrapper.h index 8c5678e..2e6795d 100644 --- a/AudioManagerUtilities/include/CAmDltWrapper.h +++ b/AudioManagerUtilities/include/CAmDltWrapper.h @@ -341,7 +341,7 @@ public: template void append(T value) { std::ostringstream ss; - ss << std::dec << value; + ss << std::dec << static_cast(value); append(ss.str().c_str()); } diff --git a/AudioManagerUtilities/src/CAmDltWrapper.cpp b/AudioManagerUtilities/src/CAmDltWrapper.cpp index 37a5ff0..44ec614 100644 --- a/AudioManagerUtilities/src/CAmDltWrapper.cpp +++ b/AudioManagerUtilities/src/CAmDltWrapper.cpp @@ -23,12 +23,14 @@ */ -#include "CAmDltWrapper.h" #include #include #include #include #include +#include +#include +#include "CAmDltWrapper.h" namespace am { @@ -624,7 +626,7 @@ bool CAmDltWrapper::initNoDlt(DltLogLevelType loglevel, DltContext* context) bool CAmDltWrapper::init(DltLogLevelType loglevel, DltContext* context) { pthread_mutex_lock(&mMutex); - initNoDlt(loglevel,context); + return initNoDlt(loglevel,context); } void CAmDltWrapper::send() -- cgit v1.2.1 From 31cc258d4a724701afcd99ef42c14d8dcf39731f Mon Sep 17 00:00:00 2001 From: Jacqueline Molz Date: Wed, 17 May 2017 17:02:49 +0200 Subject: updated misleading log message for setSystemProperty Change-Id: I331913ecaf302d5c00a4c4dfaf84b71e25f8eebf --- AudioManagerCore/src/CAmCommandReceiver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AudioManagerCore/src/CAmCommandReceiver.cpp b/AudioManagerCore/src/CAmCommandReceiver.cpp index 0c6338a..ccf9612 100644 --- a/AudioManagerCore/src/CAmCommandReceiver.cpp +++ b/AudioManagerCore/src/CAmCommandReceiver.cpp @@ -120,7 +120,7 @@ am_Error_e CAmCommandReceiver::setMainSourceSoundProperty(const am_MainSoundProp am_Error_e CAmCommandReceiver::setSystemProperty(const am_SystemProperty_s & property) { - logInfo(__METHOD_NAME__,"type=", property.type, "soundPropertyValue=", property.value); + logInfo(__METHOD_NAME__,"type=", property.type, "systemPropertyValue=", property.value); return (mControlSender->hookUserSetSystemProperty(property)); } -- cgit v1.2.1 From 1de23e9a30227986fff1f0ff6440af9a9ed703ba Mon Sep 17 00:00:00 2001 From: Jacqueline Molz Date: Thu, 18 May 2017 07:54:42 +0200 Subject: [Doc] removed link in docs added by mistake Change-Id: Ia370e64f20da7a692c07ea378a8619ee72715f17 --- docs/main_8cpp_source.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/main_8cpp_source.html b/docs/main_8cpp_source.html index 9b9df41..0c55aa5 100644 --- a/docs/main_8cpp_source.html +++ b/docs/main_8cpp_source.html @@ -279,7 +279,7 @@ $(document).ready(function(){initNavTree('main_8cpp_source.html','');});
204  switch (sig)
205  {
206  /*ctl +c lets call direct controllerRundown, because we might be blocked at the moment.
-
207  But there is the risk of interrupting something important */https://asc.bmwgroup.net/wiki/display/MGUROTO/Lastest+and+greatest
+
207  But there is the risk of interrupting something important */
208  case SIGINT:
210  break;
-- cgit v1.2.1 From 060323be5e5456b57229555d684680bf5d815052 Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Fri, 19 May 2017 11:55:01 +0200 Subject: The primary signals SIGINT and SIGQUIT are handled on top level in contrast to secondary signals SIGHUP, SIGTERM, SIGCHLD, which are handled in the SocketHandler. Signed-off-by: Christian Linke Change-Id: I8c5d3c436ac9fcd61c76a26145c731b427cab1e6 --- .../test/AmControlInterfaceTest/CMakeLists.txt | 1 + .../test/AmMapHandlerTest/CMakeLists.txt | 5 +- .../test/AmRouterMapTest/CMakeLists.txt | 5 +- AudioManagerCore/test/AmRouterTest/CMakeLists.txt | 1 + .../test/AmRoutingInterfaceTest/CMakeLists.txt | 3 +- AudioManagerDaemon/src/main.cpp | 54 +- AudioManagerUtilities/include/CAmSocketHandler.h | 791 +++++----- AudioManagerUtilities/src/CAmSocketHandler.cpp | 1627 ++++++++++---------- .../test/AmSerializerTest/CMakeLists.txt | 1 + .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 116 +- .../AmSocketHandlerTest/CAmSocketHandlerTest.h | 2 + .../test/AmSocketHandlerTest/CMakeLists.txt | 1 + CMakeLists.txt | 1 + 13 files changed, 1347 insertions(+), 1261 deletions(-) diff --git a/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt b/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt index f2636a8..b1a0dae 100644 --- a/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt +++ b/AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable(AmControlInterfaceTest ${CONTROL_INTERFACE_SRCS_CXX}) TARGET_LINK_LIBRARIES(AmControlInterfaceTest ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} AudioManagerCore ) diff --git a/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt b/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt index 41c62c7..57f4130 100644 --- a/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt +++ b/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt @@ -34,9 +34,10 @@ file(GLOB DATABASE_SRCS_CXX ADD_EXECUTABLE( AmMapHandlerTest ${DATABASE_SRCS_CXX}) TARGET_LINK_LIBRARIES( AmMapHandlerTest - ${GTEST_LIBRARIES} + ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} - AudioManagerCore + ${CMAKE_THREAD_LIBS_INIT} + AudioManagerCore ) ADD_TEST(AmMapHandlerTest AmMapHandlerTest) diff --git a/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt b/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt index dc2732c..f1400e4 100644 --- a/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt +++ b/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt @@ -32,9 +32,10 @@ file(GLOB ROUTINGMAP_SRCS_CXX ADD_EXECUTABLE( AmRouterMapTest ${ROUTINGMAP_SRCS_CXX}) TARGET_LINK_LIBRARIES(AmRouterMapTest - ${GTEST_LIBRARIES} + ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} - AudioManagerCore + ${CMAKE_THREAD_LIBS_INIT} + AudioManagerCore ) ADD_TEST(AmRouterMapTest AmRouterMapTest) diff --git a/AudioManagerCore/test/AmRouterTest/CMakeLists.txt b/AudioManagerCore/test/AmRouterTest/CMakeLists.txt index 89094c8..d866032 100644 --- a/AudioManagerCore/test/AmRouterTest/CMakeLists.txt +++ b/AudioManagerCore/test/AmRouterTest/CMakeLists.txt @@ -35,6 +35,7 @@ ADD_EXECUTABLE( AmRouterTest ${ROUTING_SRCS_CXX}) TARGET_LINK_LIBRARIES(AmRouterTest ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} AudioManagerCore ) diff --git a/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt b/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt index 6d47c15..cb6bb28 100644 --- a/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt +++ b/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt @@ -37,7 +37,8 @@ ADD_TEST(AmRoutingInterfaceTest AmRoutingInterfaceTest) TARGET_LINK_LIBRARIES(AmRoutingInterfaceTest ${GTEST_LIBRARIES} - ${GMOCK_LIBRARIES} + ${GMOCK_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} AudioManagerCore ) diff --git a/AudioManagerDaemon/src/main.cpp b/AudioManagerDaemon/src/main.cpp index 4e8ca47..5c0582e 100755 --- a/AudioManagerDaemon/src/main.cpp +++ b/AudioManagerDaemon/src/main.cpp @@ -179,6 +179,36 @@ void printCmdInformation() exit(0); } +/** + * the signal handler + * @param sig + * @param siginfo + * @param context + */ +static void signalHandler(int sig, siginfo_t *siginfo, void *context) +{ + (void) sig; + (void) siginfo; + (void) context; + logInfo("signal handler was called, signal",sig); + + switch (sig) + { + /*ctl +c lets call direct controllerRundown, because we might be blocked at the moment. + But there is the risk of interrupting something important */ + case SIGINT: + CAmControlSender::CallsetControllerRundown(sig); + break; + + /* huch- we are getting killed. Better take the fast but risky way: */ + case SIGQUIT: + CAmControlSender::CallsetControllerRundown(sig); + break; + default: + break; + } +} + void mainProgram(int argc, char *argv[]) { @@ -220,6 +250,11 @@ void mainProgram(int argc, char *argv[]) { throw std::runtime_error(std::string("CAmSocketHandler: Could not create pipe or file descriptor is invalid.")); } + + if( E_OK!=iSocketHandler.listenToSignals({SIGHUP, SIGTERM, SIGCHLD}) ) + { + logWarning("CAmSocketHandler failed to register itself as signal handler."); + } //Register signal handler sh_pollHandle_t signalHandler; iSocketHandler.addSignalHandler([&](const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData){ @@ -231,17 +266,6 @@ void mainProgram(int argc, char *argv[]) switch (sig) { - /*ctl +c lets call direct controllerRundown, because we might be blocked at the moment. - But there is the risk of interrupting something important */ - case SIGINT: - CAmControlSender::CallsetControllerRundown(sig); - break; - - /* huch- we are getting killed. Better take the fast but risky way: */ - case SIGQUIT: - CAmControlSender::CallsetControllerRundown(sig); - break; - /* more friendly here assuming systemd wants to stop us, so we can use the mainloop */ case SIGTERM: CAmControlSender::CallsetControllerRundownSafe(sig); @@ -364,6 +388,14 @@ int main(int argc, char *argv[], char** envp) listCommandPluginDirs.push_back(std::string(DEFAULT_PLUGIN_COMMAND_DIR)); listRoutingPluginDirs.push_back(std::string(DEFAULT_PLUGIN_ROUTING_DIR)); + //critical signals are registered here: + struct sigaction signalAction; + memset(&signalAction, '\0', sizeof(signalAction)); + signalAction.sa_sigaction = &signalHandler; + signalAction.sa_flags = SA_SIGINFO; + sigaction(SIGINT, &signalAction, NULL); + sigaction(SIGQUIT, &signalAction, NULL); + //register new out of memory handler std::set_new_handler(&OutOfMemoryHandler); diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h index 0f9b710..717f792 100644 --- a/AudioManagerUtilities/include/CAmSocketHandler.h +++ b/AudioManagerUtilities/include/CAmSocketHandler.h @@ -48,478 +48,447 @@ namespace am #define MAX_TIMERHANDLE UINT16_MAX #define MAX_POLLHANDLE UINT16_MAX - typedef uint16_t sh_pollHandle_t; //! class TAmShPollFired: public IAmShPollFired +{ +private: + TClass* mInstance; + void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); - /**make private, not public - * template for a callback - */ - template class TAmShPollFired: public IAmShPollFired +public: + TAmShPollFired(TClass* instance, void (TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) : + mInstance(instance), // + mFunction(function) + {} + + virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData) { - private: - TClass* mInstance; - void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); - - public: - TAmShPollFired(TClass* instance, void (TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) : - mInstance(instance), // - mFunction(function) - { - } - ; + (*mInstance.*mFunction)(pollfd, handle, userData); + } +}; - virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData) - { - (*mInstance.*mFunction)(pollfd, handle, userData); - } - ; - }; +/** + * template for a callback + */ +template class TAmShPollCheck: public IAmShPollCheck +{ +private: + TClass* mInstance; + bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData); - /** - * template for a callback - */ - template class TAmShPollCheck: public IAmShPollCheck +public: + TAmShPollCheck(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) : + mInstance(instance), // + mFunction(function) + {} + + virtual bool Call(const sh_pollHandle_t handle, void* userData) { - private: - TClass* mInstance; - bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData); - - public: - TAmShPollCheck(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) : - mInstance(instance), // - mFunction(function) - { - } - ; + return ((*mInstance.*mFunction)(handle, userData)); + } +}; - virtual bool Call(const sh_pollHandle_t handle, void* userData) - { - return ((*mInstance.*mFunction)(handle, userData)); - } - ; - }; +/** + * template for a callback + */ +template class TAmShPollDispatch: public IAmShPollDispatch +{ +private: + TClass* mInstance; + bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData); - /** - * template for a callback - */ - template class TAmShPollDispatch: public IAmShPollDispatch +public: + TAmShPollDispatch(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) : + mInstance(instance), // + mFunction(function) + {} + + virtual bool Call(const sh_pollHandle_t handle, void* userData) { - private: - TClass* mInstance; - bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData); - - public: - TAmShPollDispatch(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) : - mInstance(instance), // - mFunction(function) - { - } - ; + return ((*mInstance.*mFunction)(handle, userData)); + } +}; - virtual bool Call(const sh_pollHandle_t handle, void* userData) - { - return ((*mInstance.*mFunction)(handle, userData)); - } - ; - }; +/** + * template to create the functor for a class + */ +template class TAmShTimerCallBack: public IAmShTimerCallBack +{ +private: + TClass* mInstance; + void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData); - /** - * template to create the functor for a class - */ - template class TAmShTimerCallBack: public IAmShTimerCallBack +public: + TAmShTimerCallBack(TClass* instance, void (TClass::*function)(sh_timerHandle_t handle, void* userData)) : + IAmShTimerCallBack(), mInstance(instance), // + mFunction(function) + {} + + virtual void Call(sh_timerHandle_t handle, void* userData) { - private: - TClass* mInstance; - void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData); - - public: - TAmShTimerCallBack(TClass* instance, void (TClass::*function)(sh_timerHandle_t handle, void* userData)) : - IAmShTimerCallBack(), mInstance(instance), // - mFunction(function) - { - } - ; + (*mInstance.*mFunction)(handle, userData); + } +}; - virtual void Call(sh_timerHandle_t handle, void* userData) - { - (*mInstance.*mFunction)(handle, userData); - } - }; +/** + * template for a callback + */ - /** - * template for a callback - */ +template class TAmShPollPrepare: public IAmShPollPrepare +{ +private: + TClass* mInstance; + void (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData); - template class TAmShPollPrepare: public IAmShPollPrepare +public: + TAmShPollPrepare(TClass* instance, void (TClass::*function)(const sh_pollHandle_t handle, void* userData)) : + mInstance(instance), // + mFunction(function) + {} + + virtual void Call(const sh_pollHandle_t handle, void* userData) { - private: - TClass* mInstance; - void (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData); - - public: - TAmShPollPrepare(TClass* instance, void (TClass::*function)(const sh_pollHandle_t handle, void* userData)) : - mInstance(instance), // - mFunction(function) - { - } - ; + (*mInstance.*mFunction)(handle, userData); + } +}; - virtual void Call(const sh_pollHandle_t handle, void* userData) - { - (*mInstance.*mFunction)(handle, userData); - } - ; +/** + * The am::CAmSocketHandler implements a mainloop for the AudioManager. Plugins and different parts of the AudioManager add their filedescriptors to the handler + * to get called on communication of the filedescriptors.\n + * More information can be found here : \ref mainl + */ +class CAmSocketHandler +{ + struct sh_poll_s //! prepareCB; //preperation callback + std::function firedCB; //fired callback + std::function checkCB; //check callback + std::function dispatchCB; //dispatch callback + void* userData; + + sh_poll_s() : + handle(0), pollfdValue(), prepareCB(), firedCB(), checkCB(), dispatchCB(), userData(0) + {} }; - /** - * The am::CAmSocketHandler implements a mainloop for the AudioManager. Plugins and different parts of the AudioManager add their filedescriptors to the handler - * to get called on communication of the filedescriptors.\n - * More information can be found here : \ref mainl - */ - class CAmSocketHandler + struct sh_timer_s //! prepareCB; //preperation callback - std::function firedCB; //fired callback - std::function checkCB; //check callback - std::function dispatchCB; //dispatch callback - void* userData; - - sh_poll_s() : - handle(0), pollfdValue(), prepareCB(), firedCB(), checkCB(), dispatchCB(), userData(0) - { - } - }; - - struct sh_timer_s //! callback; //timer callback - void* userData; - sh_timer_s() : - handle(0) + std::function callback; //timer callback + void* userData; + sh_timer_s() : + handle(0) #ifdef WITH_TIMERFD - , fd(0) + , fd(0) #endif - , countdown(), callback(), userData(0) - { - } - }; + , countdown(), callback(), userData(0) + {} + }; - struct sh_signal_s - { - sh_pollHandle_t handle; //! callback; - void* userData; - sh_signal_s() : - handle(0), callback(), userData(0) - { - } - }; + struct sh_signal_s + { + sh_pollHandle_t handle; //! callback; + void* userData; + sh_signal_s() : + handle(0), callback(), userData(0) + {} + }; - struct sh_identifier_s - { - std::set pollHandles; - uint16_t limit; - uint16_t lastUsedID; - sh_identifier_s(const uint16_t pollLimit = UINT16_MAX) : - pollHandles(), limit(pollLimit), lastUsedID(0) - { - } - }; + struct sh_identifier_s + { + std::set pollHandles; + uint16_t limit; + uint16_t lastUsedID; + sh_identifier_s(const uint16_t pollLimit = UINT16_MAX) : + pollHandles(), limit(pollLimit), lastUsedID(0) + {} + }; - typedef std::reverse_iterator rListTimerIter; //! VectorListPollfd_t; //! VectorListPoll_t; //! VectorSignalHandlers_t; //! rListTimerIter; //! VectorListPollfd_t; //! VectorListPoll_t; //! VectorSignalHandlers_t; //! mListTimer; //! mListActiveTimer; //! mListTimer; //! mListActiveTimer; //!= MAX_NS) { - timespec result; - result.tv_sec = a.tv_sec + b.tv_sec; - result.tv_nsec = a.tv_nsec + b.tv_nsec; - if (result.tv_nsec >= MAX_NS) - { - result.tv_sec++; - result.tv_nsec = result.tv_nsec - MAX_NS; - } - return (result); + result.tv_sec++; + result.tv_nsec = result.tv_nsec - MAX_NS; } + return (result); + } - /** - * comapares timespec values - * @param a - * @param b - * @return - */ - inline int timespecCompare(const timespec& a, const timespec& b) - { - //less - if (a.tv_sec < b.tv_sec) - return (-1); - //greater - else if (a.tv_sec > b.tv_sec) - return (1); - //less - else if (a.tv_nsec < b.tv_nsec) - return (-1); - //greater - else if (a.tv_nsec > b.tv_nsec) - return (1); - //equal - return (0); - } + /** + * comapares timespec values + * @param a + * @param b + * @return + */ + inline int timespecCompare(const timespec& a, const timespec& b) + { + //less + if (a.tv_sec < b.tv_sec) + return (-1); + //greater + else if (a.tv_sec > b.tv_sec) + return (1); + //less + else if (a.tv_nsec < b.tv_nsec) + return (-1); + //greater + else if (a.tv_nsec > b.tv_nsec) + return (1); + //equal + return (0); + } #endif - /** - * functor to prepare all fire events - * @param a - * @return - */ - inline static void prepare(sh_poll_s& row); + /** + * functor to prepare all fire events + * @param a + * @return + */ + inline static void prepare(sh_poll_s& row); + + /** + * functor to return all fired events + * @param a + * @return + */ + inline static void fire(sh_poll_s& a); + + /** + * functor to return all fired events + * @param a + * @return + */ + inline static bool eventFired(const pollfd& a); + + /** + * functor to help find the items that do not need dispatching + * @param a + * @return + */ + inline static bool noDispatching(const sh_poll_s& a); + + /** + * checks if dispatching is already finished + * @param a + * @return + */ + inline static bool dispatchingFinished(const sh_poll_s& a); + + /** + * timer fire callback + * @param a + * @return + */ + inline static void callTimer(sh_timer_s& a); + + /** + * next handle id + * @param std::set handles + * @return handle + */ + bool nextHandle(sh_identifier_s & handle); + + am_Error_e getFDPollData(const sh_pollHandle_t handle, sh_poll_s & outPollData); + +public: + + CAmSocketHandler(); + ~CAmSocketHandler(); - /** - * functor to return all fired events - * @param a - * @return - */ - inline static void fire(sh_poll_s& a); - - /** - * functor to return all fired events - * @param a - * @return - */ - inline static bool eventFired(const pollfd& a); - - /** - * functor to help find the items that do not need dispatching - * @param a - * @return - */ - inline static bool noDispatching(const sh_poll_s& a); - - /** - * checks if dispatching is already finished - * @param a - * @return - */ - inline static bool dispatchingFinished(const sh_poll_s& a); - - /** - * timer fire callback - * @param a - * @return - */ - inline static void callTimer(sh_timer_s& a); - - /** - * install the signal fd - */ - - am_Error_e addSignalFd(); - /** - * next handle id - * @param std::set handles - * @return handle - */ - bool nextHandle(sh_identifier_s & handle); - - public: - - CAmSocketHandler(); - ~CAmSocketHandler(); - - am_Error_e addFDPoll(const int fd, const short event, std::function prepare, std::function fired, - std::function check, std::function dispatch, void* userData, sh_pollHandle_t& handle); - - am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void* userData, sh_pollHandle_t& handle); - am_Error_e removeFDPoll(const sh_pollHandle_t handle); - am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events); - am_Error_e addSignalHandler(std::function callback, sh_pollHandle_t& handle, void * userData); - am_Error_e removeSignalHandler(const sh_pollHandle_t handle); - am_Error_e addTimer(const timespec & timeouts, IAmShTimerCallBack* callback, sh_timerHandle_t& handle, void * userData, + /** + * install the signal fd + */ + am_Error_e listenToSignals(const std::vector & listSignals); + + am_Error_e addFDPoll(const int fd, const short event, std::function prepare, std::function fired, + std::function check, std::function dispatch, void* userData, sh_pollHandle_t& handle); + + am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void* userData, sh_pollHandle_t& handle); + am_Error_e removeFDPoll(const sh_pollHandle_t handle); + am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events); + am_Error_e addSignalHandler(std::function callback, sh_pollHandle_t& handle, void * userData); + am_Error_e removeSignalHandler(const sh_pollHandle_t handle); + am_Error_e addTimer(const timespec & timeouts, IAmShTimerCallBack* callback, sh_timerHandle_t& handle, void * userData, #ifndef WITH_TIMERFD - const bool __attribute__((__unused__)) repeats = false + const bool __attribute__((__unused__)) repeats = false #else - const bool repeats = false + const bool repeats = false #endif - ); - am_Error_e addTimer(const timespec & timeouts, std::function callback, sh_timerHandle_t& handle, void* userData, + ); + am_Error_e addTimer(const timespec & timeouts, std::function callback, sh_timerHandle_t& handle, void* userData, #ifndef WITH_TIMERFD - const bool __attribute__((__unused__)) repeats = false + const bool __attribute__((__unused__)) repeats = false #else - const bool repeats = false + const bool repeats = false #endif - ); - am_Error_e removeTimer(const sh_timerHandle_t handle); - am_Error_e restartTimer(const sh_timerHandle_t handle); - am_Error_e updateTimer(const sh_timerHandle_t handle, const timespec & timeouts); - am_Error_e stopTimer(const sh_timerHandle_t handle); - void start_listenting(); - void stop_listening(); - void exit_mainloop(); - - bool fatalErrorOccurred() { return ((mError&internal_error_codes_e::PIPE_ERROR)>0)||((mError&internal_error_codes_e::FD_ERROR)>0); } - }; + ); + am_Error_e removeTimer(const sh_timerHandle_t handle); + am_Error_e restartTimer(const sh_timerHandle_t handle); + am_Error_e updateTimer(const sh_timerHandle_t handle, const timespec & timeouts); + am_Error_e stopTimer(const sh_timerHandle_t handle); + void start_listenting(); + void stop_listening(); + void exit_mainloop(); + + bool fatalErrorOccurred(); +}; } /* namespace am */ #endif /* SOCKETHANDLER_H_ */ diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp index fe7cf58..7b0fc5d 100644 --- a/AudioManagerUtilities/src/CAmSocketHandler.cpp +++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp @@ -42,998 +42,1039 @@ namespace am { - CAmSocketHandler::CAmSocketHandler() : - mPipe(), // - mDispatchDone(1), // - mSetPollKeys(MAX_POLLHANDLE), // - mListPoll(), // - mSetTimerKeys(MAX_TIMERHANDLE), - mListTimer(), // - mListActiveTimer(), // - mSetSignalhandlerKeys(MAX_POLLHANDLE), // - mSignalHandlers(), // - mRecreatePollfds(true), - mError(internal_error_codes_e::NO_ERROR) +CAmSocketHandler::CAmSocketHandler() : + mPipe(), // + mDispatchDone(true), // + mSetPollKeys(MAX_POLLHANDLE), // + mListPoll(), // + mSetTimerKeys(MAX_TIMERHANDLE), + mListTimer(), // + mListActiveTimer(), // + mSetSignalhandlerKeys(MAX_POLLHANDLE), // + mSignalHandlers(), // + mRecreatePollfds(true), + mInternalCodes(internal_codes_e::NO_ERROR), + mSignalFdHandle(0) #ifndef WITH_TIMERFD - ,mStartTime() // +,mStartTime() // #endif +{ + if (pipe(mPipe) == -1) { - if (pipe(mPipe) == -1) - { - mError = internal_error_codes_e::PIPE_ERROR; - logError("Sockethandler could not create pipe!"); - } - - //add the pipe to the poll - nothing needs to be processed here we just need the pipe to trigger the ppoll - short event = 0; - sh_pollHandle_t handle; - event |= POLLIN; - if (addFDPoll(mPipe[0], event, NULL, [](const pollfd pollfd, const sh_pollHandle_t, void*) - {}, [](const sh_pollHandle_t, void*) - { return (false);}, NULL, NULL, handle) != E_OK) - mError |= internal_error_codes_e::FD_ERROR; - if (addSignalFd() != E_OK) - mError |= internal_error_codes_e::SFD_ERROR; + mInternalCodes = internal_codes_e::PIPE_ERROR; + logError("Sockethandler could not create pipe!"); } - CAmSocketHandler::~CAmSocketHandler() + //add the pipe to the poll - nothing needs to be processed here we just need the pipe to trigger the ppoll + short event = 0; + sh_pollHandle_t handle; + event |= POLLIN; + if (addFDPoll(mPipe[0], event, NULL, [](const pollfd pollfd, const sh_pollHandle_t, void*) + {}, [](const sh_pollHandle_t, void*) + { return (false);}, NULL, NULL, handle) != E_OK) + mInternalCodes |= internal_codes_e::FD_ERROR; +} + +CAmSocketHandler::~CAmSocketHandler() +{ + for (auto it : mListPoll) { - for (auto it : mListPoll) - { - close(it.pollfdValue.fd); - } - close(mPipe[0]); - close(mPipe[1]); + close(it.pollfdValue.fd); } + close(mPipe[0]); + close(mPipe[1]); +} //todo: maybe have some: give me more time returned? - /** - * start the block listening for filedescriptors. This is the mainloop. - */ - void CAmSocketHandler::start_listenting() - { - mDispatchDone = 0; - int16_t pollStatus; - - //prepare the signalmask - sigset_t sigmask; - sigemptyset(&sigmask); - sigaddset(&sigmask, SIGINT); - sigaddset(&sigmask, SIGQUIT); - sigaddset(&sigmask, SIGTERM); - sigaddset(&sigmask, SIGHUP); - sigaddset(&sigmask, SIGQUIT); +/** + * start the block listening for filedescriptors. This is the mainloop. + */ +void CAmSocketHandler::start_listenting() +{ + mDispatchDone = false; + int16_t pollStatus; + #ifndef WITH_TIMERFD - clock_gettime(CLOCK_MONOTONIC, &mStartTime); + clock_gettime(CLOCK_MONOTONIC, &mStartTime); #endif - timespec buffertime; - - std::list listPoll; - VectorListPoll_t cloneListPoll; - VectorListPoll_t::iterator listmPollIt; - VectorListPollfd_t::iterator itMfdPollingArray; - VectorListPollfd_t fdPollingArray; //! listPoll; + VectorListPoll_t cloneListPoll; + VectorListPoll_t::iterator listmPollIt; + VectorListPollfd_t::iterator itMfdPollingArray; + VectorListPollfd_t fdPollingArray; //!0)||((mInternalCodes&internal_codes_e::FD_ERROR)>0); +} + +am_Error_e CAmSocketHandler::getFDPollData(const sh_pollHandle_t handle, sh_poll_s & outPollData) +{ + VectorListPoll_t::iterator iterator = mListPoll.begin(); + for (; iterator != mListPoll.end(); ++iterator) + { + if (iterator->handle == handle) { - logError("Could not create sigset!"); - return (E_NOT_POSSIBLE); + outPollData = *iterator; + return (E_OK); } - fdErr = sigaddset(&sigset, SIGINT); - if (fdErr != 0) - logWarning("Could not add SIGINT"); - fdErr = sigaddset(&sigset, SIGHUP); - if (fdErr != 0) - logWarning("Could not add SIGHUP"); - fdErr = sigaddset(&sigset, SIGQUIT); - if (fdErr != 0) - logWarning("Could not add SIGQUIT"); - fdErr = sigaddset(&sigset, SIGTERM); - if (fdErr != 0) - logWarning("Could not add SIGTERM"); - fdErr = sigaddset(&sigset, SIGCHLD); - if (fdErr != 0) - logWarning("Could not add SIGCHLD"); + } + return (E_UNKNOWN); +} - /* We must block the signals in order for signalfd to receive them */ - fdErr = sigprocmask(SIG_BLOCK, &sigset, NULL); +/** + * Adds a signal handler filedescriptor to the polling loop + * + */ +am_Error_e CAmSocketHandler::listenToSignals(const std::vector & listSignals) +{ + int fdErr; + uint8_t addedSignals = 0; + sigset_t sigset; + + if(0==listSignals.size()) + { + logWarning("Empty signal list!"); + return (E_NOT_POSSIBLE); + } + + /* Create a sigset of all the signals that we're interested in */ + fdErr = sigemptyset(&sigset); + if (fdErr != 0) + { + logError("Could not create sigset!"); + return (E_NOT_POSSIBLE); + } + + for(uint8_t itSignal : listSignals) + { + fdErr = sigaddset(&sigset, itSignal); if (fdErr != 0) - { - logError("Could not block signals! They must be blocked in order to receive them!"); - return (E_NOT_POSSIBLE); - } + logWarning("Could not add", itSignal); + else + addedSignals++; + } + + if(0==addedSignals) + { + logWarning("None of the signals were added!"); + return (E_NOT_POSSIBLE); + } - /* Create the signalfd */ - int signalHandlerFd = signalfd(-1, &sigset, 0); + /* We must block the signals in order for signalfd to receive them */ + fdErr = sigprocmask(SIG_BLOCK, &sigset, NULL); + if (fdErr != 0) + { + logError("Could not block signals! They must be blocked in order to receive them!"); + return (E_NOT_POSSIBLE); + } + + int signalHandlerFd; + if(mSignalFdHandle) + { + sh_poll_s sgPollData; + if(E_OK!=getFDPollData(mSignalFdHandle, sgPollData)) + { + removeFDPoll(mSignalFdHandle); + mSignalFdHandle = 0; + } + else + { + int signalHandlerFd = signalfd(sgPollData.pollfdValue.fd, &sigset, 0); if (signalHandlerFd == -1) { - logError("Could not open signal fd!"); + logError("Could not update signal fd!"); return (E_NOT_POSSIBLE); } - - auto actionPoll = [this](const pollfd pollfd, const sh_pollHandle_t, void*) - { - const VectorSignalHandlers_t & signalHandlers = mSignalHandlers; - /* We have a valid signal, read the info from the fd */ - struct signalfd_siginfo info; - ssize_t bytes = read(pollfd.fd, &info, sizeof(info)); - assert(bytes == sizeof(info)); - - /* We have a valid signal, read the info from the fd */ - for(auto it: signalHandlers) - it.callback(it.handle, info, it.userData); - }; - /* We're going to add the signal fd through addFDPoll. At this point we don't have any signal listeners. */ - return addFDPoll(signalHandlerFd, POLLIN | POLLERR | POLLHUP, NULL, actionPoll, [](const sh_pollHandle_t, void*) - { return (false);}, NULL, NULL, handle); + return E_OK; + } } + + if(0==mSignalFdHandle) + { + /* Create the signalfd */ + signalHandlerFd = signalfd(-1, &sigset, 0); + if (signalHandlerFd == -1) + { + logError("Could not open signal fd!"); + return (E_NOT_POSSIBLE); + } + + auto actionPoll = [this](const pollfd pollfd, const sh_pollHandle_t, void*) + { + const VectorSignalHandlers_t & signalHandlers = mSignalHandlers; + /* We have a valid signal, read the info from the fd */ + struct signalfd_siginfo info; + ssize_t bytes = read(pollfd.fd, &info, sizeof(info)); + assert(bytes == sizeof(info)); + + /* Notify all listeners */ + for(auto it: signalHandlers) + it.callback(it.handle, info, it.userData); + }; + /* We're going to add the signal fd through addFDPoll. At this point we don't have any signal listeners. */ + am_Error_e shFdError = addFDPoll(signalHandlerFd, POLLIN | POLLERR | POLLHUP, NULL, actionPoll, [](const sh_pollHandle_t, void*) + { return (false);}, NULL, NULL, mSignalFdHandle); + return shFdError; + } +} + +/** + * Adds a filedescriptor to the polling loop + * @param fd the filedescriptor + * @param event the event flags + * @param prepare a std::function that is called before the loop is entered + * @param fired a std::function that is called when the filedescriptor needs to be read + * @param check a std::function that is called to check if further actions are neccessary + * @param dispatch a std::function that is called to dispatch the received data + * @param userData a pointer to userdata that is always passed around + * @param handle the handle of this poll + * @return E_OK if the descriptor was added, E_NON_EXISTENT if the fd is not valid + */ + +am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, std::function prepare, + std::function fired, std::function check, + std::function dispatch, void* userData, sh_pollHandle_t& handle) +{ + if (!fdIsValid(fd)) + return (E_NON_EXISTENT); - /** - * Adds a filedescriptor to the polling loop - * @param fd the filedescriptor - * @param event the event flags - * @param prepare a std::function that is called before the loop is entered - * @param fired a std::function that is called when the filedescriptor needs to be read - * @param check a std::function that is called to check if further actions are neccessary - * @param dispatch a std::function that is called to dispatch the received data - * @param userData a pointer to userdata that is always passed around - * @param handle the handle of this poll - * @return E_OK if the descriptor was added, E_NON_EXISTENT if the fd is not valid - */ - - am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, std::function prepare, - std::function fired, std::function check, - std::function dispatch, void* userData, sh_pollHandle_t& handle) + //create a new handle for the poll + if (!nextHandle(mSetPollKeys)) { - if (!fdIsValid(fd)) - return (E_NON_EXISTENT); + logError("Could not create new polls, too many open!"); + return (E_NOT_POSSIBLE); + } - //create a new handle for the poll - if (!nextHandle(mSetPollKeys)) - { - logError("Could not create new polls, too many open!"); - return (E_NOT_POSSIBLE); - } + sh_poll_s pollData; + pollData.pollfdValue.fd = fd; + pollData.handle = mSetPollKeys.lastUsedID; + pollData.pollfdValue.events = event; + pollData.pollfdValue.revents = 0; + pollData.prepareCB = prepare; + pollData.firedCB = fired; + pollData.checkCB = check; + pollData.dispatchCB = dispatch; + pollData.userData = userData; + //add new data to the list + mListPoll.push_back(pollData); - sh_poll_s pollData; - pollData.pollfdValue.fd = fd; - pollData.handle = mSetPollKeys.lastUsedID; - pollData.pollfdValue.events = event; - pollData.pollfdValue.revents = 0; - pollData.prepareCB = prepare; - pollData.firedCB = fired; - pollData.checkCB = check; - pollData.dispatchCB = dispatch; - pollData.userData = userData; - //add new data to the list - mListPoll.push_back(pollData); + mRecreatePollfds = true; - mRecreatePollfds = true; + handle = pollData.handle; + return (E_OK); - handle = pollData.handle; - return (E_OK); +} - } +/** + * Adds a filedescriptor to the polling loop + * @param fd the filedescriptor + * @param event the event flags + * @param prepare a callback that is called before the loop is entered + * @param fired a callback that is called when the filedescriptor needs to be read + * @param check a callback that is called to check if further actions are neccessary + * @param dispatch a callback that is called to dispatch the received data + * @param userData a pointer to userdata that is always passed around + * @param handle the handle of this poll + * @return E_OK if the descriptor was added, E_NON_EXISTENT if the fd is not valid + */ +am::am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void *userData, sh_pollHandle_t & handle) +{ - /** - * Adds a filedescriptor to the polling loop - * @param fd the filedescriptor - * @param event the event flags - * @param prepare a callback that is called before the loop is entered - * @param fired a callback that is called when the filedescriptor needs to be read - * @param check a callback that is called to check if further actions are neccessary - * @param dispatch a callback that is called to dispatch the received data - * @param userData a pointer to userdata that is always passed around - * @param handle the handle of this poll - * @return E_OK if the descriptor was added, E_NON_EXISTENT if the fd is not valid - */ - am::am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void *userData, sh_pollHandle_t & handle) - { + std::function prepareCB; //preperation callback + std::function firedCB; //fired callback + std::function checkCB; //check callback + std::function dispatchCB; //check callback + + if (prepare) + prepareCB = std::bind(&IAmShPollPrepare::Call, prepare, std::placeholders::_1, std::placeholders::_2); + if (fired) + firedCB = std::bind(&IAmShPollFired::Call, fired, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); + if (check) + checkCB = std::bind(&IAmShPollCheck::Call, check, std::placeholders::_1, std::placeholders::_2); + if (dispatch) + dispatchCB = std::bind(&IAmShPollDispatch::Call, dispatch, std::placeholders::_1, std::placeholders::_2); + + return addFDPoll(fd, event, prepareCB, firedCB, checkCB, dispatchCB, userData, handle); +} - std::function prepareCB; //preperation callback - std::function firedCB; //fired callback - std::function checkCB; //check callback - std::function dispatchCB; //check callback - - if (prepare) - prepareCB = std::bind(&IAmShPollPrepare::Call, prepare, std::placeholders::_1, std::placeholders::_2); - if (fired) - firedCB = std::bind(&IAmShPollFired::Call, fired, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - if (check) - checkCB = std::bind(&IAmShPollCheck::Call, check, std::placeholders::_1, std::placeholders::_2); - if (dispatch) - dispatchCB = std::bind(&IAmShPollDispatch::Call, dispatch, std::placeholders::_1, std::placeholders::_2); - - return addFDPoll(fd, event, prepareCB, firedCB, checkCB, dispatchCB, userData, handle); - } +/** + * removes a filedescriptor from the poll loop + * @param handle + * @return + */ +am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle) +{ + VectorListPoll_t::iterator iterator = mListPoll.begin(); - /** - * removes a filedescriptor from the poll loop - * @param handle - * @return - */ - am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle) + for (; iterator != mListPoll.end(); ++iterator) { - VectorListPoll_t::iterator iterator = mListPoll.begin(); - - for (; iterator != mListPoll.end(); ++iterator) + if (iterator->handle == handle) { - if (iterator->handle == handle) - { - iterator = mListPoll.erase(iterator); - mSetPollKeys.pollHandles.erase(handle); - mRecreatePollfds = true; - return (E_OK); - } + iterator = mListPoll.erase(iterator); + mSetPollKeys.pollHandles.erase(handle); + mRecreatePollfds = true; + return (E_OK); } - return (E_UNKNOWN); } + return (E_UNKNOWN); +} - /** - * Adds a callback for any signals - * @param callback - * @param handle the handle of this poll - * @param userData a pointer to userdata that is always passed around - * @return E_OK if the descriptor was added, E_NON_EXISTENT if the fd is not valid - */ - am_Error_e CAmSocketHandler::addSignalHandler(std::function callback, sh_pollHandle_t& handle, void * userData) +/** + * Adds a callback for any signals + * @param callback + * @param handle the handle of this poll + * @param userData a pointer to userdata that is always passed around + * @return E_OK if the descriptor was added, E_NON_EXISTENT if the fd is not valid + */ +am_Error_e CAmSocketHandler::addSignalHandler(std::function callback, sh_pollHandle_t& handle, void * userData) +{ + if (!nextHandle(mSetSignalhandlerKeys)) { - if (!nextHandle(mSetSignalhandlerKeys)) - { - logError("Could not create new polls, too many open!"); - return (E_NOT_POSSIBLE); - } + logError("Could not create new polls, too many open!"); + return (E_NOT_POSSIBLE); + } - mSignalHandlers.emplace_back(); - mSignalHandlers.back().callback = callback; - mSignalHandlers.back().handle = mSetSignalhandlerKeys.lastUsedID; - mSignalHandlers.back().userData = userData; - handle = mSetSignalhandlerKeys.lastUsedID; + mSignalHandlers.emplace_back(); + mSignalHandlers.back().callback = callback; + mSignalHandlers.back().handle = mSetSignalhandlerKeys.lastUsedID; + mSignalHandlers.back().userData = userData; + handle = mSetSignalhandlerKeys.lastUsedID; - return E_OK; - } + return E_OK; +} - /** - * removes a signal handler from the list - * @param handle is signal handler id - * @return E_OK in case of success, E_UNKNOWN if the handler was not found. - */ - am_Error_e CAmSocketHandler::removeSignalHandler(const sh_pollHandle_t handle) +/** + * removes a signal handler from the list + * @param handle is signal handler id + * @return E_OK in case of success, E_UNKNOWN if the handler was not found. + */ +am_Error_e CAmSocketHandler::removeSignalHandler(const sh_pollHandle_t handle) +{ + VectorSignalHandlers_t::iterator it(mSignalHandlers.begin()); + for (; it != mSignalHandlers.end(); ++it) { - VectorSignalHandlers_t::iterator it(mSignalHandlers.begin()); - for (; it != mSignalHandlers.end(); ++it) + if (it->handle == handle) { - if (it->handle == handle) - { - it = mSignalHandlers.erase(it); - mSetSignalhandlerKeys.pollHandles.erase(handle); - return (E_OK); - } + it = mSignalHandlers.erase(it); + mSetSignalhandlerKeys.pollHandles.erase(handle); + return (E_OK); } - return (E_UNKNOWN); } + return (E_UNKNOWN); +} - /** - * adds a timer to the list of timers. The callback will be fired when the timer is up. - * This is not a high precise timer, it is very coarse. It is meant to be used for timeouts when waiting - * for an answer via a filedescriptor. - * One time timer. If you need again a timer, you need to add a new timer in the callback of the old one. - * @param timeouts timeouts time until the callback is fired - * @param callback callback the callback - * @param handle handle the handle that is created for the timer is returned. Can be used to remove the timer - * @param userData pointer always passed with the call - * @return E_OK in case of success - */ - - am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, IAmShTimerCallBack* callback, sh_timerHandle_t& handle, void * userData, const bool repeats) - { - assert(callback!=NULL); +/** + * adds a timer to the list of timers. The callback will be fired when the timer is up. + * This is not a high precise timer, it is very coarse. It is meant to be used for timeouts when waiting + * for an answer via a filedescriptor. + * One time timer. If you need again a timer, you need to add a new timer in the callback of the old one. + * @param timeouts timeouts time until the callback is fired + * @param callback callback the callback + * @param handle handle the handle that is created for the timer is returned. Can be used to remove the timer + * @param userData pointer always passed with the call + * @return E_OK in case of success + */ + +am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, IAmShTimerCallBack* callback, sh_timerHandle_t& handle, void * userData, const bool repeats) +{ + assert(callback!=NULL); - std::function callbackFunc; - callbackFunc = std::bind(&IAmShTimerCallBack::Call, callback, std::placeholders::_1, std::placeholders::_2); + std::function callbackFunc; + callbackFunc = std::bind(&IAmShTimerCallBack::Call, callback, std::placeholders::_1, std::placeholders::_2); - return addTimer(timeouts, callbackFunc, handle, userData, repeats); - } + return addTimer(timeouts, callbackFunc, handle, userData, repeats); +} - am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, std::function callback, sh_timerHandle_t& handle, void * userData, const bool repeats) - { - assert(!((timeouts.tv_sec == 0) && (timeouts.tv_nsec == 0))); +am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, std::function callback, sh_timerHandle_t& handle, void * userData, const bool repeats) +{ + assert(!((timeouts.tv_sec == 0) && (timeouts.tv_nsec == 0))); - mListTimer.emplace_back(); - sh_timer_s & timerItem = mListTimer.back(); + mListTimer.emplace_back(); + sh_timer_s & timerItem = mListTimer.back(); #ifndef WITH_TIMERFD - //create a new handle for the timer - if (!nextHandle(mSetTimerKeys)) - { - logError("Could not create new timers, too many open!"); - mListTimer.pop_back(); - return (E_NOT_POSSIBLE); - } - //create a new handle for the timer - handle = mSetTimerKeys.lastUsedID; + //create a new handle for the timer + if (!nextHandle(mSetTimerKeys)) + { + logError("Could not create new timers, too many open!"); + mListTimer.pop_back(); + return (E_NOT_POSSIBLE); + } + //create a new handle for the timer + handle = mSetTimerKeys.lastUsedID; - timerItem.countdown = timeouts; - timerItem.callback = callback; - timerItem.userData = userData; + timerItem.countdown = timeouts; + timerItem.callback = callback; + timerItem.userData = userData; - timerItem.handle = handle; + timerItem.handle = handle; - //we add here the time difference between startTime and currenttime, because this time will be substracted later on in timecorrection - timespec currentTime; - clock_gettime(CLOCK_MONOTONIC, ¤tTime); - if (!mDispatchDone)//the mainloop is started - timerItem.countdown = timespecAdd(timeouts, timespecSub(currentTime, mStartTime)); - mListTimer.push_back(timerItem); - mListActiveTimer.push_back(timerItem); - mListActiveTimer.sort(compareCountdown); - return (E_OK); + //we add here the time difference between startTime and currenttime, because this time will be substracted later on in timecorrection + timespec currentTime; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + if (!mDispatchDone)//the mainloop is started + timerItem.countdown = timespecAdd(timeouts, timespecSub(currentTime, mStartTime)); + mListTimer.push_back(timerItem); + mListActiveTimer.push_back(timerItem); + mListActiveTimer.sort(compareCountdown); + return (E_OK); #else - timerItem.countdown.it_value = timeouts; - if (repeats) - timerItem.countdown.it_interval = timeouts; - else - { - timespec zero; - zero.tv_sec = 0; - zero.tv_nsec = 0; - timerItem.countdown.it_interval = zero; - } - - timerItem.fd = -1; - timerItem.userData = userData; - am_Error_e err = createTimeFD(timerItem.countdown, timerItem.fd); - if (err != E_OK) - { - mListTimer.pop_back(); - return err; - } + timerItem.countdown.it_value = timeouts; + if (repeats) + timerItem.countdown.it_interval = timeouts; + else + { + timespec zero; + zero.tv_sec = 0; + zero.tv_nsec = 0; + timerItem.countdown.it_interval = zero; + } - static auto actionPoll = [](const pollfd pollfd, const sh_pollHandle_t handle, void* userData) - { - uint64_t mExpirations; - if (read(pollfd.fd, &mExpirations, sizeof(uint64_t)) == -1) - { - //error received...try again - read(pollfd.fd, &mExpirations, sizeof(uint64_t)); - } - }; + timerItem.fd = -1; + timerItem.userData = userData; + am_Error_e err = createTimeFD(timerItem.countdown, timerItem.fd); + if (err != E_OK) + { + mListTimer.pop_back(); + return err; + } - err = addFDPoll(timerItem.fd, POLLIN, NULL, actionPoll, [callback](const sh_pollHandle_t handle, void* userData)->bool - { - callback(handle, userData); - return false; - }, - NULL, userData, handle); - if (E_OK == err) - { - timerItem.handle = handle; - } - else + static auto actionPoll = [](const pollfd pollfd, const sh_pollHandle_t handle, void* userData) + { + uint64_t mExpirations; + if (read(pollfd.fd, &mExpirations, sizeof(uint64_t)) == -1) { - mListTimer.pop_back(); + //error received...try again + read(pollfd.fd, &mExpirations, sizeof(uint64_t)); } - return err; -#endif + }; + err = addFDPoll(timerItem.fd, POLLIN, NULL, actionPoll, [callback](const sh_pollHandle_t handle, void* userData)->bool + { + callback(handle, userData); + return false; + }, + NULL, userData, handle); + if (E_OK == err) + { + timerItem.handle = handle; } - - /** - * removes a timer from the list of timers - * @param handle the handle to the timer - * @return E_OK in case of success, E_UNKNOWN if timer was not found. - */ - am_Error_e CAmSocketHandler::removeTimer(const sh_timerHandle_t handle) + else { - assert(handle != 0); + mListTimer.pop_back(); + } + return err; +#endif - //stop the current timer +} + +/** + * removes a timer from the list of timers + * @param handle the handle to the timer + * @return E_OK in case of success, E_UNKNOWN if timer was not found. + */ +am_Error_e CAmSocketHandler::removeTimer(const sh_timerHandle_t handle) +{ + assert(handle != 0); + + //stop the current timer #ifdef WITH_TIMERFD - std::list::iterator it = mListTimer.begin(); - for (; it != mListTimer.end(); ++it) - { - if (it->handle == handle) - break; - } - if (it == mListTimer.end()) - return (E_NON_EXISTENT); + std::list::iterator it = mListTimer.begin(); + for (; it != mListTimer.end(); ++it) + { + if (it->handle == handle) + break; + } + if (it == mListTimer.end()) + return (E_NON_EXISTENT); - close(it->fd); - mListTimer.erase(it); - return removeFDPoll(handle); + close(it->fd); + mListTimer.erase(it); + return removeFDPoll(handle); #else - stopTimer(handle); - std::list::iterator it(mListTimer.begin()); - for (; it != mListTimer.end(); ++it) + stopTimer(handle); + std::list::iterator it(mListTimer.begin()); + for (; it != mListTimer.end(); ++it) + { + if (it->handle == handle) { - if (it->handle == handle) - { - it = mListTimer.erase(it); - mSetTimerKeys.pollHandles.erase(handle); - return (E_OK); - } + it = mListTimer.erase(it); + mSetTimerKeys.pollHandles.erase(handle); + return (E_OK); } - return (E_UNKNOWN); -#endif } + return (E_UNKNOWN); +#endif +} - /** - * restarts a timer and updates with a new interva - * @param handle handle to the timer - * @param timeouts new timout time - * @return E_OK on success, E_NON_EXISTENT if the handle was not found - */ - am_Error_e CAmSocketHandler::updateTimer(const sh_timerHandle_t handle, const timespec & timeouts) - { +/** + * restarts a timer and updates with a new interva + * @param handle handle to the timer + * @param timeouts new timout time + * @return E_OK on success, E_NON_EXISTENT if the handle was not found + */ +am_Error_e CAmSocketHandler::updateTimer(const sh_timerHandle_t handle, const timespec & timeouts) +{ #ifdef WITH_TIMERFD - std::list::iterator it = mListTimer.begin(); - for (; it != mListTimer.end(); ++it) - { - if (it->handle == handle) - break; - } - if (it == mListTimer.end()) - return (E_NON_EXISTENT); + std::list::iterator it = mListTimer.begin(); + for (; it != mListTimer.end(); ++it) + { + if (it->handle == handle) + break; + } + if (it == mListTimer.end()) + return (E_NON_EXISTENT); - if (it->countdown.it_interval.tv_nsec != 0 || it->countdown.it_interval.tv_sec != 0) - it->countdown.it_interval = timeouts; - it->countdown.it_value = timeouts; + if (it->countdown.it_interval.tv_nsec != 0 || it->countdown.it_interval.tv_sec != 0) + it->countdown.it_interval = timeouts; + it->countdown.it_value = timeouts; - if (!fdIsValid(it->fd)) - { - am_Error_e err = createTimeFD(it->countdown, it->fd); - if (err != E_OK) - return err; - } - else + if (!fdIsValid(it->fd)) + { + am_Error_e err = createTimeFD(it->countdown, it->fd); + if (err != E_OK) + return err; + } + else + { + if (timerfd_settime(it->fd, 0, &it->countdown, NULL)) { - if (timerfd_settime(it->fd, 0, &it->countdown, NULL)) - { - logError("Failed to set timer duration"); - return E_NOT_POSSIBLE; - } + logError("Failed to set timer duration"); + return E_NOT_POSSIBLE; } + } #else - //update the mList .... - sh_timer_s timerItem; - std::list::iterator it(mListTimer.begin()), activeIt(mListActiveTimer.begin()); - bool found(false); - for (; it != mListTimer.end(); ++it) + //update the mList .... + sh_timer_s timerItem; + std::list::iterator it(mListTimer.begin()), activeIt(mListActiveTimer.begin()); + bool found(false); + for (; it != mListTimer.end(); ++it) + { + if (it->handle == handle) { - if (it->handle == handle) - { - it->countdown = timeouts; - timerItem = *it; - found = true; - break; - } + it->countdown = timeouts; + timerItem = *it; + found = true; + break; } - if (!found) - return (E_NON_EXISTENT); + } + if (!found) + return (E_NON_EXISTENT); - found = false; + found = false; - //we add here the time difference between startTime and currenttime, because this time will be substracted later on in timecorrection - timespec currentTime, timeoutsCorrected; - currentTime.tv_nsec=timeoutsCorrected.tv_nsec=0; - currentTime.tv_sec=timeoutsCorrected.tv_sec=0; - clock_gettime(CLOCK_MONOTONIC, ¤tTime); - if (!mDispatchDone)//the mainloop is started - timeoutsCorrected = timespecAdd(timeouts, timespecSub(currentTime, mStartTime)); + //we add here the time difference between startTime and currenttime, because this time will be substracted later on in timecorrection + timespec currentTime, timeoutsCorrected; + currentTime.tv_nsec=timeoutsCorrected.tv_nsec=0; + currentTime.tv_sec=timeoutsCorrected.tv_sec=0; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + if (!mDispatchDone)//the mainloop is started + timeoutsCorrected = timespecAdd(timeouts, timespecSub(currentTime, mStartTime)); - for (; activeIt != mListActiveTimer.end(); ++activeIt) + for (; activeIt != mListActiveTimer.end(); ++activeIt) + { + if (activeIt->handle == handle) { - if (activeIt->handle == handle) - { - activeIt->countdown = timeoutsCorrected; - found = true; - break; - } + activeIt->countdown = timeoutsCorrected; + found = true; + break; } + } - if (!found) - timerItem.countdown = timeoutsCorrected; - mListActiveTimer.push_back(timerItem); + if (!found) + timerItem.countdown = timeoutsCorrected; + mListActiveTimer.push_back(timerItem); - mListActiveTimer.sort(compareCountdown); + mListActiveTimer.sort(compareCountdown); #endif - return (E_OK); - } + return (E_OK); +} - /** - * restarts a timer with the original value - * @param handle - * @return E_OK on success, E_NON_EXISTENT if the handle was not found - */ - am_Error_e CAmSocketHandler::restartTimer(const sh_timerHandle_t handle) - { +/** + * restarts a timer with the original value + * @param handle + * @return E_OK on success, E_NON_EXISTENT if the handle was not found + */ +am_Error_e CAmSocketHandler::restartTimer(const sh_timerHandle_t handle) +{ #ifdef WITH_TIMERFD - std::list::iterator it = mListTimer.begin(); - for (; it != mListTimer.end(); ++it) - { - if (it->handle == handle) - break; - } - if (it == mListTimer.end()) - return (E_NON_EXISTENT); + std::list::iterator it = mListTimer.begin(); + for (; it != mListTimer.end(); ++it) + { + if (it->handle == handle) + break; + } + if (it == mListTimer.end()) + return (E_NON_EXISTENT); - if (!fdIsValid(it->fd)) - { - am_Error_e err = createTimeFD(it->countdown, it->fd); - if (err != E_OK) - return err; - } - else + if (!fdIsValid(it->fd)) + { + am_Error_e err = createTimeFD(it->countdown, it->fd); + if (err != E_OK) + return err; + } + else + { + if (timerfd_settime(it->fd, 0, &it->countdown, NULL)) { - if (timerfd_settime(it->fd, 0, &it->countdown, NULL)) - { - logError("Failed to set timer duration"); - return E_NOT_POSSIBLE; - } + logError("Failed to set timer duration"); + return E_NOT_POSSIBLE; } + } #else - sh_timer_s timerItem; //!::iterator it(mListTimer.begin()), activeIt(mListActiveTimer.begin()); - bool found(false); - for (; it != mListTimer.end(); ++it) + sh_timer_s timerItem; //!::iterator it(mListTimer.begin()), activeIt(mListActiveTimer.begin()); + bool found(false); + for (; it != mListTimer.end(); ++it) + { + if (it->handle == handle) { - if (it->handle == handle) - { - timerItem = *it; - found = true; - break; - } + timerItem = *it; + found = true; + break; } - if (!found) - return (E_NON_EXISTENT); + } + if (!found) + return (E_NON_EXISTENT); - found = false; + found = false; - //we add here the time difference between startTime and currenttime, because this time will be substracted later on in timecorrection - timespec currentTime, timeoutsCorrected; - clock_gettime(CLOCK_MONOTONIC, ¤tTime); - if (!mDispatchDone)//the mainloop is started - { - timeoutsCorrected = timespecAdd(timerItem.countdown, timespecSub(currentTime, mStartTime)); - timerItem.countdown = timeoutsCorrected; - } + //we add here the time difference between startTime and currenttime, because this time will be substracted later on in timecorrection + timespec currentTime, timeoutsCorrected; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + if (!mDispatchDone)//the mainloop is started + { + timeoutsCorrected = timespecAdd(timerItem.countdown, timespecSub(currentTime, mStartTime)); + timerItem.countdown = timeoutsCorrected; + } - for (; activeIt != mListActiveTimer.end(); ++activeIt) + for (; activeIt != mListActiveTimer.end(); ++activeIt) + { + if (activeIt->handle == handle) { - if (activeIt->handle == handle) - { - activeIt->countdown = timerItem.countdown; - found = true; - break; - } + activeIt->countdown = timerItem.countdown; + found = true; + break; } + } - if (!found) - mListActiveTimer.push_back(timerItem); + if (!found) + mListActiveTimer.push_back(timerItem); - mListActiveTimer.sort(compareCountdown); + mListActiveTimer.sort(compareCountdown); #endif - return (E_OK); - } + return (E_OK); +} - /** - * stops a timer - * @param handle - * @return E_OK on success, E_NON_EXISTENT if the handle was not found - */ - am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) - { +/** + * stops a timer + * @param handle + * @return E_OK on success, E_NON_EXISTENT if the handle was not found + */ +am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) +{ #ifdef WITH_TIMERFD - std::list::iterator it = mListTimer.begin(); - for (; it != mListTimer.end(); ++it) - { - if (it->handle == handle) - break; - } - if (it == mListTimer.end()) - return (E_NON_EXISTENT); + std::list::iterator it = mListTimer.begin(); + for (; it != mListTimer.end(); ++it) + { + if (it->handle == handle) + break; + } + if (it == mListTimer.end()) + return (E_NON_EXISTENT); - itimerspec countdown = it->countdown; - countdown.it_value.tv_nsec = 0; - countdown.it_value.tv_sec = 0; + itimerspec countdown = it->countdown; + countdown.it_value.tv_nsec = 0; + countdown.it_value.tv_sec = 0; - if (timerfd_settime(it->fd, 0, &countdown, NULL)) - { - logError("Failed to set timer duration"); - return E_NOT_POSSIBLE; - } - return (E_OK); + if (timerfd_settime(it->fd, 0, &countdown, NULL)) + { + logError("Failed to set timer duration"); + return E_NOT_POSSIBLE; + } + return (E_OK); #else - //go through the list and remove the timer with the handle - std::list::iterator it(mListActiveTimer.begin()); - for (; it != mListActiveTimer.end(); ++it) + //go through the list and remove the timer with the handle + std::list::iterator it(mListActiveTimer.begin()); + for (; it != mListActiveTimer.end(); ++it) + { + if (it->handle == handle) { - if (it->handle == handle) - { - it = mListActiveTimer.erase(it); - return (E_OK); - } + it = mListActiveTimer.erase(it); + return (E_OK); } - return (E_NON_EXISTENT); -#endif } + return (E_NON_EXISTENT); +#endif +} - /** - * updates the eventFlags of a poll - * @param handle - * @param events - * @return @return E_OK on succsess, E_NON_EXISTENT if fd was not found - */ - am_Error_e CAmSocketHandler::updateEventFlags(const sh_pollHandle_t handle, const short events) - { - VectorListPoll_t::iterator iterator = mListPoll.begin(); +/** + * updates the eventFlags of a poll + * @param handle + * @param events + * @return @return E_OK on succsess, E_NON_EXISTENT if fd was not found + */ +am_Error_e CAmSocketHandler::updateEventFlags(const sh_pollHandle_t handle, const short events) +{ + VectorListPoll_t::iterator iterator = mListPoll.begin(); - for (; iterator != mListPoll.end(); ++iterator) + for (; iterator != mListPoll.end(); ++iterator) + { + if (iterator->handle == handle) { - if (iterator->handle == handle) - { - iterator->pollfdValue.events = events; - mRecreatePollfds = true; - return (E_OK); - } + iterator->pollfdValue.events = events; + mRecreatePollfds = true; + return (E_OK); } - return (E_UNKNOWN); } + return (E_UNKNOWN); +} - /** - * checks if a filedescriptor is validCAmShSubstractTime - * @param fd the filedescriptor - * @return true if the fd is valid - */ - bool CAmSocketHandler::fdIsValid(const int fd) const - { - return (fcntl(fd, F_GETFL) != -1 || errno != EBADF); - } +/** + * checks if a filedescriptor is validCAmShSubstractTime + * @param fd the filedescriptor + * @return true if the fd is valid + */ +bool CAmSocketHandler::fdIsValid(const int fd) const +{ + return (fcntl(fd, F_GETFL) != -1 || errno != EBADF); +} #ifndef WITH_TIMERFD - /** - * timer is up. - */ - void CAmSocketHandler::timerUp() +/** + * timer is up. + */ +void CAmSocketHandler::timerUp() +{ + //find out the timedifference to starttime + static timespec currentTime, diffTime; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + diffTime = timespecSub(currentTime, mStartTime); + + static auto countdownUp = [&](const sh_timer_s& row)->bool { - //find out the timedifference to starttime - static timespec currentTime, diffTime; - clock_gettime(CLOCK_MONOTONIC, ¤tTime); - diffTime = timespecSub(currentTime, mStartTime); + timespec sub = timespecSub(row.countdown, diffTime); + if (sub.tv_nsec == 0 && sub.tv_sec == 0) + return (true); + return (false); + }; - static auto countdownUp = [&](const sh_timer_s& row)->bool - { - timespec sub = timespecSub(row.countdown, diffTime); - if (sub.tv_nsec == 0 && sub.tv_sec == 0) - return (true); - return (false); - }; + //now we need to substract the diffTime from all timers and see if they are up + std::list::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), countdownUp); - //now we need to substract the diffTime from all timers and see if they are up - std::list::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), countdownUp); + //copy all fired timers into a list + std::vector tempList(overflowIter, mListActiveTimer.rend()); - //copy all fired timers into a list - std::vector tempList(overflowIter, mListActiveTimer.rend()); + //erase all fired timers + std::list::iterator it(overflowIter.base()); + mListActiveTimer.erase(mListActiveTimer.begin(), it); - //erase all fired timers - std::list::iterator it(overflowIter.base()); - mListActiveTimer.erase(mListActiveTimer.begin(), it); + //call the callbacks for the timers + std::for_each(tempList.begin(), tempList.end(), CAmSocketHandler::callTimer); +} - //call the callbacks for the timers - std::for_each(tempList.begin(), tempList.end(), CAmSocketHandler::callTimer); - } +/** + * correct timers and fire the ones who are up + */ +void CAmSocketHandler::timerCorrection() +{ + //get the current time and calculate the correction value + static timespec currentTime, correctionTime; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + correctionTime = timespecSub(currentTime, mStartTime); + mStartTime = currentTime; - /** - * correct timers and fire the ones who are up - */ - void CAmSocketHandler::timerCorrection() + static auto countdownZero = [](const sh_timer_s& row)->bool { - //get the current time and calculate the correction value - static timespec currentTime, correctionTime; - clock_gettime(CLOCK_MONOTONIC, ¤tTime); - correctionTime = timespecSub(currentTime, mStartTime); - mStartTime = currentTime; - - static auto countdownZero = [](const sh_timer_s& row)->bool - { - if (row.countdown.tv_nsec == 0 && row.countdown.tv_sec == 0) - return (true); - return (false); - }; + if (row.countdown.tv_nsec == 0 && row.countdown.tv_sec == 0) + return (true); + return (false); + }; - static auto substractTime = [&](sh_timer_s& t) - { - t.countdown = timespecSub(t.countdown, correctionTime); - }; + static auto substractTime = [&](sh_timer_s& t) + { + t.countdown = timespecSub(t.countdown, correctionTime); + }; - if (!mListActiveTimer.empty()) - { + if (!mListActiveTimer.empty()) + { - //subtract the correction value from all items in the list - std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), substractTime); + //subtract the correction value from all items in the list + std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), substractTime); - //find the last occurrence of zero -> timer overflowed - std::list::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), countdownZero); + //find the last occurrence of zero -> timer overflowed + std::list::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), countdownZero); - //only if a timer overflowed - if (overflowIter != mListActiveTimer.rend()) - { - //copy all timers that need to be called to a new list - std::vector tempList(overflowIter, mListActiveTimer.rend()); + //only if a timer overflowed + if (overflowIter != mListActiveTimer.rend()) + { + //copy all timers that need to be called to a new list + std::vector tempList(overflowIter, mListActiveTimer.rend()); - //erase all fired timers - std::list::iterator it(overflowIter.base()); - mListActiveTimer.erase(mListActiveTimer.begin(), it); + //erase all fired timers + std::list::iterator it(overflowIter.base()); + mListActiveTimer.erase(mListActiveTimer.begin(), it); - //call the callbacks for the timers - std::for_each(tempList.begin(), tempList.end(), CAmSocketHandler::callTimer); - } + //call the callbacks for the timers + std::for_each(tempList.begin(), tempList.end(), CAmSocketHandler::callTimer); } } +} #endif - /** - * prepare for poll - */ - void CAmSocketHandler::prepare(am::CAmSocketHandler::sh_poll_s& row) - { - if (row.prepareCB) - { - try - { - row.prepareCB(row.handle, row.userData); - } catch (std::exception& e) - { - logError("Sockethandler: Exception in Preparecallback,caught", e.what()); - } - } - } - - /** - * fire callback - */ - void CAmSocketHandler::fire(sh_poll_s& a) +/** + * prepare for poll + */ +void CAmSocketHandler::prepare(am::CAmSocketHandler::sh_poll_s& row) +{ + if (row.prepareCB) { try { - a.firedCB(a.pollfdValue, a.handle, a.userData); + row.prepareCB(row.handle, row.userData); } catch (std::exception& e) { logError("Sockethandler: Exception in Preparecallback,caught", e.what()); } } +} - /** - * should disptach - */ - bool CAmSocketHandler::noDispatching(const sh_poll_s& a) +/** + * fire callback + */ +void CAmSocketHandler::fire(sh_poll_s& a) +{ + try { - //remove from list of there is no checkCB - if (nullptr == a.checkCB) - return (true); - return (!a.checkCB(a.handle, a.userData)); - } - - /** - * disptach - */ - bool CAmSocketHandler::dispatchingFinished(const sh_poll_s& a) + a.firedCB(a.pollfdValue, a.handle, a.userData); + } catch (std::exception& e) { - //remove from list of there is no dispatchCB - if (nullptr == a.dispatchCB) - return (true); - return (!a.dispatchCB(a.handle, a.userData)); + logError("Sockethandler: Exception in Preparecallback,caught", e.what()); } +} - /** - * event triggered - */ - bool CAmSocketHandler::eventFired(const pollfd& a) - { - return (a.revents == 0 ? false : true); - } +/** + * should disptach + */ +bool CAmSocketHandler::noDispatching(const sh_poll_s& a) +{ + //remove from list of there is no checkCB + if (nullptr == a.checkCB) + return (true); + return (!a.checkCB(a.handle, a.userData)); +} - /** - * is used to set the pointer for the ppoll command - * @param buffertime - * @return - */ - inline timespec* CAmSocketHandler::insertTime(timespec& buffertime) - { +/** + * disptach + */ +bool CAmSocketHandler::dispatchingFinished(const sh_poll_s& a) +{ + //remove from list of there is no dispatchCB + if (nullptr == a.dispatchCB) + return (true); + return (!a.dispatchCB(a.handle, a.userData)); +} + +/** + * event triggered + */ +bool CAmSocketHandler::eventFired(const pollfd& a) +{ + return (a.revents == 0 ? false : true); +} + +/** + * is used to set the pointer for the ppoll command + * @param buffertime + * @return + */ +inline timespec* CAmSocketHandler::insertTime(timespec& buffertime) +{ #ifndef WITH_TIMERFD - if (!mListActiveTimer.empty()) - { - buffertime = mListActiveTimer.front().countdown; - return (&buffertime); - } - else + if (!mListActiveTimer.empty()) + { + buffertime = mListActiveTimer.front().countdown; + return (&buffertime); + } + else #endif - { - return (NULL); - } + { + return (NULL); } +} #ifdef WITH_TIMERFD - am_Error_e CAmSocketHandler::createTimeFD(const itimerspec & timeouts, int & fd) +am_Error_e CAmSocketHandler::createTimeFD(const itimerspec & timeouts, int & fd) +{ + fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); + if (fd <= 0) { - fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); - if (fd <= 0) - { - logError("Failed to create timer"); - return E_NOT_POSSIBLE; - } + logError("Failed to create timer"); + return E_NOT_POSSIBLE; + } - if (timerfd_settime(fd, 0, &timeouts, NULL)) - { - logError("Failed to set timer duration"); - return E_NOT_POSSIBLE; - } - return E_OK; + if (timerfd_settime(fd, 0, &timeouts, NULL)) + { + logError("Failed to set timer duration"); + return E_NOT_POSSIBLE; } + return E_OK; +} #endif - void CAmSocketHandler::callTimer(sh_timer_s& a) +void CAmSocketHandler::callTimer(sh_timer_s& a) +{ + try { - try - { - a.callback(a.handle, a.userData); - } catch (std::exception& e) - { - logError("Sockethandler: Exception in Timercallback,caught", e.what()); - } + a.callback(a.handle, a.userData); + } catch (std::exception& e) + { + logError("Sockethandler: Exception in Timercallback,caught", e.what()); } +} - bool CAmSocketHandler::nextHandle(sh_identifier_s & handle) +bool CAmSocketHandler::nextHandle(sh_identifier_s & handle) +{ + //create a new handle for the poll + const sh_pollHandle_t lastHandle(handle.lastUsedID); + do { - //create a new handle for the poll - const sh_pollHandle_t lastHandle(handle.lastUsedID); - do + ++handle.lastUsedID; + if (handle.lastUsedID == handle.limit) { - ++handle.lastUsedID; - if (handle.lastUsedID == handle.limit) - { - handle.lastUsedID = 1; - } - if (handle.lastUsedID == lastHandle) - { - logError("Could not create new polls, too many open!"); - return (false); - } + handle.lastUsedID = 1; + } + if (handle.lastUsedID == lastHandle) + { + logError("Could not create new polls, too many open!"); + return (false); + } - } while (handle.pollHandles.find(handle.lastUsedID) != handle.pollHandles.end()); + } while (handle.pollHandles.find(handle.lastUsedID) != handle.pollHandles.end()); - handle.pollHandles.insert(handle.lastUsedID); + handle.pollHandles.insert(handle.lastUsedID); - return (true); - } + return (true); +} } diff --git a/AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt b/AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt index 3e89267..e0d2287 100644 --- a/AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt +++ b/AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt @@ -33,6 +33,7 @@ ADD_EXECUTABLE(AmSerializerTest ${Socket_SRCS_CXX}) TARGET_LINK_LIBRARIES(AmSerializerTest ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} AudioManagerUtilities ) diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index af21f90..ecd38fe 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -48,6 +48,22 @@ static const char * TEST_SOCKET_DATA_FINAL = "finish!"; static const std::chrono::time_point TP_ZERO; + +MockIAmSignalHandler *pMockSignalHandler = NULL; +static void signalHandler(int sig, siginfo_t *siginfo, void *context) +{ + (void) sig; + (void) siginfo; + (void) context; + + if(pMockSignalHandler!=NULL) + pMockSignalHandler->signalHandler(sig, siginfo, context); + +#ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT + std::cout<<"signal handler was called with signal " << sig << std::endl; +#endif +} + CAmSocketHandlerTest::CAmSocketHandlerTest() { } @@ -227,7 +243,7 @@ TEST(CAmSocketHandlerTest, timersOneshot) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 1); #else - ASSERT_EQ(handle, 3); + ASSERT_EQ(handle, 2); #endif EXPECT_CALL(testCallback1,timerCallback(handle,&userData)).Times(1); @@ -240,7 +256,7 @@ TEST(CAmSocketHandlerTest, timersOneshot) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 2); #else - ASSERT_EQ(handle, 4); + ASSERT_EQ(handle, 3); #endif EXPECT_CALL(testCallback4,timerCallback(handle,NULL)).Times(1); myHandler.start_listenting(); @@ -269,7 +285,7 @@ TEST(CAmSocketHandlerTest, timersStop) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 1); #else - ASSERT_EQ(handle, 3); + ASSERT_EQ(handle, 2); #endif EXPECT_CALL(testCallback1,timerCallback(handle,&userData)).Times(4); @@ -282,7 +298,7 @@ TEST(CAmSocketHandlerTest, timersStop) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 2); #else - ASSERT_EQ(handle, 4); + ASSERT_EQ(handle, 3); #endif EXPECT_CALL(testCallback4,timerCallback(handle,NULL)).Times(1); myHandler.start_listenting(); @@ -312,7 +328,7 @@ TEST(CAmSocketHandlerTest, timersGeneral) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 1); #else - ASSERT_EQ(handle, 3); + ASSERT_EQ(handle, 2); #endif EXPECT_CALL(testCallback1,timerCallback(handle,&userData)).Times(4); //+1 because of measurment @@ -325,7 +341,7 @@ TEST(CAmSocketHandlerTest, timersGeneral) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 2); #else - ASSERT_EQ(handle, 4); + ASSERT_EQ(handle, 3); #endif EXPECT_CALL(testCallback4,timerCallback(handle,NULL)).Times(1); myHandler.start_listenting(); @@ -356,7 +372,7 @@ TEST(CAmSocketHandlerTest,playWithTimers) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 1); #else - ASSERT_EQ(handle, 3); + ASSERT_EQ(handle, 2); #endif EXPECT_CALL(testCallback1,timerCallback(handle,NULL)).Times(AnyNumber()); @@ -364,7 +380,7 @@ TEST(CAmSocketHandlerTest,playWithTimers) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 2); #else - ASSERT_EQ(handle, 4); + ASSERT_EQ(handle, 3); #endif EXPECT_CALL(testCallback2,timerCallback(handle,NULL)).Times(AnyNumber()); @@ -372,7 +388,7 @@ TEST(CAmSocketHandlerTest,playWithTimers) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 3); #else - ASSERT_EQ(handle, 5); + ASSERT_EQ(handle, 4); #endif EXPECT_CALL(testCallback3,timerCallback(handle,NULL)).Times(2); //+1 because of measurment @@ -380,64 +396,82 @@ TEST(CAmSocketHandlerTest,playWithTimers) #ifndef WITH_TIMERFD ASSERT_EQ(handle, 4); #else - ASSERT_EQ(handle, 6); + ASSERT_EQ(handle, 5); #endif EXPECT_CALL(testCallback4,timerCallback(handle,NULL)).Times(1); myHandler.start_listenting(); } -TEST(CAmSocketHandlerTest, signalHandler) + + +TEST(CAmSocketHandlerTest, signalHandlerPrimaryPlusSecondary) { + pMockSignalHandler = new MockIAmSignalHandler; CAmSocketHandler myHandler; ASSERT_FALSE(myHandler.fatalErrorOccurred()); + ASSERT_TRUE(myHandler.listenToSignals({SIGHUP})==E_OK); + ASSERT_TRUE(myHandler.listenToSignals({SIGHUP, SIGTERM, SIGCHLD})==E_OK); sh_pollHandle_t signalHandler1, signalHandler2; - MockIAmSignalHandler mock; + std::string userData = "User data"; - myHandler.addSignalHandler([&](const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData) - { - unsigned sig = info.ssi_signo; - mock.signalHandlerAction(handle, sig, userData); + +// critical signals are registered here: + struct sigaction signalAction; + memset(&signalAction, '\0', sizeof(signalAction)); + signalAction.sa_sigaction = &signalHandler; + signalAction.sa_flags = SA_RESETHAND | SA_NODEFER| SA_SIGINFO; + sigaction(SIGINT, &signalAction, NULL); + sigaction(SIGQUIT, &signalAction, NULL); + + myHandler.addSignalHandler([&](const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData) + { + unsigned sig = info.ssi_signo; + pMockSignalHandler->signalHandlerAction(handle, sig, userData); #ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT - unsigned user = info.ssi_uid; - std::cout<<"signal handler was called from user "<< user << " with signal " << sig << std::endl; + unsigned user = info.ssi_uid; + std::cout<<"signal handler was called from user "<< user << " with signal " << sig << std::endl; #endif - }, signalHandler1, &userData); - ASSERT_EQ(signalHandler1, 1); - myHandler.addSignalHandler([&](const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData) - { - unsigned sig = info.ssi_signo; - mock.signalHandlerAction(handle, sig, userData); - #ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT - unsigned user = info.ssi_uid; - std::cout<<"signal handler was called from user "<< user << " with signal " << sig << std::endl; - #endif - }, signalHandler2, &userData); - ASSERT_EQ(signalHandler2, 2); + }, signalHandler1, &userData); + ASSERT_EQ(signalHandler1, 1); + myHandler.addSignalHandler([&](const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData) + { + unsigned sig = info.ssi_signo; + pMockSignalHandler->signalHandlerAction(handle, sig, userData); +#ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT + unsigned user = info.ssi_uid; + std::cout<<"signal handler was called from user "<< user << " with signal " << sig << std::endl; +#endif + }, signalHandler2, &userData); + ASSERT_EQ(signalHandler2, 2); timespec timeout4; timeout4.tv_nsec = 200000000; timeout4.tv_sec = 0; - std::set signals; - signals.insert(SIGHUP); - signals.insert(SIGINT); - signals.insert(SIGTERM); - signals.insert(SIGQUIT); + std::set secondarySignals; + secondarySignals.insert({SIGHUP,SIGTERM, SIGCHLD}); + std::set primarySignals({SIGQUIT,SIGINT}); + std::set signals(primarySignals); + signals.insert(secondarySignals.begin(), secondarySignals.end()); CAmTimerSignalHandler testCallback4(&myHandler, timeout4, signals); sh_timerHandle_t handle; myHandler.addTimer(timeout4, &testCallback4.pTimerCallback, handle, NULL, true); #ifndef WITH_TIMERFD - ASSERT_EQ(handle, 1); + ASSERT_EQ(handle, 1); #else - ASSERT_EQ(handle, 3); + ASSERT_EQ(handle, 3); #endif EXPECT_CALL(testCallback4,timerCallback(handle,NULL)).Times(signals.size()+1); - for(auto it: signals) - EXPECT_CALL(mock,signalHandlerAction(signalHandler1,it,&userData)).Times(1); - for(auto it: signals) - EXPECT_CALL(mock,signalHandlerAction(signalHandler2,it,&userData)).Times(1); + for(auto it: secondarySignals) + EXPECT_CALL(*pMockSignalHandler,signalHandlerAction(signalHandler1,it,&userData)).Times(1); + for(auto it: secondarySignals) + EXPECT_CALL(*pMockSignalHandler,signalHandlerAction(signalHandler2,it,&userData)).Times(1); + for(auto it: primarySignals) + EXPECT_CALL(*pMockSignalHandler,signalHandler(it,_,_)).Times(1); + myHandler.start_listenting(); + delete pMockSignalHandler; } TEST(CAmSocketHandlerTest,playWithUNIXSockets) diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h index d38f8c1..ba2bf51 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h @@ -54,6 +54,7 @@ namespace am { } virtual void signalHandlerAction(const sh_pollHandle_t handle, const unsigned sig, void* userData)=0; + virtual void signalHandler(int sig, siginfo_t *siginfo, void *context)=0; }; class IAmSocketHandlerCb @@ -78,6 +79,7 @@ namespace am { public: MOCK_METHOD3(signalHandlerAction, void (const sh_pollHandle_t handle, const unsigned sig, void* userData)); + MOCK_METHOD3(signalHandler, void(int sig, siginfo_t *siginfo, void *context)); }; class MockSocketHandlerCb: public IAmSocketHandlerCb diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CMakeLists.txt b/AudioManagerUtilities/test/AmSocketHandlerTest/CMakeLists.txt index 8f0c9e6..5e5b9e1 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CMakeLists.txt +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CMakeLists.txt @@ -33,6 +33,7 @@ ADD_EXECUTABLE(AmSocketHandlerTest ${Socket_SRCS_CXX}) TARGET_LINK_LIBRARIES(AmSocketHandlerTest ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} AudioManagerUtilities ) diff --git a/CMakeLists.txt b/CMakeLists.txt index b89daa1..5c70c61 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,6 +141,7 @@ if(WITH_TESTS) #check if we can find the google stuff pkg_check_modules (GTEST "gtest >= 1.6.0") pkg_check_modules (GMOCK "gmock >= 1.6.0") + find_package (Threads) if (NOT("${GTEST_FOUND}" AND "${GMOCK_FOUND}")) message (STATUS "Building and installing with shipped sources") add_subdirectory(googleMock) -- cgit v1.2.1 From e94f414079757ecb946f36fa0caf55524a75d5e7 Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Mon, 25 Sep 2017 17:01:18 +0200 Subject: Timer fd is closed at the beginning of the next iteration + some unit tests. Signed-off-by: Christian Linke Change-Id: I8c5d3c436ac9fad62c76a26145c731b538abb1e7 --- AudioManagerUtilities/include/CAmSocketHandler.h | 11 +- AudioManagerUtilities/src/CAmSocketHandler.cpp | 103 ++++++--- .../test/AmSerializerTest/CAmSerializerTest.cpp | 7 +- .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 229 ++++++++++++++++++++- .../AmSocketHandlerTest/CAmSocketHandlerTest.h | 72 ++++++- 5 files changed, 378 insertions(+), 44 deletions(-) diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h index 717f792..7baa496 100644 --- a/AudioManagerUtilities/include/CAmSocketHandler.h +++ b/AudioManagerUtilities/include/CAmSocketHandler.h @@ -244,10 +244,11 @@ class CAmSocketHandler sh_timer_s() : handle(0) #ifdef WITH_TIMERFD - , fd(0) + , fd(-1) #endif , countdown(), callback(), userData(0) {} + }; struct sh_signal_s @@ -291,7 +292,11 @@ class CAmSocketHandler VectorListPoll_t mListPoll; //! mListTimer; //! mListActiveTimer; //! mListRemovedTimers; +#endif sh_identifier_s mSetSignalhandlerKeys; //!A set of all used signal handler keys VectorSignalHandlers_t mSignalHandlers; bool mRecreatePollfds; //! & listSi * @return E_OK if the descriptor was added, E_NON_EXISTENT if the fd is not valid */ -am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, std::function prepare, - std::function fired, std::function check, - std::function dispatch, void* userData, sh_pollHandle_t& handle) +am_Error_e CAmSocketHandler::addFDPoll(const int fd, + const short event, + std::function prepare, + std::function fired, + std::function check, + std::function dispatch, + void* userData, + sh_pollHandle_t& handle) { if (!fdIsValid(fd)) return (E_NON_EXISTENT); @@ -528,7 +543,6 @@ am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, std::functionbool - { - callback(handle, userData); - return false; - }, - NULL, userData, handle); + err = addFDPoll(timerItem.fd, + POLLIN, + NULL, + actionPoll, + [callback](const sh_pollHandle_t handle, void* userData)->bool{ + callback(handle, userData); + return false; + }, + NULL, + userData, + handle); if (E_OK == err) { timerItem.handle = handle; @@ -603,20 +622,22 @@ am_Error_e CAmSocketHandler::removeTimer(const sh_timerHandle_t handle) if (it == mListTimer.end()) return (E_NON_EXISTENT); - close(it->fd); + mListRemovedTimers.push_back(*it); mListTimer.erase(it); return removeFDPoll(handle); #else stopTimer(handle); std::list::iterator it(mListTimer.begin()); - for (; it != mListTimer.end(); ++it) + while (it != mListTimer.end()) { if (it->handle == handle) { - it = mListTimer.erase(it); + it = mListTimer.erase(it); mSetTimerKeys.pollHandles.erase(handle); return (E_OK); } + else + ++it; } return (E_UNKNOWN); #endif @@ -652,7 +673,7 @@ am_Error_e CAmSocketHandler::updateTimer(const sh_timerHandle_t handle, const ti } else { - if (timerfd_settime(it->fd, 0, &it->countdown, NULL)) + if (timerfd_settime(it->fd, 0, &it->countdown, NULL)<0) { logError("Failed to set timer duration"); return E_NOT_POSSIBLE; @@ -732,7 +753,7 @@ am_Error_e CAmSocketHandler::restartTimer(const sh_timerHandle_t handle) } else { - if (timerfd_settime(it->fd, 0, &it->countdown, NULL)) + if (timerfd_settime(it->fd, 0, &it->countdown, NULL)<0) { logError("Failed to set timer duration"); return E_NOT_POSSIBLE; @@ -806,7 +827,7 @@ am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) countdown.it_value.tv_nsec = 0; countdown.it_value.tv_sec = 0; - if (timerfd_settime(it->fd, 0, &countdown, NULL)) + if (timerfd_settime(it->fd, 0, &countdown, NULL)<0) { logError("Failed to set timer duration"); return E_NOT_POSSIBLE; @@ -815,13 +836,16 @@ am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) #else //go through the list and remove the timer with the handle std::list::iterator it(mListActiveTimer.begin()); - for (; it != mListActiveTimer.end(); ++it) + + while (it != mListActiveTimer.end()) { if (it->handle == handle) { it = mListActiveTimer.erase(it); return (E_OK); } + else + it++; } return (E_NON_EXISTENT); #endif @@ -1026,19 +1050,32 @@ inline timespec* CAmSocketHandler::insertTime(timespec& buffertime) am_Error_e CAmSocketHandler::createTimeFD(const itimerspec & timeouts, int & fd) { fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); - if (fd <= 0) + if (fd < 0) { logError("Failed to create timer"); return E_NOT_POSSIBLE; } - if (timerfd_settime(fd, 0, &timeouts, NULL)) + if (timerfd_settime(fd, 0, &timeouts, NULL) < 0) { logError("Failed to set timer duration"); return E_NOT_POSSIBLE; } return E_OK; } + +void CAmSocketHandler::closeRemovedTimers() +{ + std::list::iterator it(mListRemovedTimers.begin()); + while (it != mListRemovedTimers.end()) + { + if( it->fd > -1 ) + close( it->fd ); + ++it; + } + mListRemovedTimers.clear(); +} + #endif void CAmSocketHandler::callTimer(sh_timer_s& a) diff --git a/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp b/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp index 49c6738..b18b284 100644 --- a/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp +++ b/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp @@ -79,6 +79,8 @@ struct SerializerData V2::CAmSerializer *pSerializer; }; +#define ASYNCLOOP 100 + void* ptSerializerSync(void* data) { SerializerData *pData = (SerializerData*) data; @@ -96,6 +98,7 @@ void* ptSerializerSync(void* data) return (NULL); } + void* ptSerializerASync(void* data) { SerializerData *pData = (SerializerData*) data; @@ -106,7 +109,7 @@ void* ptSerializerASync(void* data) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - for (uint32_t i = 0; i < 5; i++) + for (uint32_t i = 0; i < ASYNCLOOP; i++) { testStr = pData->testStr; pData->pSerializer->asyncCall(pData->pSerCb, &MockIAmSerializerCb::dispatchData, i, testStr); @@ -191,7 +194,7 @@ TEST(CAmSerializerTest, asyncTest) EXPECT_CALL(serCb,check()).Times(2); EXPECT_CALL(serCb,checkInt()).Times(1).WillRepeatedly(Return(100)); - for (int i = 0; i < 5; i++) + for (int i = 0; i < ASYNCLOOP; i++) EXPECT_CALL(serCb,dispatchData(i,testStr)).WillOnce(DoAll(ActionDispatchData(), Return(true))); myHandler.start_listenting(); diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index ecd38fe..129f896 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -38,7 +38,8 @@ #define SOCK_PATH "/tmp/mysock" -#define SOCKET_TEST_LOOPS_COUNT 1000 +#define SOCKET_TEST_LOOPS_COUNT 10 +#define TIMERS_TO_TEST 500 using namespace testing; using namespace am; @@ -48,6 +49,11 @@ static const char * TEST_SOCKET_DATA_FINAL = "finish!"; static const std::chrono::time_point TP_ZERO; +struct TestUserData +{ + int i; + float f; +}; MockIAmSignalHandler *pMockSignalHandler = NULL; static void signalHandler(int sig, siginfo_t *siginfo, void *context) @@ -149,6 +155,41 @@ void am::CAmTimer::timerCallback(sh_timerHandle_t handle, void* userData) } } +CAmTimerStressTest::CAmTimerStressTest(CAmSocketHandler *myHandler, const timespec &timeout, const int32_t repeats) : + MockIAmTimerCb(), mpSocketHandler(myHandler), mUpdateTimeout(timeout), pTimerCallback(this, &CAmTimerStressTest::timerCallback), mRepeats(repeats), mId(0), mHandle(0) +{ +} + +am::CAmTimerStressTest::~CAmTimerStressTest() +{ +} + +void am::CAmTimerStressTest::timerCallback(sh_timerHandle_t handle, void* pUserData) +{ + mpSocketHandler->removeTimer(handle); + MockIAmTimerCb::timerCallback(handle, pUserData); + sh_timerHandle_t handle1; + mpSocketHandler->addTimer(mUpdateTimeout, &pTimerCallback, handle1, &(*((TestUserData*)pUserData)), true); +} + +CAmTimerStressTest2::CAmTimerStressTest2(CAmSocketHandler *myHandler, const timespec &timeout, const int32_t repeats) : + MockIAmTimerCb(), mpSocketHandler(myHandler), mUpdateTimeout(timeout), pTimerCallback(this, &CAmTimerStressTest2::timerCallback), mRepeats(repeats), mId(0) +{ +} + +am::CAmTimerStressTest2::~CAmTimerStressTest2() +{ +} + +void am::CAmTimerStressTest2::timerCallback(sh_timerHandle_t handle, void* pUserData) +{ + #ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT + std::cout<<"timerCallback handle=" << handle < timers; + + for(int i=0;isetId(i); + timers.push_back( ptestCallback1 ); + myHandler.addTimer(timeoutTime, &(ptestCallback1->pTimerCallback), handle, &userData, true); + EXPECT_CALL(*ptestCallback1,timerCallback(_,&userData)).Times(AnyNumber()); + } + + timespec timeoutTime11, timeout12, timeout13; + timeoutTime11.tv_sec = 1; + timeoutTime11.tv_nsec = 34000000; + CAmTimerMeasurment testCallback11(&myHandler, timeoutTime11, "repeatedCallback 1", std::numeric_limits::max()); + + timeout12.tv_nsec = 2000000; + timeout12.tv_sec = 0; + CAmTimerMeasurment testCallback12(&myHandler, timeout12, "repeatedCallback 2", std::numeric_limits::max()); + + timeout13.tv_nsec = 333000000; + timeout13.tv_sec = 3; + CAmTimerMeasurment testCallback13(&myHandler, timeout13, "oneshotCallback 3"); + + myHandler.addTimer(timeoutTime, &testCallback11.pTimerCallback, handle, NULL, true); + EXPECT_CALL(testCallback11,timerCallback(_,NULL)).Times(AnyNumber()); + + myHandler.addTimer(timeout12, &testCallback12.pTimerCallback, handle, NULL, true); + EXPECT_CALL(testCallback12,timerCallback(_,NULL)).Times(AnyNumber()); + + myHandler.addTimer(timeout13, &testCallback13.pTimerCallback, handle, NULL); + EXPECT_CALL(testCallback13,timerCallback(_,NULL)).Times(AnyNumber()); + + + CAmTimerSockethandlerController testCallback4(&myHandler, timeout4); + + myHandler.addTimer(timeout4, &testCallback4.pTimerCallback, handle, NULL); + + EXPECT_CALL(testCallback4,timerCallback(_,NULL)).Times(1); + myHandler.start_listenting(); + + for(int i=0;isetId(i); + if(E_OK==mySocketHandler->addTimer(timeoutTime, &(ptestCallback1->pTimerCallback), handle, &userData, true)) + { + mTimers.push_back( ptestCallback1 ); + ptestCallback1->setHandle(handle); + } + + EXPECT_CALL(*ptestCallback1,timerCallback(_,&userData)).Times(AnyNumber()); + } +} + +CAmSamplePluginStressTest::~CAmSamplePluginStressTest() +{ + for(int i=0;iremoveTimer(mTimers[i]->getHandle()); + am_Error_e resultAdd = mSocketHandler->addTimer(mTimers[i]->getUpdateTimeout(), &(mTimers[i]->pTimerCallback), handle1, NULL, true); + #ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT + std::cout << "receiveData return removeTimer=" << resultRemove << " return addTimer=" << resultAdd <setHandle(handle1); + } +} + +bool CAmSamplePluginStressTest::dispatchData(const sh_pollHandle_t handle, void* userData) +{ + return CAmSamplePlugin::dispatchData( handle, userData); +} + +bool CAmSamplePluginStressTest::check(const sh_pollHandle_t handle, void* userData) +{ + return CAmSamplePlugin::check( handle, userData); +} + diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h index ba2bf51..269e5da 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h @@ -101,20 +101,20 @@ namespace am UNIX, INET }; CAmSamplePlugin(CAmSocketHandler *mySocketHandler, sockType_e socketType); - ~CAmSamplePlugin() + virtual ~CAmSamplePlugin() { } ; void connectSocket(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); - void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); - bool dispatchData(const sh_pollHandle_t handle, void* userData); - bool check(const sh_pollHandle_t handle, void* userData); + virtual void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); + virtual bool dispatchData(const sh_pollHandle_t handle, void* userData); + virtual bool check(const sh_pollHandle_t handle, void* userData); TAmShPollFired connectFiredCB; TAmShPollFired receiveFiredCB; TAmShPollDispatch sampleDispatchCB; TAmShPollCheck sampleCheckCB; - private: + protected: CAmSocketHandler *mSocketHandler; sh_pollHandle_t mConnecthandle, mReceiveHandle; std::queue msgList; @@ -162,6 +162,54 @@ namespace am TAmShTimerCallBack pTimerCallback; }; + class CAmTimerStressTest: public MockIAmTimerCb + { + CAmSocketHandler *mpSocketHandler; + timespec mUpdateTimeout; + int32_t mRepeats; + int32_t mId; + int32_t mHandle; + public: + explicit CAmTimerStressTest(CAmSocketHandler *SocketHandler, const timespec &timeout, const int32_t repeats = 0u); + virtual ~CAmTimerStressTest(); + + int32_t getId() { return mId; } + void setId(const int32_t id) { mId=id; } + + int32_t getHandle() { return mHandle; } + void setHandle(const int32_t id) { mHandle=id; } + + timespec getUpdateTimeout( ) { return mUpdateTimeout; } + + void timerCallback(sh_timerHandle_t handle, void * userData); + + TAmShTimerCallBack pTimerCallback; + }; + + class CAmTimerStressTest2: public MockIAmTimerCb + { + CAmSocketHandler *mpSocketHandler; + timespec mUpdateTimeout; + int32_t mRepeats; + int32_t mId; + int32_t mHandle; + public: + explicit CAmTimerStressTest2(CAmSocketHandler *SocketHandler, const timespec &timeout, const int32_t repeats = 0u); + virtual ~CAmTimerStressTest2(); + + int32_t getId() { return mId; } + void setId(const int32_t id) { mId=id; } + + int32_t getHandle() { return mHandle; } + void setHandle(const int32_t id) { mHandle=id; } + + timespec getUpdateTimeout( ) { return mUpdateTimeout; } + + void timerCallback(sh_timerHandle_t handle, void * userData); + + TAmShTimerCallBack pTimerCallback; + }; + class CAmTimerMeasurment: public MockIAmTimerCb { CAmSocketHandler *mSocketHandler; @@ -188,6 +236,20 @@ namespace am void SetUp(); void TearDown(); }; + + class CAmSamplePluginStressTest: public CAmSamplePlugin + { + std::vector mTimers; + public: + CAmSamplePluginStressTest(CAmSocketHandler *mySocketHandler, sockType_e socketType); + ~CAmSamplePluginStressTest(); + + virtual void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); + virtual bool dispatchData(const sh_pollHandle_t handle, void* userData); + virtual bool check(const sh_pollHandle_t handle, void* userData); + + std::vector & getTimers() { return mTimers; } + }; } /* namespace am */ #endif /* SOCKETHANDLERTEST_H_ */ -- cgit v1.2.1 From d3a37a8b5da87a77be8f8df8c3c75f337ac03a8e Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Tue, 26 Sep 2017 16:07:00 +0200 Subject: A filedescriptor removal will set an invalidation flag which will prevent calls on the invalidated objects in the current iteration. Signed-off-by: Christian Linke Change-Id: I9d5d3c434ac9fad62c76a76145c731b538aeb1e3 --- AudioManagerUtilities/include/CAmSocketHandler.h | 11 ++-- AudioManagerUtilities/src/CAmSocketHandler.cpp | 58 ++++++++++++++-------- .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 9 ++-- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h index 7baa496..d14c1a3 100644 --- a/AudioManagerUtilities/include/CAmSocketHandler.h +++ b/AudioManagerUtilities/include/CAmSocketHandler.h @@ -217,6 +217,7 @@ class CAmSocketHandler { struct sh_poll_s //! prepareCB; //preperation callback @@ -226,7 +227,7 @@ class CAmSocketHandler void* userData; sh_poll_s() : - handle(0), pollfdValue(), prepareCB(), firedCB(), checkCB(), dispatchCB(), userData(0) + isValid(true), handle(0), pollfdValue(), prepareCB(), firedCB(), checkCB(), dispatchCB(), userData(0) {} }; @@ -302,9 +303,11 @@ class CAmSocketHandler bool mRecreatePollfds; //! listPoll; - VectorListPoll_t cloneListPoll; + std::list listPoll; VectorListPoll_t::iterator listmPollIt; VectorListPollfd_t::iterator itMfdPollingArray; VectorListPollfd_t fdPollingArray; //!handle == handle) @@ -442,10 +444,24 @@ am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle) iterator = mListPoll.erase(iterator); mSetPollKeys.pollHandles.erase(handle); mRecreatePollfds = true; - return (E_OK); + break; } } - return (E_UNKNOWN); + + if (iterator == mListPoll.end()) + return (E_UNKNOWN); + + VectorListPoll_t::iterator iteratorActivePolls = mListActivePolls.begin(); + for (; iteratorActivePolls != mListActivePolls.end(); ++iteratorActivePolls) + { + if (iteratorActivePolls->handle == handle) + { + iteratorActivePolls->isValid = false; + break; + } + } + + return (E_OK); } /** @@ -985,11 +1001,11 @@ void CAmSocketHandler::prepare(am::CAmSocketHandler::sh_poll_s& row) /** * fire callback */ -void CAmSocketHandler::fire(sh_poll_s& a) +void CAmSocketHandler::fire(const sh_poll_s* a) { try { - a.firedCB(a.pollfdValue, a.handle, a.userData); + a->firedCB(a->pollfdValue, a->handle, a->userData); } catch (std::exception& e) { logError("Sockethandler: Exception in Preparecallback,caught", e.what()); @@ -999,23 +1015,23 @@ void CAmSocketHandler::fire(sh_poll_s& a) /** * should disptach */ -bool CAmSocketHandler::noDispatching(const sh_poll_s& a) +bool CAmSocketHandler::noDispatching(const sh_poll_s* a) { //remove from list of there is no checkCB - if (nullptr == a.checkCB) + if (nullptr == a->checkCB || false==a->isValid ) return (true); - return (!a.checkCB(a.handle, a.userData)); + return (!a->checkCB(a->handle, a->userData)); } /** * disptach */ -bool CAmSocketHandler::dispatchingFinished(const sh_poll_s& a) +bool CAmSocketHandler::dispatchingFinished(const sh_poll_s* a) { //remove from list of there is no dispatchCB - if (nullptr == a.dispatchCB) + if (nullptr == a->dispatchCB || false==a->isValid ) return (true); - return (!a.dispatchCB(a.handle, a.userData)); + return (!a->dispatchCB(a->handle, a->userData)); } /** diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index 129f896..07f6aaf 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -36,9 +36,12 @@ //todo: expand test, implement more usecases //todo: test removeFD +#undef ENABLED_SOCKETHANDLER_TEST_OUTPUT +#undef ENABLED_TIMERS_TEST_OUTPUT + #define SOCK_PATH "/tmp/mysock" -#define SOCKET_TEST_LOOPS_COUNT 10 +#define SOCKET_TEST_LOOPS_COUNT 50 #define TIMERS_TO_TEST 500 using namespace testing; @@ -464,7 +467,7 @@ TEST(CAmSocketHandlerTest, timersStressTest) timespec timeoutTime; timeoutTime.tv_sec = 0; - timeoutTime.tv_nsec = 50000000;// 0,05 + timeoutTime.tv_nsec = 10000000;// 0,01 std::vector timers; @@ -896,7 +899,7 @@ CAmSamplePluginStressTest::CAmSamplePluginStressTest(CAmSocketHandler *mySocketH userData.f = 1.f; timespec timeoutTime; timeoutTime.tv_sec = 0; - timeoutTime.tv_nsec = 500000000;// 0,5 + timeoutTime.tv_nsec = 10000000;// 0,01 for(int i=0;i Date: Wed, 27 Sep 2017 11:51:13 +0200 Subject: Runtime check for calls to the sockethandler from other threads Signed-off-by: Christian Linke Change-Id: I9d9d3c424ac9fad62c76a76545c731b518bdb1e2 --- AudioManagerUtilities/include/CAmSocketHandler.h | 6 ++ AudioManagerUtilities/src/CAmSocketHandler.cpp | 33 +++++- .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 116 +++++++++++---------- 3 files changed, 99 insertions(+), 56 deletions(-) diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h index d14c1a3..6163b3c 100644 --- a/AudioManagerUtilities/include/CAmSocketHandler.h +++ b/AudioManagerUtilities/include/CAmSocketHandler.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include "audiomanagertypes.h" @@ -309,6 +310,9 @@ class CAmSocketHandler #endif private: + + static void checkCallerThreadId(void); + bool fdIsValid(const int fd) const; timespec* insertTime(timespec& buffertime); @@ -496,6 +500,8 @@ public: void exit_mainloop(); bool fatalErrorOccurred(); + + static const std::thread::id SOCKETHANDLER_THREAD_ID; }; } /* namespace am */ diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp index 54ba4ef..2a49770 100644 --- a/AudioManagerUtilities/src/CAmSocketHandler.cpp +++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp @@ -32,6 +32,7 @@ #include #include + #include "CAmDltWrapper.h" #include "CAmSocketHandler.h" @@ -42,6 +43,9 @@ namespace am { +const std::thread::id CAmSocketHandler::SOCKETHANDLER_THREAD_ID = std::this_thread::get_id(); + + CAmSocketHandler::CAmSocketHandler() : mPipe(), // mDispatchDone(true), // @@ -102,6 +106,8 @@ void CAmSocketHandler::start_listenting() mDispatchDone = false; int16_t pollStatus; + checkCallerThreadId(); + #ifndef WITH_TIMERFD clock_gettime(CLOCK_MONOTONIC, &mStartTime); #endif @@ -253,6 +259,8 @@ am_Error_e CAmSocketHandler::getFDPollData(const sh_pollHandle_t handle, sh_poll */ am_Error_e CAmSocketHandler::listenToSignals(const std::vector & listSignals) { + checkCallerThreadId(); + int fdErr; uint8_t addedSignals = 0; sigset_t sigset; @@ -366,6 +374,8 @@ am_Error_e CAmSocketHandler::addFDPoll(const int fd, void* userData, sh_pollHandle_t& handle) { + checkCallerThreadId(); + if (!fdIsValid(fd)) return (E_NON_EXISTENT); @@ -435,6 +445,8 @@ am::am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, IAmS */ am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle) { + checkCallerThreadId(); + VectorListPoll_t::iterator iterator = mListPoll.begin(); for (; iterator != mListPoll.end(); ++iterator) @@ -473,6 +485,8 @@ am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle) */ am_Error_e CAmSocketHandler::addSignalHandler(std::function callback, sh_pollHandle_t& handle, void * userData) { + checkCallerThreadId(); + if (!nextHandle(mSetSignalhandlerKeys)) { logError("Could not create new polls, too many open!"); @@ -495,6 +509,8 @@ am_Error_e CAmSocketHandler::addSignalHandler(std::function callback, sh_timerHandle_t& handle, void * userData, const bool repeats) { + checkCallerThreadId(); assert(!((timeouts.tv_sec == 0) && (timeouts.tv_nsec == 0))); mListTimer.emplace_back(); @@ -625,6 +642,7 @@ am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, std::function::iterator it = mListTimer.begin(); for (; it != mListTimer.end(); ++it) @@ -751,6 +771,7 @@ am_Error_e CAmSocketHandler::updateTimer(const sh_timerHandle_t handle, const ti */ am_Error_e CAmSocketHandler::restartTimer(const sh_timerHandle_t handle) { + checkCallerThreadId(); #ifdef WITH_TIMERFD std::list::iterator it = mListTimer.begin(); for (; it != mListTimer.end(); ++it) @@ -829,6 +850,7 @@ am_Error_e CAmSocketHandler::restartTimer(const sh_timerHandle_t handle) */ am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) { + checkCallerThreadId(); #ifdef WITH_TIMERFD std::list::iterator it = mListTimer.begin(); for (; it != mListTimer.end(); ++it) @@ -875,6 +897,7 @@ am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) */ am_Error_e CAmSocketHandler::updateEventFlags(const sh_pollHandle_t handle, const short events) { + checkCallerThreadId(); VectorListPoll_t::iterator iterator = mListPoll.begin(); for (; iterator != mListPoll.end(); ++iterator) @@ -889,6 +912,14 @@ am_Error_e CAmSocketHandler::updateEventFlags(const sh_pollHandle_t handle, cons return (E_UNKNOWN); } +void CAmSocketHandler::checkCallerThreadId(void) +{ + bool bSameThread = (std::this_thread::get_id() == CAmSocketHandler::SOCKETHANDLER_THREAD_ID); + if(!bSameThread) + logError("Sockethandler: Call from another thread detected!"); + assert(bSameThread); +} + /** * checks if a filedescriptor is validCAmShSubstractTime * @param fd the filedescriptor @@ -1064,7 +1095,7 @@ inline timespec* CAmSocketHandler::insertTime(timespec& buffertime) #ifdef WITH_TIMERFD am_Error_e CAmSocketHandler::createTimeFD(const itimerspec & timeouts, int & fd) -{ +{ fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); if (fd < 0) { diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index 07f6aaf..7e03f6e 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -252,16 +252,64 @@ void am::CAmTimerMeasurment::timerCallback(sh_timerHandle_t handle, void* userDa void* playWithSocketServer(void* data) { - CAmSocketHandler *pSockethandler = (CAmSocketHandler*) data; - pSockethandler->start_listenting(); + int socket_ = *((int*)data); + struct sockaddr_in servAddr; + unsigned short servPort = 6060; + struct hostent *host; + + if ((host = (struct hostent*) gethostbyname("localhost")) == 0) + { + std::cout << "ERROR: gethostbyname() failed\n" << std::endl; + exit(1); + } + + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*) (host->h_addr_list[0]))); + servAddr.sin_port = htons(servPort); + sleep(1); + + if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + { + std::cout << "ERROR: connect() failed\n" << std::endl; + } + + for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) + { + std::string string(TEST_SOCKET_DATA); + send(socket_, string.c_str(), string.size(), 0); + } + std::string string(TEST_SOCKET_DATA_FINAL); + send(socket_, string.c_str(), string.size(), 0); + return (NULL); } void* playWithUnixSocketServer(void* data) { - CAmSocketHandler *pSockethandler = (CAmSocketHandler*) data; - pSockethandler->start_listenting(); + int socket_ = *((int*)data); + struct sockaddr_un servAddr; + memset(&servAddr, 0, sizeof(servAddr)); + strcpy(servAddr.sun_path, SOCK_PATH); + servAddr.sun_family = AF_UNIX; + sleep(1); + + if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + { + std::cout << "ERROR: connect() failed\n" << std::endl; + } + + for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) + { + std::string stringToSend(TEST_SOCKET_DATA); + send(socket_, stringToSend.c_str(), stringToSend.size(), 0); + } + std::string stringToSend(TEST_SOCKET_DATA_FINAL); + send(socket_, stringToSend.c_str(), stringToSend.size(), 0); + return (NULL); + + } void* threadCallbackUnixSocketAndTimers(void* data) @@ -660,32 +708,16 @@ TEST(CAmSocketHandlerTest,playWithUNIXSockets) EXPECT_CALL(myplugin,dispatchData(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); EXPECT_CALL(myplugin,check(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); - //creates a thread that handles the serverpart - pthread_create(&serverThread, NULL, playWithUnixSocketServer, &myHandler); - - sleep(1); //we need that here because the port needs to be opened if ((socket_ = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { std::cout << "socket problem" << std::endl; - - } - - memset(&servAddr, 0, sizeof(servAddr)); - strcpy(servAddr.sun_path, SOCK_PATH); - servAddr.sun_family = AF_UNIX; - if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) - { - std::cout << "ERROR: connect() failed\n" << std::endl; - } - - for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) - { - std::string stringToSend(TEST_SOCKET_DATA); - send(socket_, stringToSend.c_str(), stringToSend.size(), 0); } - std::string stringToSend(TEST_SOCKET_DATA_FINAL); - send(socket_, stringToSend.c_str(), stringToSend.size(), 0); + + //creates a thread that handles the serverpart + pthread_create(&serverThread, NULL, playWithUnixSocketServer, &socket_); + myHandler.start_listenting(); + pthread_join(serverThread, NULL); } @@ -693,9 +725,6 @@ TEST(CAmSocketHandlerTest,playWithUNIXSockets) TEST(CAmSocketHandlerTest,playWithSockets) { pthread_t serverThread; - struct sockaddr_in servAddr; - unsigned short servPort = 6060; - struct hostent *host; int socket_; CAmSocketHandler myHandler; @@ -707,39 +736,16 @@ TEST(CAmSocketHandlerTest,playWithSockets) EXPECT_CALL(myplugin,dispatchData(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); EXPECT_CALL(myplugin,check(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); - //creates a thread that handles the serverpart - pthread_create(&serverThread, NULL, playWithSocketServer, &myHandler); - - sleep(1); //we need that here because the port needs to be opened if ((socket_ = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { std::cout << "socket problem" << std::endl; } - if ((host = (struct hostent*) gethostbyname("localhost")) == 0) - { - std::cout << "ERROR: gethostbyname() failed\n" << std::endl; - exit(1); - } - - memset(&servAddr, 0, sizeof(servAddr)); - servAddr.sin_family = AF_INET; - servAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*) (host->h_addr_list[0]))); - servAddr.sin_port = htons(servPort); - - if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) - { - std::cout << "ERROR: connect() failed\n" << std::endl; - } - - for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) - { - std::string string(TEST_SOCKET_DATA); - send(socket_, string.c_str(), string.size(), 0); - } - std::string string(TEST_SOCKET_DATA_FINAL); - send(socket_, string.c_str(), string.size(), 0); + //creates a thread that handles the serverpart + pthread_create(&serverThread, NULL, playWithSocketServer, &socket_); + + myHandler.start_listenting(); pthread_join(serverThread, NULL); -- cgit v1.2.1 From 955847cc5bb490d768a2282ea396b7ef16319631 Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Thu, 28 Sep 2017 17:09:28 +0200 Subject: * All methods in CAPI wrapper with connectionID parameter are deprecated because CommonAPI creates new filedescriptor per connection which isn't needed. * revents flag is passed to the CommonAPI watcher instead events * revents set to 0 in Sockethandler Signed-off-by: Christian Linke Change-Id: I9d9d2c424ac9fad62c76a66545c731c518adb2e4 --- .../include/CAmCommonAPIWrapper.h | 185 ++++++++++----------- AudioManagerUtilities/include/CAmSocketHandler.h | 5 +- AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp | 2 +- AudioManagerUtilities/src/CAmSocketHandler.cpp | 48 +++--- 4 files changed, 119 insertions(+), 121 deletions(-) diff --git a/AudioManagerUtilities/include/CAmCommonAPIWrapper.h b/AudioManagerUtilities/include/CAmCommonAPIWrapper.h index 82328d6..a83b5b3 100644 --- a/AudioManagerUtilities/include/CAmCommonAPIWrapper.h +++ b/AudioManagerUtilities/include/CAmCommonAPIWrapper.h @@ -133,24 +133,25 @@ public: * @return Pointer to the socket handler. */ CAmSocketHandler *getSocketHandler() const { return mpSocketHandler; } -#if COMMONAPI_VERSION_NUMBER >= 300 - /** - * \brief Register stub objects. - * - * Example: std::shared_ptr aStub; - * registerService( aStub, "local", "com.your_company.instance_name", "service-name"); - * - * @param shStub: Shared pointer to a stub instance - * @param domain: A string with the domain name, usually "local" - * @param instance: Common-api instance string as example "com.your_company.instance_name" - * @param connectionId: A string connection id, which is used by CommonAPI to group applications - * - */ - template bool registerService(const std::shared_ptr & shStub, const std::string & domain, const std::string & instance, const CommonAPI::ConnectionId_t & connectionId) - { - return mRuntime->registerService(domain, instance, shStub, connectionId); - } -#endif + + /** + * \brief Deprecated method. This class is used only in single connection applications and no connectionId is needed. Instead you should use bool registerService(const std::shared_ptr & shStub, const std::string & domain, const std::string & instance). + * + * + * Example: std::shared_ptr aStub; + * registerService( aStub, "local", "com.your_company.instance_name", "service-name"); + * + * @param shStub: Shared pointer to a stub instance + * @param domain: A string with the domain name, usually "local" + * @param instance: Common-api instance string as example "com.your_company.instance_name" + * @param connectionId: A string connection id, which is used by CommonAPI to group applications + * + */ + template bool __attribute__((deprecated)) registerService(const std::shared_ptr & shStub, const std::string & domain, const std::string & instance, const CommonAPI::ConnectionId_t __attribute__((__unused__)) & /*connectionId*/) + { + return mRuntime->registerService(domain, instance, shStub, mContext); + } + /** * \brief Register stub objects. * @@ -181,61 +182,59 @@ public: } /** - * \brief Deprecated method. Instead you should use bool registerService(const std::shared_ptr & shStub, const std::string & domain, const std::string & instance). - * - * Register stub objects. - * - * Example: std::shared_ptr aStub; - * registerService( aStub, "local:com.your_company.interface_name:com.your_company.instance_name"); - * - * @param shStub: Shared pointer to a stub instance - * @param address: Complete common-api address as example "local:com.your_company.interface_name:com.your_company.instance_name" - * - */ - template bool __attribute__((deprecated)) registerStub(const std::shared_ptr & shStub, const std::string & address) - { - std::vector parts = CommonAPI::split(address, ':'); - assert(parts.size()==3); - - return registerService(shStub, parts[0], parts[2]); - } - - /** - * \brief Deprecated method. Instead you should use bool unregisterService(const std::string &domain, const std::string &interface, const std::string &instance). - * - * Unregister stub objects. - * - * @param address: Complete common-api address as example "local:com.your_company.interface_name:com.your_company.instance_name" - * - */ - bool __attribute__((deprecated)) unregisterStub(const std::string & address) - { - std::vector parts = CommonAPI::split(address, ':'); - assert(parts.size()==3); - - return unregisterService(parts[0], parts[1], parts[2]); - } - -#if COMMONAPI_VERSION_NUMBER >= 300 - /** - * \brief Build proxy objects. - * - * Example: std::shared_ptr> aProxy = buildProxy("local", "com.your_company.instance_name", "client-name"); - * - * @param domain: A string with the domain name, usually "local" - * @param instance: Common-api instance string as example "com.your_company.instance_name" - * @param connectionId: A string connection id, which is used by CommonAPI to group applications - * - * @return A proxy object. - */ - template class ProxyClass, typename ... AttributeExtensions> - std::shared_ptr> buildProxy(const std::string &domain, const std::string &instance, const CommonAPI::ConnectionId_t & connectionId) - { - return mRuntime->buildProxy(domain, instance, connectionId); - } -#endif - - /** + * \brief Deprecated method. Instead you should use bool registerService(const std::shared_ptr & shStub, const std::string & domain, const std::string & instance). + * + * Register stub objects. + * + * Example: std::shared_ptr aStub; + * registerService( aStub, "local:com.your_company.interface_name:com.your_company.instance_name"); + * + * @param shStub: Shared pointer to a stub instance + * @param address: Complete common-api address as example "local:com.your_company.interface_name:com.your_company.instance_name" + * + */ + template bool __attribute__((deprecated)) registerStub(const std::shared_ptr & shStub, const std::string & address) + { + std::vector parts = CommonAPI::split(address, ':'); + assert(parts.size()==3); + + return registerService(shStub, parts[0], parts[2]); + } + + /** + * \brief Deprecated method. Instead you should use bool unregisterService(const std::string &domain, const std::string &interface, const std::string &instance). + * + * Unregister stub objects. + * + * @param address: Complete common-api address as example "local:com.your_company.interface_name:com.your_company.instance_name" + * + */ + bool __attribute__((deprecated)) unregisterStub(const std::string & address) + { + std::vector parts = CommonAPI::split(address, ':'); + assert(parts.size()==3); + + return unregisterService(parts[0], parts[1], parts[2]); + } + + /** + * \brief Deprecated method. This class is used only in single connection applications and no connectionId is needed. Instead you should use buildProxy(const std::string &domain, const std::string &instance). + * + * Example: std::shared_ptr> aProxy = buildProxy("local", "com.your_company.instance_name", "client-name"); + * + * @param domain: A string with the domain name, usually "local" + * @param instance: Common-api instance string as example "com.your_company.instance_name" + * @param connectionId: A string connection id, which is used by CommonAPI to group applications + * + * @return A proxy object. + */ + template class ProxyClass, typename ... AttributeExtensions> + std::shared_ptr> __attribute__((deprecated)) buildProxy(const std::string &domain, const std::string &instance, const CommonAPI::ConnectionId_t __attribute__((__unused__)) & /*connectionId*/) + { + return mRuntime->buildProxy(domain, instance, mContext); + } + + /** * \brief Build proxy objects. * * Example: std::shared_ptr> aProxy = buildProxy("local", "com.your_company.instance_name"); @@ -250,26 +249,26 @@ public: { return mRuntime->buildProxy(domain, instance, mContext); } - - - /** - * \brief Deprecated method. Instead you should use buildProxy(const std::string &domain, const std::string &instance). - * - * Build proxy objects. - * Example: std::shared_ptr> aProxy = buildProxy("local:com.your_company.interface_name:com.your_company.instance_name"); - * - * @param address: Complete common-api address as example "local:com.your_company.interface_name:com.your_company.instance_name" - * - * @return A proxy object. - */ - template class ProxyClass, typename ... AttributeExtensions> - std::shared_ptr> __attribute__((deprecated)) buildProxy(const std::string & address) - { - std::vector parts=CommonAPI::split(address, ':'); - assert(parts.size()==3); - - return buildProxy(parts[0], parts[2]); - } + + + /** + * \brief Deprecated method. Instead you should use buildProxy(const std::string &domain, const std::string &instance). + * + * Build proxy objects. + * Example: std::shared_ptr> aProxy = buildProxy("local:com.your_company.interface_name:com.your_company.instance_name"); + * + * @param address: Complete common-api address as example "local:com.your_company.interface_name:com.your_company.instance_name" + * + * @return A proxy object. + */ + template class ProxyClass, typename ... AttributeExtensions> + std::shared_ptr> __attribute__((deprecated)) buildProxy(const std::string & address) + { + std::vector parts=CommonAPI::split(address, ':'); + assert(parts.size()==3); + + return buildProxy(parts[0], parts[2]); + } }; diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h index 6163b3c..8809a30 100644 --- a/AudioManagerUtilities/include/CAmSocketHandler.h +++ b/AudioManagerUtilities/include/CAmSocketHandler.h @@ -305,14 +305,13 @@ class CAmSocketHandler internal_codes_t mInternalCodes; sh_pollHandle_t mSignalFdHandle; VectorListPoll_t mListActivePolls; + const std::thread::id mThreadID; //!< Socket handler thread id used to check if the calls come from the same thread #ifndef WITH_TIMERFD timespec mStartTime; //!dispatch(pollfd.events); + mWatchToCheck->dispatch(pollfd.revents); } void CAmCommonAPIWrapper::commonPrepareCallback(const sh_pollHandle_t, void*) diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp index 2a49770..6809902 100644 --- a/AudioManagerUtilities/src/CAmSocketHandler.cpp +++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp @@ -43,8 +43,15 @@ namespace am { -const std::thread::id CAmSocketHandler::SOCKETHANDLER_THREAD_ID = std::this_thread::get_id(); - +#define CHECK_CALLER_THREAD_ID()\ + if(std::this_thread::get_id() != mThreadID)\ + {\ + logError("Sockethandler: Call from another thread detected!");\ + assert(false);\ + } + + + CAmSocketHandler::CAmSocketHandler() : mPipe(), // @@ -63,7 +70,8 @@ CAmSocketHandler::CAmSocketHandler() : mRecreatePollfds(true), mInternalCodes(internal_codes_e::NO_ERROR), mSignalFdHandle(0), - mListActivePolls() + mListActivePolls(), + mThreadID(std::this_thread::get_id()) #ifndef WITH_TIMERFD ,mStartTime() // #endif @@ -106,7 +114,7 @@ void CAmSocketHandler::start_listenting() mDispatchDone = false; int16_t pollStatus; - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() #ifndef WITH_TIMERFD clock_gettime(CLOCK_MONOTONIC, &mStartTime); @@ -181,6 +189,8 @@ void CAmSocketHandler::start_listenting() listPoll.push_back(&pollObj); CAmSocketHandler::fire(&pollObj); + + itMfdPollingArray->revents = 0; } } @@ -259,7 +269,7 @@ am_Error_e CAmSocketHandler::getFDPollData(const sh_pollHandle_t handle, sh_poll */ am_Error_e CAmSocketHandler::listenToSignals(const std::vector & listSignals) { - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() int fdErr; uint8_t addedSignals = 0; @@ -374,7 +384,7 @@ am_Error_e CAmSocketHandler::addFDPoll(const int fd, void* userData, sh_pollHandle_t& handle) { - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() if (!fdIsValid(fd)) return (E_NON_EXISTENT); @@ -445,7 +455,7 @@ am::am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, IAmS */ am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle) { - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() VectorListPoll_t::iterator iterator = mListPoll.begin(); @@ -485,7 +495,7 @@ am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle) */ am_Error_e CAmSocketHandler::addSignalHandler(std::function callback, sh_pollHandle_t& handle, void * userData) { - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() if (!nextHandle(mSetSignalhandlerKeys)) { @@ -509,7 +519,7 @@ am_Error_e CAmSocketHandler::addSignalHandler(std::function callback, sh_timerHandle_t& handle, void * userData, const bool repeats) { - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() assert(!((timeouts.tv_sec == 0) && (timeouts.tv_nsec == 0))); mListTimer.emplace_back(); @@ -642,7 +652,7 @@ am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, std::function::iterator it = mListTimer.begin(); @@ -771,7 +781,7 @@ am_Error_e CAmSocketHandler::updateTimer(const sh_timerHandle_t handle, const ti */ am_Error_e CAmSocketHandler::restartTimer(const sh_timerHandle_t handle) { - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() #ifdef WITH_TIMERFD std::list::iterator it = mListTimer.begin(); for (; it != mListTimer.end(); ++it) @@ -850,7 +860,7 @@ am_Error_e CAmSocketHandler::restartTimer(const sh_timerHandle_t handle) */ am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) { - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() #ifdef WITH_TIMERFD std::list::iterator it = mListTimer.begin(); for (; it != mListTimer.end(); ++it) @@ -897,7 +907,7 @@ am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) */ am_Error_e CAmSocketHandler::updateEventFlags(const sh_pollHandle_t handle, const short events) { - checkCallerThreadId(); + CHECK_CALLER_THREAD_ID() VectorListPoll_t::iterator iterator = mListPoll.begin(); for (; iterator != mListPoll.end(); ++iterator) @@ -912,14 +922,6 @@ am_Error_e CAmSocketHandler::updateEventFlags(const sh_pollHandle_t handle, cons return (E_UNKNOWN); } -void CAmSocketHandler::checkCallerThreadId(void) -{ - bool bSameThread = (std::this_thread::get_id() == CAmSocketHandler::SOCKETHANDLER_THREAD_ID); - if(!bSameThread) - logError("Sockethandler: Call from another thread detected!"); - assert(bSameThread); -} - /** * checks if a filedescriptor is validCAmShSubstractTime * @param fd the filedescriptor -- cgit v1.2.1 From 185746ea67a1f4256a4cde77bbee5dc634408228 Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Thu, 12 Oct 2017 13:02:09 +0200 Subject: Real time scheduler added, capi wrapper timeout return value considered in registerTimeout, only requested revent passed from within the camsockethandler instead of all Signed-off-by: Christian Linke Change-Id: I2d9d2c424ac3fac62c76a66545a531c518edb2e8 --- AudioManagerDaemon/src/main.cpp | 8 ++++ AudioManagerUtilities/include/CAmSocketHandler.h | 7 --- AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp | 43 +++++++++++++----- AudioManagerUtilities/src/CAmSocketHandler.cpp | 51 +++++++++------------- .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 48 ++++++++++++-------- 5 files changed, 90 insertions(+), 67 deletions(-) diff --git a/AudioManagerDaemon/src/main.cpp b/AudioManagerDaemon/src/main.cpp index 5c0582e..22470e9 100755 --- a/AudioManagerDaemon/src/main.cpp +++ b/AudioManagerDaemon/src/main.cpp @@ -384,6 +384,14 @@ iControlSender.setControllerReady(); */ int main(int argc, char *argv[], char** envp) { + struct sched_param param; + param.sched_priority = 50;//mid rt proprity + if (sched_setscheduler(0, SCHED_FIFO, & param) != 0) + { + std::cerr <<"sched_setscheduler:"<getTimeoutInterval(); - - pollTimeout.tv_sec = localTimeout / 1000; - pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000; + + if(CommonAPI::TIMEOUT_INFINITE==localTimeout)//dispatch never + { + pollTimeout.tv_sec = localTimeout; + pollTimeout.tv_nsec = 0; + } + else if(CommonAPI::TIMEOUT_NONE==localTimeout)//dispatch immediately + { + pollTimeout.tv_sec = 0; + pollTimeout.tv_nsec = 1000000; + } + else + { + pollTimeout.tv_sec = localTimeout / 1000; + pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000; + } //prepare handle and callback. new is eval, but there is no other choice because we need the pointer! sh_timerHandle_t handle; //add the timer to the pollLoop - mpSocketHandler->addTimer(pollTimeout, &pCommonTimerCallback, handle, timeout); - - timerHandles myHandle({handle,timeout}); - mpListTimerhandles.push_back(myHandle); - - return; + am_Error_e error = mpSocketHandler->addTimer(pollTimeout, &pCommonTimerCallback, handle, timeout); + if (error != am_Error_e::E_OK || handle == 0) + { + logError(__func__,"adding timer failed"); + } + else + { + timerHandles myHandle({handle,timeout}); + mpListTimerhandles.push_back(myHandle); + } } void CAmCommonAPIWrapper::deregisterTimeout(CommonAPI::Timeout* timeout) @@ -243,10 +260,12 @@ void CAmCommonAPIWrapper::registerWatch(CommonAPI::Watch* watch, const CommonAPI am_Error_e error = mpSocketHandler->addFDPoll(pollfd_.fd, pollfd_.events, &pCommonPrepareCallback, &pCommonFireCallback, &pCommonCheckCallback, &pCommonDispatchCallback, watch, handle); //if everything is alright, add the watch and the handle to our map so we know this relationship - if (error == !am_Error_e::E_OK || handle == 0) + if (error != am_Error_e::E_OK || handle == 0) + { logError(__func__,"entering watch failed"); - - mMapWatches.insert(std::make_pair(pollfd_.fd,watch)); + } + else + mMapWatches.insert(std::make_pair(pollfd_.fd,watch)); } void CAmCommonAPIWrapper::commonTimerCallback(sh_timerHandle_t handle, void *) diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp index 6809902..250d731 100644 --- a/AudioManagerUtilities/src/CAmSocketHandler.cpp +++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp @@ -31,7 +31,7 @@ #include #include #include - +#include #include "CAmDltWrapper.h" #include "CAmSocketHandler.h" @@ -180,7 +180,8 @@ void CAmSocketHandler::start_listenting() //stage 0+1, call firedCB for (itMfdPollingArray = fdPollingArray.begin(); itMfdPollingArray != fdPollingArray.end(); itMfdPollingArray++) { - if (CAmSocketHandler::eventFired(*itMfdPollingArray)) + itMfdPollingArray->revents &= itMfdPollingArray->events | POLLERR | POLLHUP; + if ( itMfdPollingArray->revents!=0 ) { listmPollIt = mListActivePolls.begin(); std::advance(listmPollIt, std::distance(fdPollingArray.begin(), itMfdPollingArray)); @@ -189,7 +190,6 @@ void CAmSocketHandler::start_listenting() listPoll.push_back(&pollObj); CAmSocketHandler::fire(&pollObj); - itMfdPollingArray->revents = 0; } } @@ -312,31 +312,19 @@ am_Error_e CAmSocketHandler::listenToSignals(const std::vector & listSi return (E_NOT_POSSIBLE); } - int signalHandlerFd; + sh_poll_s sgPollData; if(mSignalFdHandle) { - sh_poll_s sgPollData; if(E_OK!=getFDPollData(mSignalFdHandle, sgPollData)) { - removeFDPoll(mSignalFdHandle); - mSignalFdHandle = 0; - } - else - { - int signalHandlerFd = signalfd(sgPollData.pollfdValue.fd, &sigset, 0); - if (signalHandlerFd == -1) - { - logError("Could not update signal fd!"); - return (E_NOT_POSSIBLE); - } - return E_OK; + mSignalFdHandle = 0; } } if(0==mSignalFdHandle) { /* Create the signalfd */ - signalHandlerFd = signalfd(-1, &sigset, 0); + int signalHandlerFd = signalfd(-1, &sigset, 0); if (signalHandlerFd == -1) { logError("Could not open signal fd!"); @@ -356,10 +344,19 @@ am_Error_e CAmSocketHandler::listenToSignals(const std::vector & listSi it.callback(it.handle, info, it.userData); }; /* We're going to add the signal fd through addFDPoll. At this point we don't have any signal listeners. */ - am_Error_e shFdError = addFDPoll(signalHandlerFd, POLLIN | POLLERR | POLLHUP, NULL, actionPoll, [](const sh_pollHandle_t, void*) + return addFDPoll(signalHandlerFd, POLLIN | POLLERR | POLLHUP, NULL, actionPoll, [](const sh_pollHandle_t, void*) { return (false);}, NULL, NULL, mSignalFdHandle); - return shFdError; } + else + { + int signalHandlerFd = signalfd(sgPollData.pollfdValue.fd, &sigset, 0); + if (signalHandlerFd == -1) + { + logError("Could not update signal fd!", strerror(errno)); + return (E_NOT_POSSIBLE); + } + return E_OK; + } } /** @@ -611,7 +608,7 @@ am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, std::functiondispatchCB(a->handle, a->userData)); } -/** - * event triggered - */ -bool CAmSocketHandler::eventFired(const pollfd& a) -{ - return (a.revents == 0 ? false : true); -} - /** * is used to set the pointer for the ppoll command * @param buffertime @@ -1088,8 +1077,8 @@ inline timespec* CAmSocketHandler::insertTime(timespec& buffertime) buffertime = mListActiveTimer.front().countdown; return (&buffertime); } - else -#endif + else +#endif { return (NULL); } diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index 7e03f6e..b0c00d4 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -42,7 +42,7 @@ #define SOCK_PATH "/tmp/mysock" #define SOCKET_TEST_LOOPS_COUNT 50 -#define TIMERS_TO_TEST 500 +#define TIMERS_TO_TEST 100 using namespace testing; using namespace am; @@ -194,10 +194,16 @@ void am::CAmTimerStressTest2::timerCallback(sh_timerHandle_t handle, void* pUser CAmTimerMeasurment::CAmTimerMeasurment(CAmSocketHandler *myHandler, const timespec &timeout, const std::string & label, const int32_t repeats, void * userData) : - MockIAmTimerCb(), pTimerCallback(this, &CAmTimerMeasurment::timerCallback), // - mSocketHandler(myHandler), mUpdateTimeout(timeout), mUpdateTimePoint(std::chrono::seconds - { mUpdateTimeout.tv_sec } + std::chrono::nanoseconds - { mUpdateTimeout.tv_nsec }), mLastInvocationTime(), mExpected(mUpdateTimePoint - TP_ZERO), mRepeats(repeats), mpUserData(userData), mDebugText(label) + MockIAmTimerCb() + , pTimerCallback(this, &CAmTimerMeasurment::timerCallback) + , mSocketHandler(myHandler) + , mUpdateTimeout(timeout) + , mUpdateTimePoint(std::chrono::seconds{ mUpdateTimeout.tv_sec } + std::chrono::nanoseconds{ mUpdateTimeout.tv_nsec }) + , mLastInvocationTime() + , mExpected(mUpdateTimePoint - TP_ZERO) + , mRepeats(repeats) + , mpUserData(userData) + , mDebugText(label) { } @@ -245,7 +251,7 @@ void am::CAmTimerMeasurment::timerCallback(sh_timerHandle_t handle, void* userDa std::cout << mDebugText << " Init measurment " << std::endl; #endif mLastInvocationTime = t_end; - mSocketHandler->updateTimer(handle, mUpdateTimeout); + mSocketHandler->updateTimer( handle, mUpdateTimeout); } } @@ -531,17 +537,17 @@ TEST(CAmSocketHandlerTest, timersStressTest) timespec timeoutTime11, timeout12, timeout13; timeoutTime11.tv_sec = 1; timeoutTime11.tv_nsec = 34000000; - CAmTimerMeasurment testCallback11(&myHandler, timeoutTime11, "repeatedCallback 1", std::numeric_limits::max()); + CAmTimerMeasurment testCallback11(&myHandler, timeoutTime11, "repeated 1", std::numeric_limits::max()); - timeout12.tv_nsec = 2000000; + timeout12.tv_nsec = 100000000; timeout12.tv_sec = 0; - CAmTimerMeasurment testCallback12(&myHandler, timeout12, "repeatedCallback 2", std::numeric_limits::max()); + CAmTimerMeasurment testCallback12(&myHandler, timeout12, "repeated 2", std::numeric_limits::max()); timeout13.tv_nsec = 333000000; timeout13.tv_sec = 3; - CAmTimerMeasurment testCallback13(&myHandler, timeout13, "oneshotCallback 3"); + CAmTimerMeasurment testCallback13(&myHandler, timeout13, "oneshot 3"); - myHandler.addTimer(timeoutTime, &testCallback11.pTimerCallback, handle, NULL, true); + myHandler.addTimer(timeoutTime11, &testCallback11.pTimerCallback, handle, NULL, true); EXPECT_CALL(testCallback11,timerCallback(_,NULL)).Times(AnyNumber()); myHandler.addTimer(timeout12, &testCallback12.pTimerCallback, handle, NULL, true); @@ -557,8 +563,8 @@ TEST(CAmSocketHandlerTest, timersStressTest) EXPECT_CALL(testCallback4,timerCallback(_,NULL)).Times(1); myHandler.start_listenting(); - - for(int i=0;i::max()); + CAmTimerMeasurment testCallback1(&myHandler, timeoutTime, "repeated 1", std::numeric_limits::max()); timeout2.tv_nsec = 2000000; timeout2.tv_sec = 0; - CAmTimerMeasurment testCallback2(&myHandler, timeout2, "repeatedCallback 2", std::numeric_limits::max()); + CAmTimerMeasurment testCallback2(&myHandler, timeout2, "repeated 2", std::numeric_limits::max()); timeout3.tv_nsec = 333000000; timeout3.tv_sec = 3; - CAmTimerMeasurment testCallback3(&myHandler, timeout3, "oneshotCallback 3"); + CAmTimerMeasurment testCallback3(&myHandler, timeout3, "oneshot 3"); timeout4.tv_nsec = 0; timeout4.tv_sec = 8; CAmTimerSockethandlerController testCallback4(&myHandler, timeout4); @@ -609,7 +615,7 @@ TEST(CAmSocketHandlerTest,playWithTimers) #else ASSERT_EQ(handle, 4); #endif - EXPECT_CALL(testCallback3,timerCallback(handle,NULL)).Times(2); //+1 because of measurment + EXPECT_CALL(testCallback3,timerCallback(handle,NULL)).Times(2); myHandler.addTimer(timeout4, &testCallback4.pTimerCallback, handle, NULL); #ifndef WITH_TIMERFD @@ -753,6 +759,14 @@ TEST(CAmSocketHandlerTest,playWithSockets) int main(int argc, char **argv) { + struct sched_param param; + param.sched_priority = 50;//mid rt proprity + if (sched_setscheduler(0, SCHED_FIFO, & param) != 0) + { + std::cerr <<"sched_setscheduler:"< Date: Thu, 12 Oct 2017 17:38:49 +0200 Subject: Fix for CAPI timeouts and support for more than one CAPI watch Signed-off-by: Christian Linke Change-Id: I9a9d2c424bc8fac62c76a66545a531c518edb2e3 --- .../include/CAmCommonAPIWrapper.h | 46 ++-- AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp | 268 +++++++++++++-------- 2 files changed, 198 insertions(+), 116 deletions(-) diff --git a/AudioManagerUtilities/include/CAmCommonAPIWrapper.h b/AudioManagerUtilities/include/CAmCommonAPIWrapper.h index a83b5b3..0f770c4 100644 --- a/AudioManagerUtilities/include/CAmCommonAPIWrapper.h +++ b/AudioManagerUtilities/include/CAmCommonAPIWrapper.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -48,29 +49,37 @@ class CAmSocketHandler; class CAmCommonAPIWrapper { - void commonPrepareCallback(const sh_pollHandle_t handle, void* userData); + void commonPrepareCallback ( const sh_pollHandle_t, void* ); TAmShPollPrepare pCommonPrepareCallback; - bool commonDispatchCallback(const sh_pollHandle_t handle, void* userData); - TAmShPollDispatch pCommonDispatchCallback; - void commonFireCallback(const pollfd pollfd, const sh_pollHandle_t, void*); TAmShPollFired pCommonFireCallback; bool commonCheckCallback(const sh_pollHandle_t handle, void*); TAmShPollCheck pCommonCheckCallback; + + bool commonDispatchCallback(const sh_pollHandle_t handle, void* userData); + TAmShPollDispatch pCommonDispatchCallback; void commonTimerCallback(sh_timerHandle_t handle, void* userData); TAmShTimerCallBack pCommonTimerCallback; - struct timerHandles - { - sh_timerHandle_t handle; - CommonAPI::Timeout* timeout; - }; - CAmSocketHandler *mpSocketHandler; //!< pointer to the sockethandler + typedef std::vector ArrayDispatchSources; + typedef ArrayDispatchSources::iterator IteratorArrayDispatchSources; + typedef std::unordered_map MapWatches; + typedef MapWatches::iterator IteratorMapWatches; + typedef std::unordered_map> MapDispatchSources; + typedef MapDispatchSources::iterator IteratorDispatchSources; + typedef std::unordered_map MapTimeouts; + typedef MapTimeouts::iterator IteratorMapTimeouts; + + ArrayDispatchSources mRegisteredDispatchSources; + MapWatches mMapWatches; + MapDispatchSources mSourcesToDispatch; + MapTimeouts mListTimerhandles; + std::shared_ptr mRuntime; std::shared_ptr mContext; @@ -78,22 +87,23 @@ class CAmCommonAPIWrapper CommonAPI::WatchListenerSubscription mWatchListenerSubscription; CommonAPI::TimeoutSourceListenerSubscription mTimeoutSourceListenerSubscription; CommonAPI::WakeupListenerSubscription mWakeupListenerSubscription; - std::multimap mRegisteredDispatchSources; - std::map mMapWatches; - CommonAPI::Watch* mWatchToCheck; - std::list mSourcesToDispatch; - std::vector mpListTimerhandles; + void registerDispatchSource(CommonAPI::DispatchSource* dispatchSource, const CommonAPI::DispatchPriority dispatchPriority); void deregisterDispatchSource(CommonAPI::DispatchSource* dispatchSource); + void deregisterAllDispatchSource(); void registerWatch(CommonAPI::Watch* watch, const CommonAPI::DispatchPriority dispatchPriority); void deregisterWatch(CommonAPI::Watch* watch); + void deregisterAllWatches(); void registerTimeout(CommonAPI::Timeout* timeout, const CommonAPI::DispatchPriority dispatchPriority); void deregisterTimeout(CommonAPI::Timeout* timeout); - void wakeup(); - + void deregisterAllTimeouts(); + + CommonAPI::Watch* watchWithHandle(const sh_pollHandle_t handle); + CommonAPI::Timeout* timeoutWithHandle(const sh_pollHandle_t handle); + protected: - CAmCommonAPIWrapper(CAmSocketHandler* socketHandler, const std::string & applicationName = "") ; + CAmCommonAPIWrapper ( CAmSocketHandler* socketHandler, const std::string& applicationName = "" ) ; public: diff --git a/AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp b/AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp index caa7aa8..702d384 100644 --- a/AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp +++ b/AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp @@ -36,21 +36,47 @@ namespace am static CAmCommonAPIWrapper* pSingleCommonAPIInstance = NULL; +bool timeoutToTimespec(const int64_t & localTimeout, timespec & pollTimeout) +{ + if(CommonAPI::TIMEOUT_INFINITE == localTimeout)//dispatch never + { + return false; + } + else + { + if(CommonAPI::TIMEOUT_NONE==localTimeout)//dispatch immediately + { + pollTimeout.tv_sec = 0; + pollTimeout.tv_nsec = 5000000;//5 ms + } + else + { + pollTimeout.tv_sec = localTimeout / 1000; + pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000; + } + return true; + } +} + + CAmCommonAPIWrapper::CAmCommonAPIWrapper(CAmSocketHandler* socketHandler, const std::string & applicationName): pCommonPrepareCallback(this,&CAmCommonAPIWrapper::commonPrepareCallback), // - pCommonDispatchCallback(this, &CAmCommonAPIWrapper::commonDispatchCallback), // pCommonFireCallback(this, &CAmCommonAPIWrapper::commonFireCallback), // pCommonCheckCallback(this, &CAmCommonAPIWrapper::commonCheckCallback), // + pCommonDispatchCallback(this, &CAmCommonAPIWrapper::commonDispatchCallback), // pCommonTimerCallback(this, &CAmCommonAPIWrapper::commonTimerCallback), // - mpSocketHandler(socketHandler), // - mWatchToCheck(NULL) + mpSocketHandler(socketHandler), + mRegisteredDispatchSources(), + mMapWatches(), + mSourcesToDispatch(), + mListTimerhandles() { assert(NULL!=socketHandler); //Get the runtime mRuntime = CommonAPI::Runtime::get(); assert(NULL!=mRuntime); - //Create the context +//Create the context if(applicationName.size()) mContext = std::make_shared(applicationName); else @@ -75,9 +101,11 @@ CAmCommonAPIWrapper::~CAmCommonAPIWrapper() mContext->unsubscribeForDispatchSources(mDispatchSourceListenerSubscription); mContext->unsubscribeForWatches(mWatchListenerSubscription); mContext->unsubscribeForTimeouts(mTimeoutSourceListenerSubscription); + deregisterAllDispatchSource(); + deregisterAllTimeouts(); + deregisterAllWatches(); mContext.reset(); mpSocketHandler = NULL; - mWatchToCheck = NULL; } CAmCommonAPIWrapper* CAmCommonAPIWrapper::instantiateOnce(CAmSocketHandler* socketHandler, const std::string & applicationName) @@ -115,170 +143,214 @@ CAmCommonAPIWrapper* CAmCommonAPIWrapper::getInstance() return pSingleCommonAPIInstance; } -bool CAmCommonAPIWrapper::commonDispatchCallback(const sh_pollHandle_t handle, void *userData) +void CAmCommonAPIWrapper::commonPrepareCallback(const sh_pollHandle_t, void*) { - (void) handle; - (void) userData; - - std::list::iterator iterator(mSourcesToDispatch.begin()); - for(;iterator!=mSourcesToDispatch.end();) + for (auto dispatchSourceIterator = mRegisteredDispatchSources.begin(); + dispatchSourceIterator != mRegisteredDispatchSources.end(); + dispatchSourceIterator++) { - CommonAPI::DispatchSource* source = *iterator; - if (!source->dispatch()) { - iterator=mSourcesToDispatch.erase(iterator); + int64_t dispatchTimeout(CommonAPI::TIMEOUT_INFINITE); + if((*dispatchSourceIterator)->prepare(dispatchTimeout)) + { + while ((*dispatchSourceIterator)->dispatch()); } - else - iterator++; } - if (!mSourcesToDispatch.empty()) - return (true); +} - return false; +void CAmCommonAPIWrapper::commonFireCallback(const pollfd pollfd, const sh_pollHandle_t handle, void *) +{ + CommonAPI::Watch* pWatchToCheck = watchWithHandle(handle); + if( pWatchToCheck ) + pWatchToCheck->dispatch(pollfd.revents); } -bool CAmCommonAPIWrapper::commonCheckCallback(const sh_pollHandle_t, void *) +bool CAmCommonAPIWrapper::commonCheckCallback(const sh_pollHandle_t handle, void *) { - std::vector vecDispatch=mWatchToCheck->getDependentDispatchSources(); - mSourcesToDispatch.insert(mSourcesToDispatch.end(), vecDispatch.begin(), vecDispatch.end()); + CommonAPI::Watch* pWatchToCheck = watchWithHandle(handle); + if( pWatchToCheck ) + { + const ArrayDispatchSources & vecDispatch = pWatchToCheck->getDependentDispatchSources(); + if(vecDispatch.size()>0) + { + mSourcesToDispatch[handle].insert(mSourcesToDispatch[handle].end(), vecDispatch.begin(), vecDispatch.end()); + return true; + } + } + return false; +} - return (mWatchToCheck || !mSourcesToDispatch.empty()); +bool CAmCommonAPIWrapper::commonDispatchCallback(const sh_pollHandle_t handle, void *) +{ + CommonAPI::Watch* pWatchToCheck = watchWithHandle(handle); + if( pWatchToCheck ) + { + std::list & srcList = mSourcesToDispatch[handle]; + for(auto it = srcList.begin();it!=srcList.end();) + { + if (false==(*it)->dispatch()) + it=srcList.erase(it); + else + it++; + } + if (!srcList.empty()) + return (true); + } + mSourcesToDispatch.erase(handle); + return false; } -void CAmCommonAPIWrapper::commonFireCallback(const pollfd pollfd, const sh_pollHandle_t, void *) +void CAmCommonAPIWrapper::commonTimerCallback(sh_timerHandle_t handle, void *) { - mWatchToCheck=NULL; - try + CommonAPI::Timeout* pTimeout = timeoutWithHandle(handle); + + if( NULL==pTimeout ) { - mWatchToCheck=mMapWatches.at(pollfd.fd); + //erroneous call because deregisterTimeout has been called, so try to remove the timer from the sockethandler + mpSocketHandler->removeTimer(handle); } - catch (const std::out_of_range& error) { - logInfo(__PRETTY_FUNCTION__,error.what()); - return; + else + { + if ( false==pTimeout->dispatch() ) //it should be removed + { + mpSocketHandler->removeTimer(handle); + mListTimerhandles.erase(handle); + } + #ifndef WITH_TIMERFD + else //the timeout should be rescheduled + mpSocketHandler->restartTimer(handle); + #endif } +} - mWatchToCheck->dispatch(pollfd.revents); +void CAmCommonAPIWrapper::registerDispatchSource(CommonAPI::DispatchSource* dispatchSource, const CommonAPI::DispatchPriority) +{ + mRegisteredDispatchSources.push_back(dispatchSource); } -void CAmCommonAPIWrapper::commonPrepareCallback(const sh_pollHandle_t, void*) +void CAmCommonAPIWrapper::deregisterDispatchSource(CommonAPI::DispatchSource* dispatchSource) { - for (auto dispatchSourceIterator = mRegisteredDispatchSources.begin(); - dispatchSourceIterator != mRegisteredDispatchSources.end(); - dispatchSourceIterator++) + for(IteratorArrayDispatchSources dispatchSourceIterator = mRegisteredDispatchSources.begin(); dispatchSourceIterator != mRegisteredDispatchSources.end(); dispatchSourceIterator++) { - int64_t dispatchTimeout(CommonAPI::TIMEOUT_INFINITE); - if(dispatchSourceIterator->second->prepare(dispatchTimeout)) + if( *dispatchSourceIterator == dispatchSource ) { - while (dispatchSourceIterator->second->dispatch()); + mRegisteredDispatchSources.erase(dispatchSourceIterator); + break; } } } -void CAmCommonAPIWrapper::registerDispatchSource(CommonAPI::DispatchSource* dispatchSource, const CommonAPI::DispatchPriority dispatchPriority) +void CAmCommonAPIWrapper::deregisterAllDispatchSource() { - mRegisteredDispatchSources.insert({dispatchPriority, dispatchSource}); + mRegisteredDispatchSources.clear(); } -void CAmCommonAPIWrapper::deregisterDispatchSource(CommonAPI::DispatchSource* dispatchSource) +void CAmCommonAPIWrapper::registerWatch(CommonAPI::Watch* watch, const CommonAPI::DispatchPriority) { - for(auto dispatchSourceIterator = mRegisteredDispatchSources.begin(); - dispatchSourceIterator != mRegisteredDispatchSources.end(); - dispatchSourceIterator++) { + logInfo(__PRETTY_FUNCTION__); + pollfd pollfd_ (watch->getAssociatedFileDescriptor()); + sh_pollHandle_t handle (0); - if(dispatchSourceIterator->second == dispatchSource) { - mRegisteredDispatchSources.erase(dispatchSourceIterator); - break; - } + am_Error_e error = mpSocketHandler->addFDPoll(pollfd_.fd, pollfd_.events, &pCommonPrepareCallback, &pCommonFireCallback, &pCommonCheckCallback, &pCommonDispatchCallback, watch, handle); + + //if everything is alright, add the watch and the handle to our map so we know this relationship + if (error != am_Error_e::E_OK || handle == 0) + { + logError(__func__,"entering watch failed"); } + else + mMapWatches.insert(std::make_pair(handle,watch)); } void CAmCommonAPIWrapper::deregisterWatch(CommonAPI::Watch* watch) { - for(std::map::iterator iter(mMapWatches.begin());iter!=mMapWatches.end();iter++) + for(IteratorMapWatches iter=mMapWatches.begin();iter!=mMapWatches.end();iter++) { if (iter->second == watch) { + mpSocketHandler->removeFDPoll(iter->first); mMapWatches.erase(iter); break; } } } +void CAmCommonAPIWrapper::deregisterAllWatches() +{ + for(IteratorMapWatches iter=mMapWatches.begin();iter!=mMapWatches.end();iter++) + mpSocketHandler->removeFDPoll(iter->first); + mMapWatches.clear(); +} + void CAmCommonAPIWrapper::registerTimeout(CommonAPI::Timeout* timeout, const CommonAPI::DispatchPriority) { timespec pollTimeout; - int64_t localTimeout = timeout->getTimeoutInterval(); - - if(CommonAPI::TIMEOUT_INFINITE==localTimeout)//dispatch never - { - pollTimeout.tv_sec = localTimeout; - pollTimeout.tv_nsec = 0; - } - else if(CommonAPI::TIMEOUT_NONE==localTimeout)//dispatch immediately + if(timeoutToTimespec(timeout->getTimeoutInterval(), pollTimeout)) { - pollTimeout.tv_sec = 0; - pollTimeout.tv_nsec = 1000000; - } - else - { - pollTimeout.tv_sec = localTimeout / 1000; - pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000; - } + //prepare handle and callback. new is eval, but there is no other choice because we need the pointer! + sh_timerHandle_t handle; - //prepare handle and callback. new is eval, but there is no other choice because we need the pointer! - sh_timerHandle_t handle; - - //add the timer to the pollLoop - am_Error_e error = mpSocketHandler->addTimer(pollTimeout, &pCommonTimerCallback, handle, timeout); - if (error != am_Error_e::E_OK || handle == 0) - { - logError(__func__,"adding timer failed"); - } - else - { - timerHandles myHandle({handle,timeout}); - mpListTimerhandles.push_back(myHandle); + //add the timer to the pollLoop + am_Error_e error = mpSocketHandler->addTimer(pollTimeout, &pCommonTimerCallback, handle, timeout, true); + if (error != am_Error_e::E_OK || handle == 0) + { + logError(__func__,"adding timer failed"); + } + else + { + mListTimerhandles.insert(std::make_pair(handle,timeout)); + } } } void CAmCommonAPIWrapper::deregisterTimeout(CommonAPI::Timeout* timeout) { - for( std::vector::iterator iter(mpListTimerhandles.begin());iter!=mpListTimerhandles.end();iter++) + for( IteratorMapTimeouts iter=mListTimerhandles.begin();iter!= mListTimerhandles.end();iter++) { - if(iter->timeout==timeout) + if(iter->second==timeout) { - mpSocketHandler->removeTimer(iter->handle); + mpSocketHandler->removeTimer(iter->first); + mListTimerhandles.erase(iter->first); + break; } } } -void CAmCommonAPIWrapper::registerWatch(CommonAPI::Watch* watch, const CommonAPI::DispatchPriority) +void CAmCommonAPIWrapper::deregisterAllTimeouts() { - logInfo(__PRETTY_FUNCTION__); - pollfd pollfd_ (watch->getAssociatedFileDescriptor()); - sh_pollHandle_t handle (0); - - am_Error_e error = mpSocketHandler->addFDPoll(pollfd_.fd, pollfd_.events, &pCommonPrepareCallback, &pCommonFireCallback, &pCommonCheckCallback, &pCommonDispatchCallback, watch, handle); + for( IteratorMapTimeouts iter=mListTimerhandles.begin();iter!= mListTimerhandles.end();iter++) + mpSocketHandler->removeTimer(iter->first); + mListTimerhandles.clear(); +} - //if everything is alright, add the watch and the handle to our map so we know this relationship - if (error != am_Error_e::E_OK || handle == 0) +CommonAPI::Watch* CAmCommonAPIWrapper::watchWithHandle(const sh_pollHandle_t handle) +{ + CommonAPI::Watch* pWatchToCheck = NULL; + try { - logError(__func__,"entering watch failed"); + pWatchToCheck = mMapWatches.at(handle); } - else - mMapWatches.insert(std::make_pair(pollfd_.fd,watch)); + catch (const std::out_of_range& error) + { + logInfo(__PRETTY_FUNCTION__,error.what()); + } + return pWatchToCheck; } -void CAmCommonAPIWrapper::commonTimerCallback(sh_timerHandle_t handle, void *) +CommonAPI::Timeout* CAmCommonAPIWrapper::timeoutWithHandle(const sh_pollHandle_t handle) { - for( std::vector::iterator iter(mpListTimerhandles.begin());iter!=mpListTimerhandles.end();iter++) + CommonAPI::Timeout* pTimeout = NULL; + try { - if(iter->handle==handle) - { - iter->timeout->dispatch(); - } + pTimeout = mListTimerhandles.at(handle); } + catch (const std::out_of_range& error) + { + logInfo(__PRETTY_FUNCTION__,error.what()); + } + return pTimeout; } + CAmCommonAPIWrapper* (*getCAPI)() = CAmCommonAPIWrapper::getInstance; } -- cgit v1.2.1 From 18cfa6bd57d952f0b556402760f3b6dd3af20ef2 Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Mon, 27 Nov 2017 15:39:53 +0100 Subject: Cmake parameters for real-time scheduler's priority and policy and throw runtime error if read fails. Signed-off-by: Christian Linke Change-Id: I6a7a2c424bc8fac62c76a66545a231c518edb2e1 --- AudioManagerDaemon/src/main.cpp | 13 ++-- AudioManagerUtilities/include/CAmSocketHandler.h | 22 ++++++ AudioManagerUtilities/src/CAmSocketHandler.cpp | 35 +++++++--- .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 79 +++++++++++----------- .../AmSocketHandlerTest/CAmSocketHandlerTest.h | 16 ++--- CMakeLists.txt | 17 ++++- cmake/config.cmake.in | 3 + 7 files changed, 120 insertions(+), 65 deletions(-) diff --git a/AudioManagerDaemon/src/main.cpp b/AudioManagerDaemon/src/main.cpp index 22470e9..527206a 100755 --- a/AudioManagerDaemon/src/main.cpp +++ b/AudioManagerDaemon/src/main.cpp @@ -384,14 +384,11 @@ iControlSender.setControllerReady(); */ int main(int argc, char *argv[], char** envp) { - struct sched_param param; - param.sched_priority = 50;//mid rt proprity - if (sched_setscheduler(0, SCHED_FIFO, & param) != 0) - { - std::cerr <<"sched_setscheduler:"<0)||((mInternalCodes&internal_codes_e::FD_ERROR)>0); + return ((mInternalCodes&internal_codes_e::PIPE_ERROR)>0)||((mInternalCodes&internal_codes_e::FD_ERROR)>0); } +#ifdef WITH_REALTIME_SCHEDULER +int CAmSocketHandler::setRuntimeScheduler(const pid_t pid, const int policy, const int priority) +{ + //The following structure is used to set a processes priority + struct sched_param param; + //Set the priority of the process + param.sched_priority = priority; + + int ret = sched_setscheduler(pid, policy, & param); + return ret; +} +#endif + am_Error_e CAmSocketHandler::getFDPollData(const sh_pollHandle_t handle, sh_poll_s & outPollData) { VectorListPoll_t::iterator iterator = mListPoll.begin(); @@ -324,7 +337,7 @@ am_Error_e CAmSocketHandler::listenToSignals(const std::vector & listSi if(0==mSignalFdHandle) { /* Create the signalfd */ - int signalHandlerFd = signalfd(-1, &sigset, 0); + int signalHandlerFd = signalfd(-1, &sigset, SFD_NONBLOCK); if (signalHandlerFd == -1) { logError("Could not open signal fd!"); @@ -337,8 +350,13 @@ am_Error_e CAmSocketHandler::listenToSignals(const std::vector & listSi /* We have a valid signal, read the info from the fd */ struct signalfd_siginfo info; ssize_t bytes = read(pollfd.fd, &info, sizeof(info)); - assert(bytes == sizeof(info)); - + if(bytes != sizeof(info)) + { + //error received... + logError("Failed to read from signal fd"); + throw std::runtime_error(std::string("Failed to read from signal fd.")); + } + /* Notify all listeners */ for(auto it: signalHandlers) it.callback(it.handle, info, it.userData); @@ -608,13 +626,14 @@ am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, std::function #include #include - +#include "CAmDltWrapper.h" #include "CAmSocketHandler.h" -//todo: expand test, implement more usecases -//todo: test removeFD #undef ENABLED_SOCKETHANDLER_TEST_OUTPUT #undef ENABLED_TIMERS_TEST_OUTPUT @@ -274,10 +272,11 @@ void* playWithSocketServer(void* data) servAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*) (host->h_addr_list[0]))); servAddr.sin_port = htons(servPort); sleep(1); - - if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + int ret = connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if (ret < 0) { - std::cout << "ERROR: connect() failed\n" << std::endl; + std::cerr << "ERROR: connect() failed\n" << std::endl; + return (NULL); } for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) @@ -299,10 +298,11 @@ void* playWithUnixSocketServer(void* data) strcpy(servAddr.sun_path, SOCK_PATH); servAddr.sun_family = AF_UNIX; sleep(1); - - if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + int ret = connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if ( ret < 0) { - std::cout << "ERROR: connect() failed\n" << std::endl; + std::cerr << "ERROR: connect() failed\n" << std::endl; + return (NULL); } for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) @@ -314,8 +314,6 @@ void* playWithUnixSocketServer(void* data) send(socket_, stringToSend.c_str(), stringToSend.size(), 0); return (NULL); - - } void* threadCallbackUnixSocketAndTimers(void* data) @@ -326,9 +324,11 @@ void* threadCallbackUnixSocketAndTimers(void* data) strcpy(servAddr.sun_path, SOCK_PATH); servAddr.sun_family = AF_UNIX; sleep(1); - if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + int ret = connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if ( ret < 0) { - std::cout << "ERROR: connect() failed\n" << std::endl; + std::cerr << "ERROR: connect() failed\n" << std::endl; + return (NULL); } for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) @@ -369,6 +369,7 @@ TEST(CAmSocketHandlerTest, stressTestUnixSocketAndTimers) { std::cout << "socket problem" << std::endl; } + ASSERT_GT(socket_, -1); //creates a thread that handles the serverpart pthread_create(&serverThread, NULL, threadCallbackUnixSocketAndTimers, &socket_); @@ -376,6 +377,7 @@ TEST(CAmSocketHandlerTest, stressTestUnixSocketAndTimers) myHandler.start_listenting(); pthread_join(serverThread, NULL); + shutdown(socket_, SHUT_RDWR); } TEST(CAmSocketHandlerTest, timersOneshot) @@ -709,6 +711,7 @@ TEST(CAmSocketHandlerTest,playWithUNIXSockets) ASSERT_FALSE(myHandler.fatalErrorOccurred()); CAmSamplePlugin::sockType_e type = CAmSamplePlugin::UNIX; CAmSamplePlugin myplugin(&myHandler, type); + ASSERT_TRUE(myplugin.isSocketOpened()); EXPECT_CALL(myplugin,receiveData(_,_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); EXPECT_CALL(myplugin,dispatchData(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); @@ -718,14 +721,14 @@ TEST(CAmSocketHandlerTest,playWithUNIXSockets) { std::cout << "socket problem" << std::endl; } - + ASSERT_GT(socket_, -1); //creates a thread that handles the serverpart pthread_create(&serverThread, NULL, playWithUnixSocketServer, &socket_); myHandler.start_listenting(); pthread_join(serverThread, NULL); - + shutdown(socket_, SHUT_RDWR); } TEST(CAmSocketHandlerTest,playWithSockets) @@ -737,7 +740,7 @@ TEST(CAmSocketHandlerTest,playWithSockets) ASSERT_FALSE(myHandler.fatalErrorOccurred()); CAmSamplePlugin::sockType_e type = CAmSamplePlugin::INET; CAmSamplePlugin myplugin(&myHandler, type); - + ASSERT_TRUE(myplugin.isSocketOpened()); EXPECT_CALL(myplugin,receiveData(_,_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); EXPECT_CALL(myplugin,dispatchData(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); EXPECT_CALL(myplugin,check(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); @@ -745,28 +748,24 @@ TEST(CAmSocketHandlerTest,playWithSockets) if ((socket_ = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { std::cout << "socket problem" << std::endl; - } - + ASSERT_GT(socket_, -1); //creates a thread that handles the serverpart pthread_create(&serverThread, NULL, playWithSocketServer, &socket_); myHandler.start_listenting(); pthread_join(serverThread, NULL); - + shutdown(socket_, SHUT_RDWR); } int main(int argc, char **argv) { - struct sched_param param; - param.sched_priority = 50;//mid rt proprity - if (sched_setscheduler(0, SCHED_FIFO, & param) != 0) - { - std::cerr <<"sched_setscheduler:"<addFDPoll(socketHandle, events, NULL, &connectFiredCB, NULL, NULL, NULL, mConnecthandle); + mySocketHandler->addFDPoll(mSocket, events, NULL, &connectFiredCB, NULL, NULL, NULL, mConnecthandle); #ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT std::cout << "setup server - listening" << std::endl; #endif diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h index 269e5da..6cda2b3 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h @@ -101,10 +101,7 @@ namespace am UNIX, INET }; CAmSamplePlugin(CAmSocketHandler *mySocketHandler, sockType_e socketType); - virtual ~CAmSamplePlugin() - { - } - ; + virtual ~CAmSamplePlugin(){ shutdown(mSocket, SHUT_RDWR); } void connectSocket(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); virtual void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); virtual bool dispatchData(const sh_pollHandle_t handle, void* userData); @@ -113,11 +110,12 @@ namespace am TAmShPollFired receiveFiredCB; TAmShPollDispatch sampleDispatchCB; TAmShPollCheck sampleCheckCB; - + bool isSocketOpened() { return mSocket>-1; } protected: CAmSocketHandler *mSocketHandler; sh_pollHandle_t mConnecthandle, mReceiveHandle; std::queue msgList; + int mSocket; }; class CAmTimerSockethandlerController: public MockIAmTimerCb @@ -242,11 +240,11 @@ namespace am std::vector mTimers; public: CAmSamplePluginStressTest(CAmSocketHandler *mySocketHandler, sockType_e socketType); - ~CAmSamplePluginStressTest(); + virtual ~CAmSamplePluginStressTest(); - virtual void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); - virtual bool dispatchData(const sh_pollHandle_t handle, void* userData); - virtual bool check(const sh_pollHandle_t handle, void* userData); + void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData) final; + bool dispatchData(const sh_pollHandle_t handle, void* userData) final; + bool check(const sh_pollHandle_t handle, void* userData) final; std::vector & getTimers() { return mTimers; } }; diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c70c61..7f34774 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,8 +61,13 @@ option ( WITH_SHARED_CORE "Build audio manager core as dynamic library" OFF) option ( WITH_TIMERFD - "Build with the linux specific TIMERFD feature to support timing without using signals" ON) + "Build with timer fd support" ON ) + +option ( WITH_REALTIME_SCHEDULER + "Use real time scheduler" OFF ) +option( WITH_TESTS + "Build together with all available unitTest" ON ) set(DBUS_SERVICE_PREFIX "org.genivi.audiomanager" CACHE PROPERTY "The dbus service prefix for the AM - only changable for legacy dbus") @@ -94,6 +99,12 @@ set(AM_MAX_CONNECTIONS 0x1000 set(AM_MAX_MAIN_CONNECTIONS 0x1000 CACHE INTEGER "Number of max Mainconnections before rollover") +set(AM_PROCESS_PRIORITY 50 + CACHE INTEGER "Set the priority of the process. The priority is between 1 and 99.") + +set(AM_REALTIME_POLICY SCHED_FIFO + CACHE PROPERTY "The real-time policies that may be specified. See the sched_setscheduler documentation for more details.") + set(AUDIOMANGER_APP_ID "AUDI" CACHE PROPERTY "The application ID that is used by the audiomanager") @@ -209,7 +220,6 @@ if(WITH_DOCUMENTATION) PATTERN "def" EXCLUDE) endif(WITH_DOCUMENTATION) - message(STATUS) message(STATUS "${PROJECT_NAME} Configuration:") message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") @@ -224,6 +234,7 @@ message(STATUS "WITH_DBUS_WRAPPER = ${WITH_DBUS_WRAPPER}") message(STATUS "WITH_SHARED_UTILITIES = ${WITH_SHARED_UTILITIES}") message(STATUS "WITH_SHARED_CORE = ${WITH_SHARED_CORE}") message(STATUS "WITH_TIMERFD = ${WITH_TIMERFD}") +message(STATUS "WITH_REALTIME_SCHEDULER = ${WITH_REALTIME_SCHEDULER}") message(STATUS "DYNAMIC_ID_BOUNDARY = ${DYNAMIC_ID_BOUNDARY}") message(STATUS "LIB_INSTALL_SUFFIX = ${LIB_INSTALL_SUFFIX}") message(STATUS "TEST_EXECUTABLE_INSTALL_PATH = ${TEST_EXECUTABLE_INSTALL_PATH}") @@ -235,6 +246,8 @@ message(STATUS "AM_SHARE_FOLDER = ${AM_SHARE_FOLDER}") message(STATUS "AM_MAP_CAPACITY = ${AM_MAP_CAPACITY}") message(STATUS "AM_MAX_CONNECTIONS = ${AM_MAX_CONNECTIONS}") message(STATUS "AM_MAX_MAIN_CONNECTIONS = ${AM_MAX_MAIN_CONNECTIONS}") +message(STATUS "AM_PROCESS_PRIORITY = ${AM_PROCESS_PRIORITY}") +message(STATUS "AM_REALTIME_POLICY = ${AM_REALTIME_POLICY}") message(STATUS "BUILD_TESTING = ${BUILD_TESTING}") message(STATUS "CMAKE_INSTALL_DOCDIR = ${CMAKE_INSTALL_DOCDIR}") message(STATUS "AUDIOMANGER_APP_ID = ${AUDIOMANGER_APP_ID}") diff --git a/cmake/config.cmake.in b/cmake/config.cmake.in index 1501393..268fbf2 100644 --- a/cmake/config.cmake.in +++ b/cmake/config.cmake.in @@ -10,6 +10,7 @@ #cmakedefine GLIB_DBUS_TYPES_TOLERANT #cmakedefine WITH_SYSTEMD_WATCHDOG #cmakedefine WITH_TIMERFD +#cmakedefine WITH_REALTIME_SCHEDULER #cmakedefine DEFAULT_PLUGIN_DIR "@DEFAULT_PLUGIN_DIR@" #cmakedefine DEFAULT_PLUGIN_COMMAND_DIR "@DEFAULT_PLUGIN_COMMAND_DIR@" @@ -29,6 +30,8 @@ #cmakedefine AM_MAP_CAPACITY @AM_MAP_CAPACITY@ #cmakedefine AM_MAX_CONNECTIONS @AM_MAX_CONNECTIONS@ #cmakedefine AM_MAX_MAIN_CONNECTIONS @AM_MAX_MAIN_CONNECTIONS@ +#cmakedefine AM_PROCESS_PRIORITY @AM_PROCESS_PRIORITY@ +#cmakedefine AM_REALTIME_POLICY @AM_REALTIME_POLICY@ #cmakedefine LIB_COMMAND_INTERFACE_VERSION @LIB_COMMAND_INTERFACE_VERSION@ #cmakedefine LIB_CONTROL_INTERFACE_VERSION @LIB_CONTROL_INTERFACE_VERSION@ #cmakedefine LIB_ROUTING_INTERFACE_VERSION @LIB_ROUTING_INTERFACE_VERSION@ -- cgit v1.2.1 From a0668945bbbab6434fef9c3f491877fc45460430 Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Wed, 7 Feb 2018 10:51:17 +0100 Subject: The real-time scheduler removed. Signed-off-by: Christian Linke Change-Id: I7c8a2c474bc8fac62c76a46545a231c518edb2a8 --- AudioManagerDaemon/src/main.cpp | 5 ----- AudioManagerUtilities/include/CAmSocketHandler.h | 22 ---------------------- AudioManagerUtilities/src/CAmSocketHandler.cpp | 13 ------------- .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 5 ----- CMakeLists.txt | 12 ------------ cmake/config.cmake.in | 3 --- 6 files changed, 60 deletions(-) diff --git a/AudioManagerDaemon/src/main.cpp b/AudioManagerDaemon/src/main.cpp index 527206a..5c0582e 100755 --- a/AudioManagerDaemon/src/main.cpp +++ b/AudioManagerDaemon/src/main.cpp @@ -384,11 +384,6 @@ iControlSender.setControllerReady(); */ int main(int argc, char *argv[], char** envp) { - //Set runtime-scheduler with priority and policy for all threads. You can define the priority and policy via cmake. - //If the cmake option WITH_REALTIME_SCHEDULER is OFF the following macro is empty. - //If a thread needs other settings you can use CAmSocketHandler::setRuntimeScheduler(...) - SET_REALTIME_SCHEDULER() - (void) envp; listCommandPluginDirs.push_back(std::string(DEFAULT_PLUGIN_COMMAND_DIR)); listRoutingPluginDirs.push_back(std::string(DEFAULT_PLUGIN_ROUTING_DIR)); diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h index 2fd5c42..53010ba 100644 --- a/AudioManagerUtilities/include/CAmSocketHandler.h +++ b/AudioManagerUtilities/include/CAmSocketHandler.h @@ -492,29 +492,7 @@ public: void exit_mainloop(); bool fatalErrorOccurred(); -#ifdef WITH_REALTIME_SCHEDULER - /** - * Set scheduling algorithm and/or parameters for a thread whose ID is specified in pid. - * If pid equals zero, the scheduling policy and parameters of the calling thread will be set. - * @param pid_t pid thread id - * @param int policy equals specified policies in sched_setscheduler documentation - * @param int priority between 1 and 99 - * @return on success 0 and on error -1 - */ - static int setRuntimeScheduler(const pid_t pid, const int policy, const int priority); -#endif }; -#ifdef WITH_REALTIME_SCHEDULER -#define SET_REALTIME_SCHEDULER()\ - if ( CAmSocketHandler::setRuntimeScheduler(0, AM_REALTIME_POLICY, AM_PROCESS_PRIORITY) != 0 )\ - {\ - std::cerr <<"sched_setscheduler:"<0)||((mInternalCodes&internal_codes_e::FD_ERROR)>0); } -#ifdef WITH_REALTIME_SCHEDULER -int CAmSocketHandler::setRuntimeScheduler(const pid_t pid, const int policy, const int priority) -{ - //The following structure is used to set a processes priority - struct sched_param param; - //Set the priority of the process - param.sched_priority = priority; - - int ret = sched_setscheduler(pid, policy, & param); - return ret; -} -#endif - am_Error_e CAmSocketHandler::getFDPollData(const sh_pollHandle_t handle, sh_poll_s & outPollData) { VectorListPoll_t::iterator iterator = mListPoll.begin(); diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index c4af4c1..3908c2e 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -761,11 +761,6 @@ TEST(CAmSocketHandlerTest,playWithSockets) int main(int argc, char **argv) { - //Set runtime-scheduler with priority and policy for all threads. You can define the priority and policy via cmake. - //If the cmake option WITH_REALTIME_SCHEDULER is OFF the following macro is empty. - //If a thread needs other settings you can use CAmSocketHandler::setRuntimeScheduler(...) - SET_REALTIME_SCHEDULER() - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f34774..eb27f96 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,9 +62,6 @@ option ( WITH_SHARED_CORE option ( WITH_TIMERFD "Build with timer fd support" ON ) - -option ( WITH_REALTIME_SCHEDULER - "Use real time scheduler" OFF ) option( WITH_TESTS "Build together with all available unitTest" ON ) @@ -99,12 +96,6 @@ set(AM_MAX_CONNECTIONS 0x1000 set(AM_MAX_MAIN_CONNECTIONS 0x1000 CACHE INTEGER "Number of max Mainconnections before rollover") -set(AM_PROCESS_PRIORITY 50 - CACHE INTEGER "Set the priority of the process. The priority is between 1 and 99.") - -set(AM_REALTIME_POLICY SCHED_FIFO - CACHE PROPERTY "The real-time policies that may be specified. See the sched_setscheduler documentation for more details.") - set(AUDIOMANGER_APP_ID "AUDI" CACHE PROPERTY "The application ID that is used by the audiomanager") @@ -234,7 +225,6 @@ message(STATUS "WITH_DBUS_WRAPPER = ${WITH_DBUS_WRAPPER}") message(STATUS "WITH_SHARED_UTILITIES = ${WITH_SHARED_UTILITIES}") message(STATUS "WITH_SHARED_CORE = ${WITH_SHARED_CORE}") message(STATUS "WITH_TIMERFD = ${WITH_TIMERFD}") -message(STATUS "WITH_REALTIME_SCHEDULER = ${WITH_REALTIME_SCHEDULER}") message(STATUS "DYNAMIC_ID_BOUNDARY = ${DYNAMIC_ID_BOUNDARY}") message(STATUS "LIB_INSTALL_SUFFIX = ${LIB_INSTALL_SUFFIX}") message(STATUS "TEST_EXECUTABLE_INSTALL_PATH = ${TEST_EXECUTABLE_INSTALL_PATH}") @@ -246,8 +236,6 @@ message(STATUS "AM_SHARE_FOLDER = ${AM_SHARE_FOLDER}") message(STATUS "AM_MAP_CAPACITY = ${AM_MAP_CAPACITY}") message(STATUS "AM_MAX_CONNECTIONS = ${AM_MAX_CONNECTIONS}") message(STATUS "AM_MAX_MAIN_CONNECTIONS = ${AM_MAX_MAIN_CONNECTIONS}") -message(STATUS "AM_PROCESS_PRIORITY = ${AM_PROCESS_PRIORITY}") -message(STATUS "AM_REALTIME_POLICY = ${AM_REALTIME_POLICY}") message(STATUS "BUILD_TESTING = ${BUILD_TESTING}") message(STATUS "CMAKE_INSTALL_DOCDIR = ${CMAKE_INSTALL_DOCDIR}") message(STATUS "AUDIOMANGER_APP_ID = ${AUDIOMANGER_APP_ID}") diff --git a/cmake/config.cmake.in b/cmake/config.cmake.in index 268fbf2..1501393 100644 --- a/cmake/config.cmake.in +++ b/cmake/config.cmake.in @@ -10,7 +10,6 @@ #cmakedefine GLIB_DBUS_TYPES_TOLERANT #cmakedefine WITH_SYSTEMD_WATCHDOG #cmakedefine WITH_TIMERFD -#cmakedefine WITH_REALTIME_SCHEDULER #cmakedefine DEFAULT_PLUGIN_DIR "@DEFAULT_PLUGIN_DIR@" #cmakedefine DEFAULT_PLUGIN_COMMAND_DIR "@DEFAULT_PLUGIN_COMMAND_DIR@" @@ -30,8 +29,6 @@ #cmakedefine AM_MAP_CAPACITY @AM_MAP_CAPACITY@ #cmakedefine AM_MAX_CONNECTIONS @AM_MAX_CONNECTIONS@ #cmakedefine AM_MAX_MAIN_CONNECTIONS @AM_MAX_MAIN_CONNECTIONS@ -#cmakedefine AM_PROCESS_PRIORITY @AM_PROCESS_PRIORITY@ -#cmakedefine AM_REALTIME_POLICY @AM_REALTIME_POLICY@ #cmakedefine LIB_COMMAND_INTERFACE_VERSION @LIB_COMMAND_INTERFACE_VERSION@ #cmakedefine LIB_CONTROL_INTERFACE_VERSION @LIB_CONTROL_INTERFACE_VERSION@ #cmakedefine LIB_ROUTING_INTERFACE_VERSION @LIB_ROUTING_INTERFACE_VERSION@ -- cgit v1.2.1