diff options
author | Aleksandar Donchev <Aleksander.Donchev@partner.bmw.de> | 2017-09-26 16:07:00 +0200 |
---|---|---|
committer | Jacqueline Molz <Jacqueline.Molz@bmw.de> | 2017-11-06 11:34:39 +0100 |
commit | cee30860cefff89ba258537f2bd6178596b88ba9 (patch) | |
tree | a15c9f081653706d4f28209fe6752265f1caa4cc | |
parent | 964cee3684c97494106ee287bc33ace3db8fd8c2 (diff) | |
download | audiomanager-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
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); |