summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksandar Donchev <Aleksander.Donchev@partner.bmw.de>2017-09-26 16:07:00 +0200
committerJacqueline Molz <Jacqueline.Molz@bmw.de>2017-11-06 11:34:39 +0100
commitcee30860cefff89ba258537f2bd6178596b88ba9 (patch)
treea15c9f081653706d4f28209fe6752265f1caa4cc
parent964cee3684c97494106ee287bc33ace3db8fd8c2 (diff)
downloadaudiomanager-cee30860cefff89ba258537f2bd6178596b88ba9.tar.gz
A filedescriptor removal will set an invalidation flag which will prevent calls on the invalidated objects in the current iteration.
Signed-off-by: Christian Linke <christian.linke@bmw.de> Change-Id: I9d5d3c434ac9fad62c76a76145c731b538aeb1e3
-rw-r--r--AudioManagerUtilities/include/CAmSocketHandler.h11
-rw-r--r--AudioManagerUtilities/src/CAmSocketHandler.cpp58
-rw-r--r--AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp9
3 files changed, 50 insertions, 28 deletions
diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h
index 7baa496..d14c1a3 100644
--- a/AudioManagerUtilities/include/CAmSocketHandler.h
+++ b/AudioManagerUtilities/include/CAmSocketHandler.h
@@ -217,6 +217,7 @@ class CAmSocketHandler
{
struct sh_poll_s //!<struct that holds information about polls
{
+ bool isValid;
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
@@ -226,7 +227,7 @@ class CAmSocketHandler
void* userData;
sh_poll_s() :
- handle(0), pollfdValue(), prepareCB(), firedCB(), checkCB(), dispatchCB(), userData(0)
+ isValid(true), handle(0), pollfdValue(), prepareCB(), firedCB(), checkCB(), dispatchCB(), userData(0)
{}
};
@@ -302,9 +303,11 @@ class CAmSocketHandler
bool mRecreatePollfds; //!<when this is true, the poll list needs to be recreated
internal_codes_t mInternalCodes;
sh_pollHandle_t mSignalFdHandle;
+ VectorListPoll_t mListActivePolls;
#ifndef WITH_TIMERFD
timespec mStartTime; //!<here the actual time is saved for timecorrection
#endif
+
private:
bool fdIsValid(const int fd) const;
@@ -413,7 +416,7 @@ private:
* @param a
* @return
*/
- inline static void fire(sh_poll_s& a);
+ inline static void fire(const sh_poll_s* a);
/**
* functor to return all fired events
@@ -427,14 +430,14 @@ private:
* @param a
* @return
*/
- inline static bool noDispatching(const sh_poll_s& a);
+ 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);
+ inline static bool dispatchingFinished(const sh_poll_s* a);
/**
* timer fire callback
diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp
index 9ed3085..54ba4ef 100644
--- a/AudioManagerUtilities/src/CAmSocketHandler.cpp
+++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp
@@ -58,7 +58,8 @@ CAmSocketHandler::CAmSocketHandler() :
mSignalHandlers(), //
mRecreatePollfds(true),
mInternalCodes(internal_codes_e::NO_ERROR),
- mSignalFdHandle(0)
+ mSignalFdHandle(0),
+ mListActivePolls()
#ifndef WITH_TIMERFD
,mStartTime() //
#endif
@@ -106,8 +107,7 @@ void CAmSocketHandler::start_listenting()
#endif
timespec buffertime;
- std::list<sh_poll_s> listPoll;
- VectorListPoll_t cloneListPoll;
+ std::list<sh_poll_s*> listPoll;
VectorListPoll_t::iterator listmPollIt;
VectorListPollfd_t::iterator itMfdPollingArray;
VectorListPollfd_t fdPollingArray; //!<the polling array for ppoll
@@ -129,15 +129,15 @@ void CAmSocketHandler::start_listenting()
#endif
fdPollingArray.clear();
//freeze mListPoll by copying it - otherwise we get problems when we want to manipulate it during the next lines
- cloneListPoll = mListPoll;
+ mListActivePolls = 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);
+ std::for_each(mListActivePolls.begin(), mListActivePolls.end(), preparePollfd);
mRecreatePollfds = false;
}
else
{
//first we go through the registered filedescriptors and check if someone needs preparation:
- std::for_each(cloneListPoll.begin(), cloneListPoll.end(), CAmSocketHandler::prepare);
+ std::for_each(mListActivePolls.begin(), mListActivePolls.end(), CAmSocketHandler::prepare);
}
#ifndef WITH_TIMERFD
@@ -168,14 +168,16 @@ void CAmSocketHandler::start_listenting()
{
if (CAmSocketHandler::eventFired(*itMfdPollingArray))
{
- listmPollIt = cloneListPoll.begin();
+ listmPollIt = mListActivePolls.begin();
std::advance(listmPollIt, std::distance(fdPollingArray.begin(), itMfdPollingArray));
- listPoll.push_back(*listmPollIt);
- CAmSocketHandler::fire(*listmPollIt);
+ sh_poll_s & pollObj = *listmPollIt;
+
+ listPoll.push_back(&pollObj);
+ CAmSocketHandler::fire(&pollObj);
}
}
-
+
//stage 2, lets ask around if some dispatching is necessary, the ones who need stay on the list
listPoll.remove_if(CAmSocketHandler::noDispatching);
@@ -434,7 +436,7 @@ am::am_Error_e CAmSocketHandler::addFDPoll(const int fd, const short event, IAmS
am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle)
{
VectorListPoll_t::iterator iterator = mListPoll.begin();
-
+
for (; iterator != mListPoll.end(); ++iterator)
{
if (iterator->handle == handle)
@@ -442,10 +444,24 @@ am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle)
iterator = mListPoll.erase(iterator);
mSetPollKeys.pollHandles.erase(handle);
mRecreatePollfds = true;
- return (E_OK);
+ break;
}
}
- return (E_UNKNOWN);
+
+ if (iterator == mListPoll.end())
+ return (E_UNKNOWN);
+
+ VectorListPoll_t::iterator iteratorActivePolls = mListActivePolls.begin();
+ for (; iteratorActivePolls != mListActivePolls.end(); ++iteratorActivePolls)
+ {
+ if (iteratorActivePolls->handle == handle)
+ {
+ iteratorActivePolls->isValid = false;
+ break;
+ }
+ }
+
+ return (E_OK);
}
/**
@@ -985,11 +1001,11 @@ void CAmSocketHandler::prepare(am::CAmSocketHandler::sh_poll_s& row)
/**
* fire callback
*/
-void CAmSocketHandler::fire(sh_poll_s& a)
+void CAmSocketHandler::fire(const sh_poll_s* a)
{
try
{
- a.firedCB(a.pollfdValue, a.handle, a.userData);
+ a->firedCB(a->pollfdValue, a->handle, a->userData);
} catch (std::exception& e)
{
logError("Sockethandler: Exception in Preparecallback,caught", e.what());
@@ -999,23 +1015,23 @@ void CAmSocketHandler::fire(sh_poll_s& a)
/**
* should disptach
*/
-bool CAmSocketHandler::noDispatching(const sh_poll_s& a)
+bool CAmSocketHandler::noDispatching(const sh_poll_s* a)
{
//remove from list of there is no checkCB
- if (nullptr == a.checkCB)
+ if (nullptr == a->checkCB || false==a->isValid )
return (true);
- return (!a.checkCB(a.handle, a.userData));
+ return (!a->checkCB(a->handle, a->userData));
}
/**
* disptach
*/
-bool CAmSocketHandler::dispatchingFinished(const sh_poll_s& a)
+bool CAmSocketHandler::dispatchingFinished(const sh_poll_s* a)
{
//remove from list of there is no dispatchCB
- if (nullptr == a.dispatchCB)
+ if (nullptr == a->dispatchCB || false==a->isValid )
return (true);
- return (!a.dispatchCB(a.handle, a.userData));
+ return (!a->dispatchCB(a->handle, a->userData));
}
/**
diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp
index 129f896..07f6aaf 100644
--- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp
+++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp
@@ -36,9 +36,12 @@
//todo: expand test, implement more usecases
//todo: test removeFD
+#undef ENABLED_SOCKETHANDLER_TEST_OUTPUT
+#undef ENABLED_TIMERS_TEST_OUTPUT
+
#define SOCK_PATH "/tmp/mysock"
-#define SOCKET_TEST_LOOPS_COUNT 10
+#define SOCKET_TEST_LOOPS_COUNT 50
#define TIMERS_TO_TEST 500
using namespace testing;
@@ -464,7 +467,7 @@ TEST(CAmSocketHandlerTest, timersStressTest)
timespec timeoutTime;
timeoutTime.tv_sec = 0;
- timeoutTime.tv_nsec = 50000000;// 0,05
+ timeoutTime.tv_nsec = 10000000;// 0,01
std::vector<CAmTimerStressTest*> timers;
@@ -896,7 +899,7 @@ CAmSamplePluginStressTest::CAmSamplePluginStressTest(CAmSocketHandler *mySocketH
userData.f = 1.f;
timespec timeoutTime;
timeoutTime.tv_sec = 0;
- timeoutTime.tv_nsec = 500000000;// 0,5
+ timeoutTime.tv_nsec = 10000000;// 0,01
for(int i=0;i<TIMERS_TO_TEST;i++)
{
CAmTimerStressTest2 *ptestCallback1 = new CAmTimerStressTest2(mySocketHandler, timeoutTime, 0);