summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksandar Donchev <Aleksander.Donchev@partner.bmw.de>2017-05-19 11:55:01 +0200
committerJacqueline Molz <Jacqueline.Molz@bmw.de>2017-07-10 12:35:05 +0200
commitbe63615585049aa4045f13e91291d64b0a9ed5a3 (patch)
tree9baabfbf751e85d0980f74e55e8332f6e20c379f
parent375dc7b81795da9bfd8372f629d7fcef704a6d58 (diff)
downloadaudiomanager-be63615585049aa4045f13e91291d64b0a9ed5a3.tar.gz
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 <christian.linke@bmw.de> Change-Id: I8c5d3c436ac9fcd61c76a26145c731b427cab1e6
-rw-r--r--AudioManagerCore/src/CAmCommandReceiver.cpp2
-rw-r--r--AudioManagerCore/test/AmControlInterfaceTest/CMakeLists.txt1
-rw-r--r--AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt1
-rw-r--r--AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt1
-rw-r--r--AudioManagerCore/test/AmRouterTest/CMakeLists.txt1
-rw-r--r--AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt1
-rwxr-xr-xAudioManagerDaemon/src/main.cpp54
-rw-r--r--AudioManagerUtilities/include/CAmSocketHandler.h791
-rw-r--r--AudioManagerUtilities/src/CAmSocketHandler.cpp1627
-rw-r--r--AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt1
-rw-r--r--AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp116
-rw-r--r--AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h2
-rw-r--r--AudioManagerUtilities/test/AmSocketHandlerTest/CMakeLists.txt1
-rwxr-xr-xCMakeLists.txt1
-rw-r--r--docs/main_8cpp_source.html2
15 files changed, 1344 insertions, 1258 deletions
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));
}
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..5a74cba 100644
--- a/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt
+++ b/AudioManagerCore/test/AmMapHandlerTest/CMakeLists.txt
@@ -36,6 +36,7 @@ ADD_EXECUTABLE( AmMapHandlerTest ${DATABASE_SRCS_CXX})
TARGET_LINK_LIBRARIES( AmMapHandlerTest
${GTEST_LIBRARIES}
${GMOCK_LIBRARIES}
+ ${CMAKE_THREAD_LIBS_INIT}
AudioManagerCore
)
diff --git a/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt b/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt
index dc2732c..c4a5968 100644
--- a/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt
+++ b/AudioManagerCore/test/AmRouterMapTest/CMakeLists.txt
@@ -34,6 +34,7 @@ ADD_EXECUTABLE( AmRouterMapTest ${ROUTINGMAP_SRCS_CXX})
TARGET_LINK_LIBRARIES(AmRouterMapTest
${GTEST_LIBRARIES}
${GMOCK_LIBRARIES}
+ ${CMAKE_THREAD_LIBS_INIT}
AudioManagerCore
)
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..369c536 100644
--- a/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt
+++ b/AudioManagerCore/test/AmRoutingInterfaceTest/CMakeLists.txt
@@ -38,6 +38,7 @@ ADD_TEST(AmRoutingInterfaceTest AmRoutingInterfaceTest)
TARGET_LINK_LIBRARIES(AmRoutingInterfaceTest
${GTEST_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; //!<this is a handle for a filedescriptor to be used with the SocketHandler
- typedef sh_pollHandle_t sh_timerHandle_t; //!<this is a handle for a timer to be used with the SocketHandler
+typedef uint16_t sh_pollHandle_t; //!<this is a handle for a filedescriptor to be used with the SocketHandler
+typedef sh_pollHandle_t sh_timerHandle_t; //!<this is a handle for a timer to be used with the SocketHandler
- /**
- * prototype for poll prepared callback
- */
- class IAmShPollPrepare
- {
- public:
- virtual void Call(const sh_pollHandle_t handle, void* userData) = 0;
- virtual ~IAmShPollPrepare()
- {
- }
- ;
- };
+/**
+ * prototype for poll prepared callback
+ */
+class IAmShPollPrepare
+{
+public:
+ virtual void Call(const sh_pollHandle_t handle, void* userData) = 0;
+ virtual ~IAmShPollPrepare() {}
+};
- /**
- * prototype for poll fired callback
- */
- class IAmShPollFired
- {
- public:
- virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData) = 0;
- virtual ~ IAmShPollFired()
- {
- }
- ;
- };
+/**
+ * prototype for poll fired callback
+ */
+class IAmShPollFired
+{
+public:
+ virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData) = 0;
+ virtual ~ IAmShPollFired() {}
+};
- /**
- * prototype for poll check callback
- */
- class IAmShPollCheck
- {
- public:
- virtual bool Call(const sh_pollHandle_t handle, void* userData) = 0;
- virtual ~ IAmShPollCheck()
- {
- }
- ;
- };
+/**
+ * prototype for poll check callback
+ */
+class IAmShPollCheck
+{
+public:
+ virtual bool Call(const sh_pollHandle_t handle, void* userData) = 0;
+ virtual ~ IAmShPollCheck() {}
+};
- /**
- * prototype for dispatch callback
- */
- class IAmShPollDispatch
- {
- public:
- virtual bool Call(const sh_pollHandle_t handle, void* userData) = 0;
- virtual ~ IAmShPollDispatch()
- {
- }
- ;
- };
+/**
+ * prototype for dispatch callback
+ */
+class IAmShPollDispatch
+{
+public:
+ virtual bool Call(const sh_pollHandle_t handle, void* userData) = 0;
+ virtual ~ IAmShPollDispatch() {}
+};
- /**
- * prototype for the timer callback
- */
- class IAmShTimerCallBack
- {
- public:
- IAmShTimerCallBack()
- {
- }
- virtual void Call(const sh_timerHandle_t handle, void* userData) = 0;
- virtual ~IAmShTimerCallBack()
- {
- }
- };
+/**
+ * prototype for the timer callback
+ */
+class IAmShTimerCallBack
+{
+public:
+ IAmShTimerCallBack(){};
+ virtual void Call(const sh_timerHandle_t handle, void* userData) = 0;
+ virtual ~IAmShTimerCallBack(){}
+};
+
+/**make private, not public
+ * template for a callback
+ */
+template<class TClass> 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 TClass> 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 TClass> class TAmShPollCheck: public IAmShPollCheck
+{
+private:
+ TClass* mInstance;
+ bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
- /**
- * template for a callback
- */
- template<class TClass> 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 TClass> class TAmShPollDispatch: public IAmShPollDispatch
+{
+private:
+ TClass* mInstance;
+ bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
- /**
- * template for a callback
- */
- template<class TClass> 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 TClass> 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 TClass> 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 TClass> class TAmShPollPrepare: public IAmShPollPrepare
+{
+private:
+ TClass* mInstance;
+ void (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
- template<class TClass> 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 //!<struct that holds information about polls
+ {
+ sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
+ pollfd pollfdValue; //!<the array for polling the filedescriptors
+ std::function<void(const sh_pollHandle_t handle, void* userData)> prepareCB; //preperation callback
+ std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> firedCB; //fired callback
+ std::function<bool(const sh_pollHandle_t handle, void* userData)> checkCB; //check callback
+ std::function<bool(const sh_pollHandle_t handle, void* userData)> 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 //!<struct that holds information of timers
{
- struct sh_poll_s //!<struct that holds information about polls
- {
- sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
- pollfd pollfdValue; //!<the array for polling the filedescriptors
- std::function<void(const sh_pollHandle_t handle, void* userData)> prepareCB; //preperation callback
- std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> firedCB; //fired callback
- std::function<bool(const sh_pollHandle_t handle, void* userData)> checkCB; //check callback
- std::function<bool(const sh_pollHandle_t handle, void* userData)> dispatchCB; //dispatch callback
- void* userData;
-
- sh_poll_s() :
- handle(0), pollfdValue(), prepareCB(), firedCB(), checkCB(), dispatchCB(), userData(0)
- {
- }
- };
-
- struct sh_timer_s //!<struct that holds information of timers
- {
- sh_timerHandle_t handle; //!<the handle of the timer
+ sh_timerHandle_t handle; //!<the handle of the timer
#ifdef WITH_TIMERFD
- int fd;
- itimerspec countdown; //!<the countdown, this value is decreased every time the timer is up
+ int fd;
+ itimerspec countdown; //!<the countdown, this value is decreased every time the timer is up
#else
- timespec countdown; //!<the countdown, this value is decreased every time the timer is up
+ timespec countdown; //!<the countdown, this value is decreased every time the timer is up
#endif
- std::function<void(const sh_timerHandle_t handle, void* userData)> callback; //timer callback
- void* userData;
- sh_timer_s() :
- handle(0)
+ std::function<void(const sh_timerHandle_t handle, void* userData)> 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; //!<handle to uniquely adress a filedesriptor
- std::function<void(const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData)> callback;
- void* userData;
- sh_signal_s() :
- handle(0), callback(), userData(0)
- {
- }
- };
+ struct sh_signal_s
+ {
+ sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
+ std::function<void(const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData)> callback;
+ void* userData;
+ sh_signal_s() :
+ handle(0), callback(), userData(0)
+ {}
+ };
- struct sh_identifier_s
- {
- std::set<sh_pollHandle_t> 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<sh_pollHandle_t> 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<sh_timer_s> rListTimerIter; //!<typedef for reverseiterator on timer lists
- typedef std::vector<pollfd> VectorListPollfd_t; //!<vector of filedescriptors
- typedef std::vector<sh_poll_s> VectorListPoll_t; //!<list for the callbacks
- typedef std::vector<sh_signal_s> VectorSignalHandlers_t; //!<list for the callbacks
+ typedef std::reverse_iterator<sh_timer_s> rListTimerIter; //!<typedef for reverseiterator on timer lists
+ typedef std::vector<pollfd> VectorListPollfd_t; //!<vector of filedescriptors
+ typedef std::vector<sh_poll_s> VectorListPoll_t; //!<list for the callbacks
+ typedef std::vector<sh_signal_s> VectorSignalHandlers_t; //!<list for the callbacks
- typedef enum:uint8_t
- {
- NO_ERROR = 0u, // OK
- PIPE_ERROR = 1u, // Pipe error
- FD_ERROR = 2u, // Invalid file descriptor
- SFD_ERROR = 4u // Signal file descriptor error
- } internal_error_codes_e;
- typedef uint8_t internal_error_codes_t;
-
- int mPipe[2];
- int mDispatchDone; //this starts / stops the mainloop
-
- sh_identifier_s mSetPollKeys; //!A set of all used ppoll keys
- VectorListPoll_t mListPoll; //!<list that holds all information for the ppoll
- sh_identifier_s mSetTimerKeys; //!A set of all used timer keys
- std::list<sh_timer_s> mListTimer; //!<list of all timers
- std::list<sh_timer_s> mListActiveTimer; //!<list of all currently active timers
- sh_identifier_s mSetSignalhandlerKeys; //!A set of all used signal handler keys
- VectorSignalHandlers_t mSignalHandlers;
- bool mRecreatePollfds; //!<when this is true, the poll list needs to be recreated
- internal_error_codes_t mError;
+ typedef enum:uint8_t
+ {
+ NO_ERROR = 0u, // OK
+ PIPE_ERROR = 1u, // Pipe error
+ FD_ERROR = 2u, // Invalid file descriptor
+ SFD_ERROR = 4u,
+ } internal_codes_e;
+ typedef uint8_t internal_codes_t;
+
+ int mPipe[2];
+ bool mDispatchDone; //this starts / stops the mainloop
+
+ sh_identifier_s mSetPollKeys; //!A set of all used ppoll keys
+ VectorListPoll_t mListPoll; //!<list that holds all information for the ppoll
+ sh_identifier_s mSetTimerKeys; //!A set of all used timer keys
+ std::list<sh_timer_s> mListTimer; //!<list of all timers
+ std::list<sh_timer_s> mListActiveTimer; //!<list of all currently active timers
+ sh_identifier_s mSetSignalhandlerKeys; //!A set of all used signal handler keys
+ VectorSignalHandlers_t mSignalHandlers;
+ bool mRecreatePollfds; //!<when this is true, the poll list needs to be recreated
+ internal_codes_t mInternalCodes;
+ sh_pollHandle_t mSignalFdHandle;
#ifndef WITH_TIMERFD
- timespec mStartTime; //!<here the actual time is saved for timecorrection
+ timespec mStartTime; //!<here the actual time is saved for timecorrection
#endif
- private:
- bool fdIsValid(const int fd) const;
+private:
+ bool fdIsValid(const int fd) const;
- timespec* insertTime(timespec& buffertime);
+ timespec* insertTime(timespec& buffertime);
#ifdef WITH_TIMERFD
- am_Error_e createTimeFD(const itimerspec & timeouts, int & fd);
+ am_Error_e createTimeFD(const itimerspec & timeouts, int & fd);
#else
- void timerUp();
- void timerCorrection();
-
- /**
- * compares countdown values
- * @param a
- * @param b
- * @return true if b greater a
- */
- inline static bool compareCountdown(const sh_timer_s& a, const sh_timer_s& b)
+ void timerUp();
+ void timerCorrection();
+
+ /**
+ * compares countdown values
+ * @param a
+ * @param b
+ * @return true if b greater a
+ */
+ inline static bool compareCountdown(const sh_timer_s& a, const sh_timer_s& b)
+ {
+ return ((a.countdown.tv_sec == b.countdown.tv_sec) ? (a.countdown.tv_nsec < b.countdown.tv_nsec) : (a.countdown.tv_sec < b.countdown.tv_sec));
+ }
+
+ /**
+ * Subtracts b from a
+ * @param a
+ * @param b
+ * @return subtracted value
+ */
+ inline static timespec timespecSub(const timespec& a, const timespec& b)
+ {
+ timespec result;
+
+ if ((a.tv_sec < b.tv_sec) || ((a.tv_sec == b.tv_sec) && (a.tv_nsec <= b.tv_nsec)))
{
- return ((a.countdown.tv_sec == b.countdown.tv_sec) ? (a.countdown.tv_nsec < b.countdown.tv_nsec) : (a.countdown.tv_sec < b.countdown.tv_sec));
+ result.tv_sec = result.tv_nsec = 0;
}
-
- /**
- * Subtracts b from a
- * @param a
- * @param b
- * @return subtracted value
- */
- inline static timespec timespecSub(const timespec& a, const timespec& b)
+ else
{
- timespec result;
-
- if ((a.tv_sec < b.tv_sec) || ((a.tv_sec == b.tv_sec) && (a.tv_nsec <= b.tv_nsec)))
+ result.tv_sec = a.tv_sec - b.tv_sec;
+ if (a.tv_nsec < b.tv_nsec)
{
- result.tv_sec = result.tv_nsec = 0;
+ result.tv_nsec = a.tv_nsec + MAX_NS - b.tv_nsec;
+ result.tv_sec--; /* Borrow a second. */
}
else
{
- result.tv_sec = a.tv_sec - b.tv_sec;
- if (a.tv_nsec < b.tv_nsec)
- {
- result.tv_nsec = a.tv_nsec + MAX_NS - b.tv_nsec;
- result.tv_sec--; /* Borrow a second. */
- }
- else
- {
- result.tv_nsec = a.tv_nsec - b.tv_nsec;
- }
+ result.tv_nsec = a.tv_nsec - b.tv_nsec;
}
- return (result);
}
+ return (result);
+ }
- /**
- * adds timespec values
- * @param a
- * @param b
- * @return the added values
- */
- inline timespec timespecAdd(const timespec& a, const timespec& b)
+ /**
+ * adds timespec values
+ * @param a
+ * @param b
+ * @return the added values
+ */
+ inline timespec timespecAdd(const timespec& a, const timespec& b)
+ {
+ 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)
{
- 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<void(const sh_pollHandle_t handle, void* userData)> prepare, std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> fired,
- std::function<bool(const sh_pollHandle_t handle, void* userData)> check, std::function<bool(const sh_pollHandle_t handle, void* userData)> 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<void(const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData)> 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<uint8_t> & listSignals);
+
+ am_Error_e addFDPoll(const int fd, const short event, std::function<void(const sh_pollHandle_t handle, void* userData)> prepare, std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> fired,
+ std::function<bool(const sh_pollHandle_t handle, void* userData)> check, std::function<bool(const sh_pollHandle_t handle, void* userData)> 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<void(const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData)> 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<void(const sh_timerHandle_t handle, void* userData)> callback, sh_timerHandle_t& handle, void* userData,
+ );
+ am_Error_e addTimer(const timespec & timeouts, std::function<void(const sh_timerHandle_t handle, void* userData)> 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<sh_poll_s> listPoll;
- VectorListPoll_t cloneListPoll;
- VectorListPoll_t::iterator listmPollIt;
- VectorListPollfd_t::iterator itMfdPollingArray;
- VectorListPollfd_t fdPollingArray; //!<the polling array for ppoll
-
- auto preparePollfd = [&](const sh_poll_s& row)
+ timespec buffertime;
+
+ std::list<sh_poll_s> listPoll;
+ VectorListPoll_t cloneListPoll;
+ VectorListPoll_t::iterator listmPollIt;
+ VectorListPollfd_t::iterator itMfdPollingArray;
+ VectorListPollfd_t fdPollingArray; //!<the polling array for ppoll
+
+ auto preparePollfd = [&](const sh_poll_s& row)
+ {
+ CAmSocketHandler::prepare((sh_poll_s&)row);
+ pollfd temp = row.pollfdValue;
+ temp.revents = 0;
+ fdPollingArray.push_back(temp);
+ };
+
+ while (!mDispatchDone)
+ {
+ if (mRecreatePollfds)
+ {
+ fdPollingArray.clear();
+ //freeze mListPoll by copying it - otherwise we get problems when we want to manipulate it during the next lines
+ cloneListPoll = mListPoll;
+ //there was a change in the setup, so we need to recreate the fdarray from the list
+ std::for_each(cloneListPoll.begin(), cloneListPoll.end(), preparePollfd);
+ mRecreatePollfds = false;
+ }
+ else
{
- CAmSocketHandler::prepare((sh_poll_s&)row);
- pollfd temp = row.pollfdValue;
- temp.revents = 0;
- fdPollingArray.push_back(temp);
- };
+ //first we go through the registered filedescriptors and check if someone needs preparation:
+ std::for_each(cloneListPoll.begin(), cloneListPoll.end(), CAmSocketHandler::prepare);
+ }
+
+#ifndef WITH_TIMERFD
+ timerCorrection();
+#endif
+ //block until something is on a filedescriptor
- while (!mDispatchDone)
+ if ((pollStatus = ppoll(&fdPollingArray[0], fdPollingArray.size(), insertTime(buffertime), NULL)) < 0)
{
- if (mRecreatePollfds)
+ if (errno == EINTR)
{
- fdPollingArray.clear();
- //freeze mListPoll by copying it - otherwise we get problems when we want to manipulate it during the next lines
- cloneListPoll = mListPoll;
- //there was a change in the setup, so we need to recreate the fdarray from the list
- std::for_each(cloneListPoll.begin(), cloneListPoll.end(), preparePollfd);
- mRecreatePollfds = false;
+ //a signal was received, that means it's time to go...
+ pollStatus = 0;
}
else
{
- //first we go through the registered filedescriptors and check if someone needs preparation:
- std::for_each(cloneListPoll.begin(), cloneListPoll.end(), CAmSocketHandler::prepare);
+ logError("SocketHandler::start_listenting ppoll returned with error", errno);
+ throw std::runtime_error(std::string("SocketHandler::start_listenting ppoll returned with error."));
}
+ }
-#ifndef WITH_TIMERFD
- timerCorrection();
-#endif
- //block until something is on a filedescriptor
-
- if ((pollStatus = ppoll(&fdPollingArray[0], fdPollingArray.size(), insertTime(buffertime), &sigmask)) < 0)
+ if (pollStatus != 0) //only check filedescriptors if there was a change
+ {
+ //todo: here could be a timer that makes sure naughty plugins return!
+ listPoll.clear();
+ //stage 0+1, call firedCB
+ for (itMfdPollingArray = fdPollingArray.begin(); itMfdPollingArray != fdPollingArray.end(); itMfdPollingArray++)
{
- if (errno == EINTR)
- {
- //a signal was received, that means it's time to go...
- pollStatus = 0;
- }
- else
- {
- logError("SocketHandler::start_listenting ppoll returned with error", errno);
- throw std::runtime_error(std::string("SocketHandler::start_listenting ppoll returned with error."));
+ if (CAmSocketHandler::eventFired(*itMfdPollingArray))
+ {
+ listmPollIt = cloneListPoll.begin();
+ std::advance(listmPollIt, std::distance(fdPollingArray.begin(), itMfdPollingArray));
+
+ listPoll.push_back(*listmPollIt);
+ CAmSocketHandler::fire(*listmPollIt);
}
}
+
+ //stage 2, lets ask around if some dispatching is necessary, the ones who need stay on the list
+ listPoll.remove_if(CAmSocketHandler::noDispatching);
- if (pollStatus != 0) //only check filedescriptors if there was a change
+ //stage 3, the ones left need to dispatch, we do this as long as there is something to dispatch..
+ do
{
- //todo: here could be a timer that makes sure naughty plugins return!
- listPoll.clear();
- //stage 0+1, call firedCB
- for (itMfdPollingArray = fdPollingArray.begin(); itMfdPollingArray != fdPollingArray.end(); itMfdPollingArray++)
- {
- if (CAmSocketHandler::eventFired(*itMfdPollingArray))
- {
- listmPollIt = cloneListPoll.begin();
- std::advance(listmPollIt, std::distance(fdPollingArray.begin(), itMfdPollingArray));
-
- listPoll.push_back(*listmPollIt);
- CAmSocketHandler::fire(*listmPollIt);
- }
- }
-
- //stage 2, lets ask around if some dispatching is necessary, the ones who need stay on the list
- listPoll.remove_if(CAmSocketHandler::noDispatching);
+ listPoll.remove_if(CAmSocketHandler::dispatchingFinished);
+ } while (!listPoll.empty());
- //stage 3, the ones left need to dispatch, we do this as long as there is something to dispatch..
- do
- {
- listPoll.remove_if(CAmSocketHandler::dispatchingFinished);
- } while (!listPoll.empty());
-
- }
-#ifndef WITH_TIMERFD
- else //Timerevent
- {
- //this was a timer event, we need to take care about the timers
- //find out the timedifference to starttime
- timerUp();
- }
-#endif
}
- }
-
- /**
- * exits the loop
- */
- void CAmSocketHandler::stop_listening()
- {
- mDispatchDone = 1;
#ifndef WITH_TIMERFD
- //this is for all running timers only - we need to handle the additional offset here
- if (!mListActiveTimer.empty())
+ else //Timerevent
{
- timespec currentTime, correctionTime;
- clock_gettime(CLOCK_MONOTONIC, &currentTime);
- correctionTime = timespecSub(currentTime, mStartTime);
- std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), [&correctionTime](sh_timer_s& t)
- { t.countdown = timespecSub(t.countdown, correctionTime);});
+ //this was a timer event, we need to take care about the timers
+ //find out the timedifference to starttime
+ timerUp();
}
#endif
}
+}
- void CAmSocketHandler::exit_mainloop()
+/**
+ * exits the loop
+ */
+void CAmSocketHandler::stop_listening()
+{
+ mDispatchDone = true;
+#ifndef WITH_TIMERFD
+ //this is for all running timers only - we need to handle the additional offset here
+ if (!mListActiveTimer.empty())
{
- //end the while loop
- stop_listening();
-
- //fire the ending filedescriptor
- int p(1);
- ssize_t result = write(mPipe[1], &p, sizeof(p));
+ timespec currentTime, correctionTime;
+ clock_gettime(CLOCK_MONOTONIC, &currentTime);
+ correctionTime = timespecSub(currentTime, mStartTime);
+ std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), [&correctionTime](sh_timer_s& t)
+ { t.countdown = timespecSub(t.countdown, correctionTime);});
}
+#endif
+}
- /**
- * Adds a signal handler filedescriptor to the polling loop
- *
- */
- am_Error_e CAmSocketHandler::addSignalFd()
- {
- sh_pollHandle_t handle;
- int fdErr;
- sigset_t sigset;
+void CAmSocketHandler::exit_mainloop()
+{
+ //end the while loop
+ stop_listening();
- /* Create a sigset of all the signals that we're interested in */
- fdErr = sigemptyset(&sigset);
- if (fdErr != 0)
+ //fire the ending filedescriptor
+ int p(1);
+ ssize_t result = write(mPipe[1], &p, sizeof(p));
+}
+
+bool CAmSocketHandler::fatalErrorOccurred()
+{
+ return ((mInternalCodes&internal_codes_e::PIPE_ERROR)>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<uint8_t> & 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<void(const sh_pollHandle_t handle, void* userData)> prepare,
+ std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> fired, std::function<bool(const sh_pollHandle_t handle, void* userData)> check,
+ std::function<bool(const sh_pollHandle_t handle, void* userData)> 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<void(const sh_pollHandle_t handle, void* userData)> prepare,
- std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> fired, std::function<bool(const sh_pollHandle_t handle, void* userData)> check,
- std::function<bool(const sh_pollHandle_t handle, void* userData)> 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<void(const sh_pollHandle_t handle, void* userData)> prepareCB; //preperation callback
+ std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> firedCB; //fired callback
+ std::function<bool(const sh_pollHandle_t handle, void* userData)> checkCB; //check callback
+ std::function<bool(const sh_pollHandle_t handle, void* userData)> 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<void(const sh_pollHandle_t handle, void* userData)> prepareCB; //preperation callback
- std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> firedCB; //fired callback
- std::function<bool(const sh_pollHandle_t handle, void* userData)> checkCB; //check callback
- std::function<bool(const sh_pollHandle_t handle, void* userData)> 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<void(const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData)> 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<void(const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData)> 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<void(const sh_timerHandle_t handle, void* userData)> callbackFunc;
- callbackFunc = std::bind(&IAmShTimerCallBack::Call, callback, std::placeholders::_1, std::placeholders::_2);
+ std::function<void(const sh_timerHandle_t handle, void* userData)> 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<void(const sh_timerHandle_t handle, void* userData)> 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<void(const sh_timerHandle_t handle, void* userData)> 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, &currentTime);
- 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, &currentTime);
+ 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<sh_timer_s>::iterator it = mListTimer.begin();
- for (; it != mListTimer.end(); ++it)
- {
- if (it->handle == handle)
- break;
- }
- if (it == mListTimer.end())
- return (E_NON_EXISTENT);
+ std::list<sh_timer_s>::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<sh_timer_s>::iterator it(mListTimer.begin());
- for (; it != mListTimer.end(); ++it)
+ stopTimer(handle);
+ std::list<sh_timer_s>::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<sh_timer_s>::iterator it = mListTimer.begin();
- for (; it != mListTimer.end(); ++it)
- {
- if (it->handle == handle)
- break;
- }
- if (it == mListTimer.end())
- return (E_NON_EXISTENT);
+ std::list<sh_timer_s>::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<sh_timer_s>::iterator it(mListTimer.begin()), activeIt(mListActiveTimer.begin());
- bool found(false);
- for (; it != mListTimer.end(); ++it)
+ //update the mList ....
+ sh_timer_s timerItem;
+ std::list<sh_timer_s>::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, &currentTime);
- 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, &currentTime);
+ 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<sh_timer_s>::iterator it = mListTimer.begin();
- for (; it != mListTimer.end(); ++it)
- {
- if (it->handle == handle)
- break;
- }
- if (it == mListTimer.end())
- return (E_NON_EXISTENT);
+ std::list<sh_timer_s>::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; //!<the original timer value
- //find the original value
- std::list<sh_timer_s>::iterator it(mListTimer.begin()), activeIt(mListActiveTimer.begin());
- bool found(false);
- for (; it != mListTimer.end(); ++it)
+ sh_timer_s timerItem; //!<the original timer value
+ //find the original value
+ std::list<sh_timer_s>::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, &currentTime);
- 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, &currentTime);
+ 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<sh_timer_s>::iterator it = mListTimer.begin();
- for (; it != mListTimer.end(); ++it)
- {
- if (it->handle == handle)
- break;
- }
- if (it == mListTimer.end())
- return (E_NON_EXISTENT);
+ std::list<sh_timer_s>::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<sh_timer_s>::iterator it(mListActiveTimer.begin());
- for (; it != mListActiveTimer.end(); ++it)
+ //go through the list and remove the timer with the handle
+ std::list<sh_timer_s>::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, &currentTime);
+ 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, &currentTime);
- 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<sh_timer_s>::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<sh_timer_s>::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), countdownUp);
+ //copy all fired timers into a list
+ std::vector<sh_timer_s> tempList(overflowIter, mListActiveTimer.rend());
- //copy all fired timers into a list
- std::vector<sh_timer_s> tempList(overflowIter, mListActiveTimer.rend());
+ //erase all fired timers
+ std::list<sh_timer_s>::iterator it(overflowIter.base());
+ mListActiveTimer.erase(mListActiveTimer.begin(), it);
- //erase all fired timers
- std::list<sh_timer_s>::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, &currentTime);
+ 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, &currentTime);
- 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<sh_timer_s>::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), countdownZero);
+ //find the last occurrence of zero -> timer overflowed
+ std::list<sh_timer_s>::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<sh_timer_s> 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<sh_timer_s> tempList(overflowIter, mListActiveTimer.rend());
- //erase all fired timers
- std::list<sh_timer_s>::iterator it(overflowIter.base());
- mListActiveTimer.erase(mListActiveTimer.begin(), it);
+ //erase all fired timers
+ std::list<sh_timer_s>::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<std::chrono::high_resolution_clock> 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<unsigned> signals;
- signals.insert(SIGHUP);
- signals.insert(SIGINT);
- signals.insert(SIGTERM);
- signals.insert(SIGQUIT);
+ std::set<unsigned> secondarySignals;
+ secondarySignals.insert({SIGHUP,SIGTERM, SIGCHLD});
+ std::set<unsigned> primarySignals({SIGQUIT,SIGINT});
+ std::set<unsigned> 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)
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','');});
<div class="line"><a name="l00204"></a><span class="lineno"> 204</span>&#160; <span class="keywordflow">switch</span> (sig)</div>
<div class="line"><a name="l00205"></a><span class="lineno"> 205</span>&#160; {</div>
<div class="line"><a name="l00206"></a><span class="lineno"> 206</span>&#160; <span class="comment">/*ctl +c lets call direct controllerRundown, because we might be blocked at the moment.</span></div>
-<div class="line"><a name="l00207"></a><span class="lineno"> 207</span>&#160;<span class="comment"> But there is the risk of interrupting something important */</span>https:<span class="comment">//asc.bmwgroup.net/wiki/display/MGUROTO/Lastest+and+greatest</span></div>
+<div class="line"><a name="l00207"></a><span class="lineno"> 207</span>&#160;<span class="comment"> But there is the risk of interrupting something important */</span></div>
<div class="line"><a name="l00208"></a><span class="lineno"> 208</span>&#160; <span class="keywordflow">case</span> SIGINT:</div>
<div class="line"><a name="l00209"></a><span class="lineno"> 209</span>&#160; <a class="code" href="classam_1_1CAmControlSender.html#a347a2af727aeb11657f145329dd23dd8">CAmControlSender::CallsetControllerRundown</a>(sig);</div>
<div class="line"><a name="l00210"></a><span class="lineno"> 210</span>&#160; <span class="keywordflow">break</span>;</div>