summaryrefslogtreecommitdiff
path: root/AudioManagerUtilities/src/CAmSocketHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'AudioManagerUtilities/src/CAmSocketHandler.cpp')
-rw-r--r--AudioManagerUtilities/src/CAmSocketHandler.cpp1172
1 files changed, 675 insertions, 497 deletions
diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp
index 1092198..56df45c 100644
--- a/AudioManagerUtilities/src/CAmSocketHandler.cpp
+++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp
@@ -15,13 +15,13 @@
*
*
* \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ * \author Aleksandar Donchev, aleksander.donchev@partner.bmw.de BMW 2017
*
* \file CAmSocketHandler.cpp
* For further information see http://www.genivi.org/.
*
*/
-#include "CAmSocketHandler.h"
#include <cassert>
#include <sys/fcntl.h>
#include <sys/errno.h>
@@ -32,618 +32,796 @@
#include <csignal>
#include <unistd.h>
#include "CAmDltWrapper.h"
+#include "CAmSocketHandler.h"
-namespace am
-{
+#ifdef WITH_TIMERFD
+#include <sys/timerfd.h>
+#endif
-CAmSocketHandler::CAmSocketHandler() :
- receiverCallbackT(this, &CAmSocketHandler::receiverCallback),//
- checkerCallbackT(this, &CAmSocketHandler::checkerCallback),//
- mPipe(), //
- mDispatchDone(1),//
- mListPoll(), //
- mListTimer(), //
- mListActiveTimer(), //
- mLastInsertedHandle(0), //
- mLastInsertedPollHandle(0), //
- mRecreatePollfds(true), //
- mStartTime() //
-{
- if (pipe(mPipe) == -1)
- {
- logError("Sockethandler could not create pipe!");
- }
-
- //add the pipe to the poll - nothing needs to be proccessed here we just need the pipe to trigger the ppoll
- short event = 0;
- sh_pollHandle_t handle;
- event |= POLLIN;
- addFDPoll(mPipe[0], event, NULL, &receiverCallbackT, &checkerCallbackT, NULL, NULL, handle);
-}
-
-CAmSocketHandler::~CAmSocketHandler()
+namespace am
{
- 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);
-
- clock_gettime(CLOCK_MONOTONIC, &mStartTime);
- while (!mDispatchDone)
+ CAmSocketHandler::CAmSocketHandler() :
+ mReceiverCallbackT(this, &CAmSocketHandler::receiverCallback), //
+ mCheckerCallbackT(this, &CAmSocketHandler::checkerCallback), //
+#ifdef WITH_TIMERFD
+ mTimerCallbackT(), //
+#endif
+ mPipe(), //
+ mDispatchDone(1), //
+ mListPoll(), //
+ mListTimer(), //
+ mListActiveTimer(), //
+ mLastInsertedHandle(0), //
+ mLastInsertedPollHandle(0), //
+ mRecreatePollfds(true)
+#ifndef WITH_TIMERFD
+ ,mStartTime() //
+#endif
{
- //first we go through the registered filedescriptors and check if someone needs preparation:
- std::for_each(mListPoll.begin(), mListPoll.end(), CAmShCallPrep());
-
- if (mRecreatePollfds)
+ if (pipe(mPipe) == -1)
{
- mfdPollingArray.clear();
- //there was a change in the setup, so we need to recreate the fdarray from the list
- std::for_each(mListPoll.begin(), mListPoll.end(), CAmShCopyPollfd(mfdPollingArray));
- mRecreatePollfds = false;
+ logError("Sockethandler could not create pipe!");
}
- timerCorrection();
-
- //block until something is on a filedescriptor
+ //add the pipe to the poll - nothing needs to be proccessed here we just need the pipe to trigger the ppoll
+ short event = 0;
+ sh_pollHandle_t handle;
+ event |= POLLIN;
+ addFDPoll(mPipe[0], event, NULL, &mReceiverCallbackT, &mCheckerCallbackT, NULL, NULL, handle);
+ }
- timespec buffertime;
- if ((pollStatus = ppoll(&mfdPollingArray[0], mfdPollingArray.size(), insertTime(buffertime), &sigmask)) < 0)
+ CAmSocketHandler::~CAmSocketHandler()
+ {
+#ifdef WITH_TIMERFD
+ for(auto it: mListTimer)
{
- 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."));
- }
+ close(it.fd);
}
+#endif
+ close(mPipe[0]);
+ close(mPipe[1]);
+ }
- if (pollStatus != 0) //only check filedescriptors if there was a change
+//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);
+#ifndef WITH_TIMERFD
+ clock_gettime(CLOCK_MONOTONIC, &mStartTime);
+#endif
+ while (!mDispatchDone)
{
- //todo: here could be a timer that makes sure naughty plugins return!
+ //first we go through the registered filedescriptors and check if someone needs preparation:
+ std::for_each(mListPoll.begin(), mListPoll.end(), CAmShCallPrep());
- //freeze mListPoll by copying it - otherwise we get problems when we want to manipulate it during the next lines
- std::list<sh_poll_s> listPoll;
- mListPoll_t::iterator listmPollIt;
+ if (mRecreatePollfds)
+ {
+ mfdPollingArray.clear();
+ //there was a change in the setup, so we need to recreate the fdarray from the list
+ std::for_each(mListPoll.begin(), mListPoll.end(), CAmShCopyPollfd(mfdPollingArray));
+ mRecreatePollfds = false;
+ }
+#ifndef WITH_TIMERFD
+ timerCorrection();
+#endif
+ //block until something is on a filedescriptor
- //remove all filedescriptors who did not fire
- std::vector<pollfd>::iterator it = mfdPollingArray.begin();
- do
+ timespec buffertime;
+ if ((pollStatus = ppoll(&mfdPollingArray[0], mfdPollingArray.size(), insertTime(buffertime), &sigmask)) < 0)
{
- it = std::find_if(it, mfdPollingArray.end(), eventFired);
- if (it != mfdPollingArray.end())
+ if (errno == EINTR)
{
- listmPollIt = mListPoll.begin();
- std::advance(listmPollIt, std::distance(mfdPollingArray.begin(), it));
- listPoll.push_back(*listmPollIt);
- listPoll.back().pollfdValue = *it;
- it++;
+ //a signal was received, that means it's time to go...
+ pollStatus = 0;
}
- } while (it != mfdPollingArray.end());
+ else
+ {
+ logError("SocketHandler::start_listenting ppoll returned with error", errno);
+ throw std::runtime_error(std::string("SocketHandler::start_listenting ppoll returned with error."));
+ }
+ }
+
+ if (pollStatus != 0) //only check filedescriptors if there was a change
+ {
+ //todo: here could be a timer that makes sure naughty plugins return!
- //stage 1, call firedCB
- std::for_each(listPoll.begin(), listPoll.end(), CAmShCallFire());
+ //freeze mListPoll by copying it - otherwise we get problems when we want to manipulate it during the next lines
+ std::list<sh_poll_s> listPoll;
+ mListPoll_t::iterator listmPollIt;
- //stage 2, lets ask around if some dispatching is necessary, the ones who need stay on the list
- listPoll.remove_if(noDispatching);
+ //remove all filedescriptors who did not fire
+ std::vector<pollfd>::iterator it = mfdPollingArray.begin();
+ do
+ {
+ it = std::find_if(it, mfdPollingArray.end(), eventFired);
+ if (it != mfdPollingArray.end())
+ {
+ listmPollIt = mListPoll.begin();
+ std::advance(listmPollIt, std::distance(mfdPollingArray.begin(), it));
+ listPoll.push_back(*listmPollIt);
+ listPoll.back().pollfdValue = *it;
+ it++;
+ }
+ } while (it != mfdPollingArray.end());
+
+ //stage 1, call firedCB
+ std::for_each(listPoll.begin(), listPoll.end(), CAmShCallFire());
+
+ //stage 2, lets ask around if some dispatching is necessary, the ones who need stay on the list
+ listPoll.erase(std::remove_if(listPoll.begin(), listPoll.end(), noDispatching), listPoll.end());
+
+ //stage 3, the ones left need to dispatch, we do this as long as there is something to dispatch..
+ do
+ {
+ listPoll.erase(std::remove_if(listPoll.begin(), listPoll.end(), dispatchingFinished), listPoll.end());
+ } while (!listPoll.empty());
- //stage 3, the ones left need to dispatch, we do this as long as there is something to dispatch..
- do
+ }
+#ifndef WITH_TIMERFD
+ else //Timerevent
{
- listPoll.remove_if(dispatchingFinished);
- } while (!listPoll.empty());
-
+ //this was a timer event, we need to take care about the timers
+ timerUp();
+ }
+#endif
}
- else //Timerevent
+ }
+
+ /**
+ * 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())
{
- //this was a timer event, we need to take care about the timers
- timerUp();
+ timespec currentTime, correctionTime;
+ clock_gettime(CLOCK_MONOTONIC, &currentTime);
+ correctionTime = timespecSub(currentTime, mStartTime);
+ std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), CAmShSubstractTime(correctionTime));
}
+#endif
}
-}
-
-/**
- * exits the loop
- */
-void CAmSocketHandler::stop_listening()
-{
- mDispatchDone = 1;
- //this is for all running timers only - we need to handle the additional offset here
- if (!mListActiveTimer.empty())
+ void CAmSocketHandler::exit_mainloop()
{
- timespec currentTime, correctionTime;
- clock_gettime(CLOCK_MONOTONIC, &currentTime);
- correctionTime = timespecSub(currentTime, mStartTime);
- std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), CAmShSubstractTime(correctionTime));
- }
+ //end the while loop
+ stop_listening();
-}
+ //fire the ending filedescriptor
+ int p(1);
+ ssize_t result = write(mPipe[1], &p, sizeof(p));
+ }
-/**
- * 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_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void *userData, sh_pollHandle_t & handle)
-{
- if (!fdIsValid(fd))
- return (E_NON_EXISTENT);
-
- //create a new handle for the poll
- sh_pollHandle_t lastHandle(mLastInsertedPollHandle);
- do
+ /**
+ * 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)
{
- ++mLastInsertedPollHandle;
- if (mLastInsertedPollHandle == MAX_POLLHANDLE)
- {
- mLastInsertedPollHandle = 1;
- }
- if (mLastInsertedPollHandle==lastHandle)
- {
- logError(__func__,"Could not create new polls, too many open!");
- return (am_Error_e::E_NOT_POSSIBLE);
- }
-
- } while (mSetPollKeys.find(mLastInsertedPollHandle) != mSetPollKeys.end());
-
- mSetPollKeys.insert(mLastInsertedPollHandle);
-
- sh_poll_s pollData;
- pollData.pollfdValue.fd = fd;
- pollData.handle = mLastInsertedPollHandle;
- pollData.pollfdValue.events = event;
- pollData.pollfdValue.revents = 0;
- pollData.userData = userData;
- pollData.prepareCB = prepare;
- pollData.firedCB = fired;
- pollData.checkCB = check;
- pollData.dispatchCB = dispatch;
-
- //add new data to the list
- mListPoll.push_back(pollData);
-
- mRecreatePollfds = true;
-
- handle = pollData.handle;
- return (E_OK);
-}
+ if (!fdIsValid(fd))
+ return (E_NON_EXISTENT);
-/**
- * removes a filedescriptor from the poll loop
- * @param handle
- * @return
- */
-am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle)
-{
- mListPoll_t::iterator iterator = mListPoll.begin();
+ //create a new handle for the poll
+ sh_pollHandle_t lastHandle(mLastInsertedPollHandle);
+ do
+ {
+ ++mLastInsertedPollHandle;
+ if (mLastInsertedPollHandle == MAX_POLLHANDLE)
+ {
+ mLastInsertedPollHandle = 1;
+ }
+ if (mLastInsertedPollHandle == lastHandle)
+ {
+ logError("Could not create new polls, too many open!");
+ return (E_NOT_POSSIBLE);
+ }
- for (; iterator != mListPoll.end(); ++iterator)
+ } while (mSetPollKeys.find(mLastInsertedPollHandle) != mSetPollKeys.end());
+
+ mSetPollKeys.insert(mLastInsertedPollHandle);
+
+ sh_poll_s pollData;
+ pollData.pollfdValue.fd = fd;
+ pollData.handle = mLastInsertedPollHandle;
+ pollData.pollfdValue.events = event;
+ pollData.pollfdValue.revents = 0;
+ pollData.userData = userData;
+ pollData.prepareCB = prepare;
+ pollData.firedCB = fired;
+ pollData.checkCB = check;
+ pollData.dispatchCB = dispatch;
+
+ //add new data to the list
+ mListPoll.push_back(pollData);
+
+ mRecreatePollfds = true;
+
+ handle = pollData.handle;
+ return (E_OK);
+ }
+
+ /**
+ * removes a filedescriptor from the poll loop
+ * @param handle
+ * @return
+ */
+ am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle)
{
- if (iterator->handle == handle)
+ mListPoll_t::iterator iterator = mListPoll.begin();
+
+ for (; iterator != mListPoll.end(); ++iterator)
{
- iterator = mListPoll.erase(iterator);
- mSetPollKeys.erase(handle);
- mRecreatePollfds = true;
- return (E_OK);
+ if (iterator->handle == handle)
+ {
+ iterator = mListPoll.erase(iterator);
+ mSetPollKeys.erase(handle);
+ mRecreatePollfds = true;
+ 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)
-{
- assert(!((timeouts.tv_sec==0) && (timeouts.tv_nsec==0)));
- 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(!((timeouts.tv_sec == 0) && (timeouts.tv_nsec == 0)));
+ assert(callback!=NULL);
- sh_timer_s timerItem;
+ mListTimer.emplace_back();
+ sh_timer_s & timerItem = mListTimer.back();
- //create a new handle for the timer
- sh_timerHandle_t lastTimerHandle(mLastInsertedHandle);
- do
- {
- ++mLastInsertedHandle;
- if (mLastInsertedHandle == MAX_TIMERHANDLE)
- {
- mLastInsertedHandle = 1;
- }
- if (lastTimerHandle==mLastInsertedHandle)
- {
- logError(__func__,"Could not create new timers, too many open!");
- return (am_Error_e::E_NOT_POSSIBLE);
- }
-
- } while (mSetTimerKeys.find(mLastInsertedHandle) != mSetTimerKeys.end());
-
- mSetTimerKeys.insert(mLastInsertedHandle);
- handle=mLastInsertedHandle;
- timerItem.handle = handle;
- timerItem.countdown = timeouts;
- timerItem.callback = callback;
- timerItem.userData = userData;
-
- mListTimer.push_back(timerItem);
-
- //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));
-
- mListActiveTimer.push_back(timerItem);
- mListActiveTimer.sort(compareCountdown);
- return (E_OK);
-}
+#ifndef WITH_TIMERFD
+ //create a new handle for the timer
+ sh_timerHandle_t lastTimerHandle(mLastInsertedHandle);
+ do
+ {
+ ++mLastInsertedHandle;
+ if (mLastInsertedHandle == MAX_TIMERHANDLE)
+ {
+ mLastInsertedHandle = 1;
+ }
+ if (lastTimerHandle==mLastInsertedHandle)
+ {
+ logError("Could not create new timers, too many open!");
+ mListTimer.pop_back();
+ return (E_NOT_POSSIBLE);
+ }
-/**
- * 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);
+ }while (mSetTimerKeys.find(mLastInsertedHandle) != mSetTimerKeys.end());
- //stop the current timer
- stopTimer(handle);
+ mSetTimerKeys.insert(mLastInsertedHandle);
+ handle=mLastInsertedHandle;
- std::list<sh_timer_s>::iterator it(mListTimer.begin());
- for (; it != mListTimer.end(); ++it)
- {
- if (it->handle == handle)
+ timerItem.countdown = timeouts;
+ timerItem.callback = callback;
+ timerItem.userData = userData;
+
+ 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);
+
+#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.callback = callback;
+ timerItem.userData = userData;
+ timerItem.fd = -1;
+ am_Error_e err = createTimeFD(timerItem.countdown, timerItem.fd);
+ if (err != E_OK)
{
- it = mListTimer.erase(it);
- mSetTimerKeys.erase(handle);
- return (E_OK);
+ mListTimer.pop_back();
+ return err;
}
+ mTimerCallbackT.emplace_back(callback);
+
+ err = addFDPoll(timerItem.fd, POLLIN, NULL, &mTimerCallbackT.back(), &mTimerCallbackT.back(), NULL, NULL, handle);
+ if (E_OK == err)
+ {
+ timerItem.handle = handle;
+ }
+ else
+ {
+ mTimerCallbackT.pop_back();
+ mListTimer.pop_back();
+ }
+ return err;
+#endif
+
}
- return (E_UNKNOWN);
-}
-/**
- * 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)
-{
- //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)
+ /**
+ * 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)
{
- if (it->handle == 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);
+
+ 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)
{
- it->countdown = timeouts;
- timerItem = *it;
- found = true;
- break;
+ if (it->handle == handle)
+ {
+ it = mListTimer.erase(it);
+ mSetTimerKeys.erase(handle);
+ return (E_OK);
+ }
}
+ return (E_UNKNOWN);
+#endif
}
- if (!found)
+
+ /**
+ * 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);
+
+ 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 (timerfd_settime(it->fd, 0, &it->countdown, NULL))
+ {
+ 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)
+ {
+ if (it->handle == handle)
+ {
+ it->countdown = timeouts;
+ timerItem = *it;
+ found = true;
+ break;
+ }
+ }
+ 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
+ //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)
- {
- if (activeIt->handle == handle)
+ for (; activeIt != mListActiveTimer.end(); ++activeIt)
{
- activeIt->countdown = timeoutsCorrected;
- found = true;
- break;
+ if (activeIt->handle == handle)
+ {
+ activeIt->countdown = timeoutsCorrected;
+ found = true;
+ break;
+ }
}
- }
- if (!found)
+ if (!found)
timerItem.countdown = timeoutsCorrected;
- mListActiveTimer.push_back(timerItem);
+ mListActiveTimer.push_back(timerItem);
- mListActiveTimer.sort(compareCountdown);
- return (E_OK);
-}
+ mListActiveTimer.sort(compareCountdown);
-/**
- * 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)
-{
- 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)
+#endif
+ 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)
{
- if (it->handle == handle)
+#ifdef WITH_TIMERFD
+ std::list<sh_timer_s>::iterator it = mListTimer.begin();
+ for (; it != mListTimer.end(); ++it)
{
- timerItem = *it;
- found = true;
- break;
+ if (it->handle == handle)
+ break;
}
- }
- if (!found)
+ 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 (timerfd_settime(it->fd, 0, &it->countdown, NULL))
+ {
+ 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)
+ {
+ if (it->handle == handle)
+ {
+ timerItem = *it;
+ found = true;
+ break;
+ }
+ }
+ 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)
- {
- if (activeIt->handle == handle)
+ for (; activeIt != mListActiveTimer.end(); ++activeIt)
{
- activeIt->countdown = timerItem.countdown;
- found = true;
- break;
+ if (activeIt->handle == handle)
+ {
+ activeIt->countdown = timerItem.countdown;
+ found = true;
+ break;
+ }
}
- }
- if (!found)
+ if (!found)
mListActiveTimer.push_back(timerItem);
- mListActiveTimer.sort(compareCountdown);
-
- return (E_OK);
-}
+ mListActiveTimer.sort(compareCountdown);
+#endif
+ 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)
-{
- //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)
+ /**
+ * 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)
{
- if (it->handle == handle)
+#ifdef WITH_TIMERFD
+ std::list<sh_timer_s>::iterator it = mListTimer.begin();
+ for (; it != mListTimer.end(); ++it)
{
- it = mListActiveTimer.erase(it);
- return (E_OK);
+ if (it->handle == handle)
+ break;
}
- }
- return (E_NON_EXISTENT);
-}
+ if (it == mListTimer.end())
+ return (E_NON_EXISTENT);
-/**
- * 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)
-{
- mListPoll_t::iterator iterator = mListPoll.begin();
+ itimerspec countdown = it->countdown;
+ countdown.it_value.tv_nsec = 0;
+ countdown.it_value.tv_sec = 0;
- for (; iterator != mListPoll.end(); ++iterator)
- {
- if (iterator->handle == handle)
+ if (timerfd_settime(it->fd, 0, &countdown, NULL))
{
- iterator->pollfdValue.events = events;
- mRecreatePollfds = true;
- return (E_OK);
+ logError("Failed to set timer duration");
+ return E_NOT_POSSIBLE;
}
+#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)
+ {
+ if (it->handle == handle)
+ {
+ it = mListActiveTimer.erase(it);
+ return (E_OK);
+ }
+ }
+ return (E_NON_EXISTENT);
+#endif
}
- 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);
-}
+ /**
+ * 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)
+ {
+ mListPoll_t::iterator iterator = mListPoll.begin();
-/**
- * timer is up.
- */
-void CAmSocketHandler::timerUp()
-{
- //find out the timedifference to starttime
- timespec currentTime, diffTime;
- clock_gettime(CLOCK_MONOTONIC, &currentTime);
- diffTime = timespecSub(currentTime, mStartTime);
+ for (; iterator != mListPoll.end(); ++iterator)
+ {
+ if (iterator->handle == handle)
+ {
+ iterator->pollfdValue.events = events;
+ mRecreatePollfds = true;
+ return (E_OK);
+ }
+ }
+ return (E_UNKNOWN);
+ }
- //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(), CAmShCountdownUp(diffTime));
+ /**
+ * 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);
+ }
- //copy all fired timers into a list
- std::vector<sh_timer_s> tempList(overflowIter, mListActiveTimer.rend());
+#ifndef WITH_TIMERFD
+ /**
+ * timer is up.
+ */
+ void CAmSocketHandler::timerUp()
+ {
+ //find out the timedifference to starttime
+ timespec currentTime, diffTime;
+ clock_gettime(CLOCK_MONOTONIC, &currentTime);
+ diffTime = timespecSub(currentTime, mStartTime);
- //erase all fired timers
- std::list<sh_timer_s>::iterator it(overflowIter.base());
- mListActiveTimer.erase(mListActiveTimer.begin(), it);
+ //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(), CAmShCountdownUp(diffTime));
- //call the callbacks for the timers
- std::for_each(tempList.begin(), tempList.end(), CAmShCallTimer());
-}
+ //copy all fired timers into a list
+ std::vector<sh_timer_s> tempList(overflowIter, mListActiveTimer.rend());
-/**
- * correct timers and fire the ones who are up
- */
-void CAmSocketHandler::timerCorrection()
-{
- //get the current time and calculate the correction value
- timespec currentTime, correctionTime;
- clock_gettime(CLOCK_MONOTONIC, &currentTime);
- correctionTime = timespecSub(currentTime, mStartTime);
- mStartTime = currentTime;
+ //erase all fired timers
+ std::list<sh_timer_s>::iterator it(overflowIter.base());
+ mListActiveTimer.erase(mListActiveTimer.begin(), it);
- if (!mListActiveTimer.empty())
+ //call the callbacks for the timers
+ std::for_each(tempList.begin(), tempList.end(), CAmShCallTimer());
+ }
+
+ /**
+ * correct timers and fire the ones who are up
+ */
+ void CAmSocketHandler::timerCorrection()
{
+ //get the current time and calculate the correction value
+ timespec currentTime, correctionTime;
+ clock_gettime(CLOCK_MONOTONIC, &currentTime);
+ correctionTime = timespecSub(currentTime, mStartTime);
+ mStartTime = currentTime;
- //subtract the correction value from all items in the list
- std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), CAmShSubstractTime(correctionTime));
+ if (!mListActiveTimer.empty())
+ {
- //find the last occurrence of zero -> timer overflowed
- std::list<sh_timer_s>::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), CAmShCountdownZero());
+ //subtract the correction value from all items in the list
+ std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), CAmShSubstractTime(correctionTime));
- //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());
+ //find the last occurrence of zero -> timer overflowed
+ std::list<sh_timer_s>::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), CAmShCountdownZero());
+
+ //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(), CAmShCallTimer());
+ //call the callbacks for the timers
+ std::for_each(tempList.begin(), tempList.end(), CAmShCallTimer());
+ }
+ }
+ }
+#endif
+ /**
+ * 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
+#endif
+ {
+ return (NULL);
}
}
-}
-void CAmSocketHandler::exit_mainloop()
-{
- //end the while loop
- stop_listening();
+#ifdef WITH_TIMERFD
+ am_Error_e CAmSocketHandler::createTimeFD(const itimerspec & timeouts, int & fd)
+ {
+ fd = timerfd_create(CLOCK_MONOTONIC, 0);
+ if (fd <= 0)
+ {
+ logError("Failed to create timer");
+ return E_NOT_POSSIBLE;
+ }
+ if (fcntl(fd, F_SETFL, O_NONBLOCK))
+ {
+ logError("Failed to set to non blocking mode");
+ return E_NOT_POSSIBLE;
+ }
- //fire the ending filedescriptor
- int p(1);
- ssize_t result = write(mPipe[1], &p, sizeof(p));
-}
+ if (timerfd_settime(fd, 0, &timeouts, NULL))
+ {
+ logError("Failed to set timer duration");
+ return E_NOT_POSSIBLE;
+ }
+ return E_OK;
+ }
+#endif
-/**
- * is used to set the pointer for the ppoll command
- * @param buffertime
- * @return
- */
-inline timespec* CAmSocketHandler::insertTime(timespec& buffertime)
-{
- if (!mListActiveTimer.empty())
+ void CAmSocketHandler::CAmShCallFire::operator()(sh_poll_s& row)
{
- buffertime = mListActiveTimer.front().countdown;
- return (&buffertime);
+ try
+ {
+ row.firedCB->Call(row.pollfdValue, row.handle, row.userData);
+ } catch (std::exception& e)
+ {
+ logError("Sockethandler: Exception in FireCallback,caught", e.what());
+ }
}
- else
+
+ void CAmSocketHandler::CAmShCallPrep::operator()(sh_poll_s& row)
{
- return (NULL);
+ if (row.prepareCB)
+ {
+ try
+ {
+ row.prepareCB->Call(row.handle, row.userData);
+ } catch (std::exception& e)
+ {
+ logError("Sockethandler: Exception in Preparecallback,caught", e.what());
+ }
+ }
}
-}
-
-void CAmSocketHandler::CAmShCallFire::operator()(sh_poll_s& row)
-{
- try
- {
- row.firedCB->Call(row.pollfdValue, row.handle, row.userData);
- }
- catch (std::exception& e)
- {
- logError("Sockethandler: Exception in FireCallback,caught",e.what());
- }
-}
-
-void CAmSocketHandler::CAmShCallPrep::operator()(sh_poll_s& row)
-{
- if (row.prepareCB)
- {
- try
- {
- row.prepareCB->Call(row.handle, row.userData);
- }
- catch (std::exception& e)
- {
- logError("Sockethandler: Exception in Preparecallback,caught",e.what());
- }
- }
-}
-void CAmSocketHandler::CAmShCallTimer::operator()(sh_timer_s& row)
-{
- try
- {
- row.callback->Call(row.handle, row.userData);
- }
- catch (std::exception& e)
- {
- logError("Sockethandler: Exception in Timercallback,caught",e.what());
- }
-}
+ void CAmSocketHandler::CAmShCallTimer::operator()(sh_timer_s& row)
+ {
+ try
+ {
+ row.callback->Call(row.handle, row.userData);
+ } catch (std::exception& e)
+ {
+ logError("Sockethandler: Exception in Timercallback,caught", e.what());
+ }
+ }
-void CAmSocketHandler::CAmShCopyPollfd::operator()(const sh_poll_s& row)
-{
- pollfd temp = row.pollfdValue;
- temp.revents = 0;
- mArray.push_back(temp);
-}
+ void CAmSocketHandler::CAmShCopyPollfd::operator()(const sh_poll_s& row)
+ {
+ pollfd temp = row.pollfdValue;
+ temp.revents = 0;
+ mArray.push_back(temp);
+ }
+#ifndef WITH_TIMERFD
bool CAmSocketHandler::CAmShCountdownUp::operator()(const sh_timer_s& row)
{
- timespec sub = timespecSub(row.countdown, mDiffTime);
- if (sub.tv_nsec == 0 && sub.tv_sec == 0)
- return (true);
- return (false);
+ timespec sub = timespecSub(row.countdown, mDiffTime);
+ if (sub.tv_nsec == 0 && sub.tv_sec == 0)
+ return (true);
+ return (false);
}
bool CAmSocketHandler::CAmShCountdownZero::operator()(const sh_timer_s& row)
{
- 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);
}
-
+#endif
}