From 9c0acd5dc485e422a4a0e329e77ab31af721efeb Mon Sep 17 00:00:00 2001 From: christian mueller Date: Thu, 29 Mar 2012 17:40:07 +0200 Subject: * [GAM-49] worked in comments to last patches * changed dlt threadsafeness * changes on timers in CAmSockethandler * adopted test of Sockethandler to changes * add versioning scheme to documentation * added forgotten #include on CamDbusWrapper and CAmRoutingSenderAsync * adopted RoutingReceiverAsyncTests to new timers Signed-off-by: christian mueller --- AudioManagerDaemon/docx/images/versioning.png | Bin 0 -> 23647 bytes AudioManagerDaemon/src/CAmDbusWrapper.cpp | 12 +- AudioManagerDaemon/src/CAmDltWrapper.cpp | 4 +- AudioManagerDaemon/src/CAmSocketHandler.cpp | 194 +++++++++++++++------ .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 21 +-- 5 files changed, 155 insertions(+), 76 deletions(-) create mode 100644 AudioManagerDaemon/docx/images/versioning.png (limited to 'AudioManagerDaemon') diff --git a/AudioManagerDaemon/docx/images/versioning.png b/AudioManagerDaemon/docx/images/versioning.png new file mode 100644 index 0000000..9b587ba Binary files /dev/null and b/AudioManagerDaemon/docx/images/versioning.png differ diff --git a/AudioManagerDaemon/src/CAmDbusWrapper.cpp b/AudioManagerDaemon/src/CAmDbusWrapper.cpp index 115d33d..97b4ccd 100644 --- a/AudioManagerDaemon/src/CAmDbusWrapper.cpp +++ b/AudioManagerDaemon/src/CAmDbusWrapper.cpp @@ -132,7 +132,7 @@ CAmDbusWrapper::~CAmDbusWrapper() */ void CAmDbusWrapper::registerCallback(const DBusObjectPathVTable* vtable, const std::string& path, void* userdata) { - logInfo("DBusWrapper::~registerCallback register callback:", path); + logInfo("DBusWrapper::registerCallback register callback:", path); std::string completePath = std::string(DBUS_SERVICE_OBJECT_PATH) + "/" + path; dbus_error_init(&mDBusError); @@ -314,10 +314,9 @@ dbus_bool_t CAmDbusWrapper::addTimeoutDelegate(DBusTimeout *timeout, void* userD //prepare handle and callback. new is eval, but there is no other choice because we need the pointer! sh_timerHandle_t* handle = new sh_timerHandle_t; mpListTimerhandles.push_back(handle); - IAmShTimerCallBack* buffer = &pDbusTimerCallback; //add the timer to the pollLoop - mpSocketHandler->addTimer(pollTimeout, buffer, *handle, timeout); + mpSocketHandler->addTimer(pollTimeout, &pDbusTimerCallback, *handle, timeout); //save the handle with dbus context dbus_timeout_set_data(timeout, handle, NULL); @@ -427,7 +426,7 @@ void CAmDbusWrapper::toggleTimeoutDelegate(DBusTimeout *timeout, void* userData) int localTimeout = dbus_timeout_get_interval(timeout); pollTimeout.tv_sec = localTimeout / 1000; pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000; - mpSocketHandler->restartTimer(*handle, pollTimeout); + mpSocketHandler->updateTimer(*handle, pollTimeout); } else { @@ -441,10 +440,7 @@ void CAmDbusWrapper::dbusTimerCallback(sh_timerHandle_t handle, void *userData) assert(userData!=NULL); if (dbus_timeout_get_enabled((DBusTimeout*) userData)) { - timespec ts; - ts.tv_nsec = -1; - ts.tv_sec = -1; - mpSocketHandler->restartTimer(handle, ts); + mpSocketHandler->restartTimer(handle); } dbus_timeout_handle((DBusTimeout*) userData); logInfo("DBusWrapper::dbusTimerCallback was called"); diff --git a/AudioManagerDaemon/src/CAmDltWrapper.cpp b/AudioManagerDaemon/src/CAmDltWrapper.cpp index 5449d7d..61d79c2 100644 --- a/AudioManagerDaemon/src/CAmDltWrapper.cpp +++ b/AudioManagerDaemon/src/CAmDltWrapper.cpp @@ -30,7 +30,7 @@ namespace am { CAmDltWrapper* CAmDltWrapper::mpDLTWrapper = NULL; -pthread_mutex_t CAmDltWrapper::logMutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t CAmDltWrapper::mMutex = PTHREAD_MUTEX_INITIALIZER; CAmDltWrapper *CAmDltWrapper::instance(const bool enableNoDLTDebug) { @@ -96,6 +96,7 @@ void CAmDltWrapper::registerContext(DltContext& handle, const char *contextid, c void CAmDltWrapper::init(DltLogLevelType loglevel, DltContext* context) { (void) loglevel; + pthread_mutex_lock(&mMutex); if (!context) context = &mDltContext; #ifdef WITH_DLT @@ -115,6 +116,7 @@ void CAmDltWrapper::send() mDltContextData.buffer.str(""); mDltContextData.buffer.clear(); #endif + pthread_mutex_unlock(&mMutex); } void CAmDltWrapper::append(const int8_t value) diff --git a/AudioManagerDaemon/src/CAmSocketHandler.cpp b/AudioManagerDaemon/src/CAmSocketHandler.cpp index a6c4be9..27cb4bb 100644 --- a/AudioManagerDaemon/src/CAmSocketHandler.cpp +++ b/AudioManagerDaemon/src/CAmSocketHandler.cpp @@ -43,7 +43,7 @@ CAmSocketHandler::CAmSocketHandler() : mRecreatePollfds(true), // mStartTime() { - gDispatchDone = 0; + gDispatchDone = 1; } CAmSocketHandler::~CAmSocketHandler() @@ -82,8 +82,7 @@ void CAmSocketHandler::start_listenting() mRecreatePollfds = false; } - if (!mListActiveTimer.empty()) - timerCorrection(); + timerCorrection(); //block until something is on a filedescriptor @@ -102,7 +101,6 @@ void CAmSocketHandler::start_listenting() } } - clock_gettime(CLOCK_MONOTONIC, &mStartTime); if (pollStatus != 0) //only check filedescriptors if there was a change { //todo: here could be a timer that makes sure naughty plugins return! @@ -153,6 +151,16 @@ void CAmSocketHandler::start_listenting() void CAmSocketHandler::stop_listening() { gDispatchDone = 1; + + //this is for all running timers only - we need to handle the additional offset here + if (!mListActiveTimer.empty()) + { + timespec currentTime, correctionTime; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + correctionTime = timespecSub(currentTime, mStartTime); + std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), CAmShSubstractTime(correctionTime)); + } + } /** @@ -224,7 +232,7 @@ am_Error_e CAmSocketHandler::removeFDPoll(const sh_pollHandle_t handle) * @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) +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); @@ -235,11 +243,17 @@ am_Error_e CAmSocketHandler::addTimer(const timespec timeouts, IAmShTimerCallBac handle = ++mLastInsertedHandle; //todo: overflow ruling !o timerItem.handle = handle; timerItem.countdown = timeouts; - timerItem.timeout = 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, ¤tTime); + if (!gDispatchDone) //the mainloop is started + timerItem.countdown = timespecAdd(timeouts, timespecSub(currentTime, mStartTime)); + mListActiveTimer.push_back(timerItem); mListActiveTimer.sort(compareCountdown); return (E_OK); @@ -257,7 +271,7 @@ am_Error_e CAmSocketHandler::removeTimer(const sh_timerHandle_t handle) //stop the current timer stopTimer(handle); - std::list::iterator it = mListTimer.begin(); + std::list::iterator it(mListTimer.begin()); for (; it != mListTimer.end(); ++it) { if (it->handle == handle) @@ -270,36 +284,117 @@ am_Error_e CAmSocketHandler::removeTimer(const sh_timerHandle_t handle) } /** - * restarts a timer and updates with a new interval + * 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::restartTimer(const sh_timerHandle_t handle, const timespec timeouts) +am_Error_e CAmSocketHandler::updateTimer(const sh_timerHandle_t handle, const timespec timeouts) { + //update the mList .... sh_timer_s timerItem; - std::list::iterator it = mListTimer.begin(); + std::list::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; - timerItem.timeout=timeouts; - timerItem.countdown=timeouts; + //we add here the time difference between startTime and currenttime, because this time will be substracted later on in timecorrection + timespec currentTime, timeoutsCorrected; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + if (!gDispatchDone) //the mainloop is started + timeoutsCorrected = timespecAdd(timeouts, timespecSub(currentTime, mStartTime)); + + for (; activeIt != mListActiveTimer.end(); ++activeIt) + { + if (activeIt->handle == handle) + { + activeIt->countdown = timeoutsCorrected; + found = true; + break; + } + } + if (!found) + timerItem.countdown = timeoutsCorrected; mListActiveTimer.push_back(timerItem); + mListActiveTimer.sort(compareCountdown); 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) +{ + sh_timer_s timerItem; //!::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; + + //we add here the time difference between startTime and currenttime, because this time will be substracted later on in timecorrection + timespec currentTime, timeoutsCorrected; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + if (!gDispatchDone) //the mainloop is started + { + timeoutsCorrected = timespecAdd(timerItem.countdown, timespecSub(currentTime, mStartTime)); + timerItem.countdown = timeoutsCorrected; + } + + for (; activeIt != mListActiveTimer.end(); ++activeIt) + { + if (activeIt->handle == handle) + { + activeIt->countdown = timerItem.countdown; + found = true; + break; + } + } + + if (!found) + mListActiveTimer.push_back(timerItem); + + mListActiveTimer.sort(compareCountdown); + + 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::iterator it = mListActiveTimer.begin(); + std::list::iterator it(mListActiveTimer.begin()); for (; it != mListActiveTimer.end(); ++it) { if (it->handle == handle) @@ -313,9 +408,7 @@ am_Error_e CAmSocketHandler::stopTimer(const sh_timerHandle_t handle) /** * updates the eventFlags of a poll - * @param handle buffertime.tv_nsec = mTimeout.tv_nsec; - buffertime.tv_sec = mTimeout.tv_sec; - return ((mTimeout.tv_nsec == -1 && mTimeout.tv_sec == -1) ? NULL : &buffertime); + * @param handle * @param events * @return @return E_OK on succsess, E_NON_EXISTENT if fd was not found */ @@ -350,11 +443,13 @@ bool CAmSocketHandler::fdIsValid(const int fd) const */ void CAmSocketHandler::timerUp() { - //first we need to correct all the countdown values by the one who fired - std::for_each(mListActiveTimer.begin(), mListActiveTimer.end(), CAmShSubstractTime(mListActiveTimer.begin()->countdown)); + //find out the timedifference to starttime + timespec currentTime, diffTime; + clock_gettime(CLOCK_MONOTONIC, ¤tTime); + diffTime = timespecSub(currentTime, mStartTime); - //then find the last value that is zero. Since the first value is subtracted, we will always have the first one - std::list::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), CAmShCountdownUp()); + //now we need to substract the diffTime from all timers and see if they are up + std::list::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), CAmShCountdownUp(diffTime)); //copy all fired timers into a list std::vector tempList(overflowIter, mListActiveTimer.rend()); @@ -368,17 +463,7 @@ void CAmSocketHandler::timerUp() } /** - * convert timespec to milliseconds - * @param time time in timespec - * @return time in milliseconds - */ -inline int CAmSocketHandler::timespec2ms(const timespec & time) -{ - return ((time.tv_nsec == -1 && time.tv_sec == -1) ? -1 : time.tv_sec * 1000 + time.tv_nsec / 1000000); -} - -/** - * correct timers + * correct timers and fire the ones who are up */ void CAmSocketHandler::timerCorrection() { @@ -386,28 +471,38 @@ void CAmSocketHandler::timerCorrection() timespec currentTime, correctionTime; clock_gettime(CLOCK_MONOTONIC, ¤tTime); 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::reverse_iterator overflowIter = std::find_if(mListActiveTimer.rbegin(), mListActiveTimer.rend(), CAmShCountdownUp()); + //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 timer that need to be called to a new list - std::vector tempList(overflowIter, mListActiveTimer.rend()); + //find the last occurrence of zero -> timer overflowed + std::list::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 tempList(overflowIter, mListActiveTimer.rend()); - //erase all fired timers - std::list::iterator it(overflowIter.base()); - mListActiveTimer.erase(mListActiveTimer.begin(), it); + //erase all fired timers + std::list::iterator it(overflowIter.base()); + mListActiveTimer.erase(mListActiveTimer.begin(), it); - //call the callbacks for the timers - std::for_each(tempList.begin(), tempList.end(), CAmShCallTimer()); + //call the callbacks for the timers + std::for_each(tempList.begin(), tempList.end(), CAmShCallTimer()); + } } } +/** + * is used to set the pointer for the ppoll command + * @param buffertime + * @return + */ inline timespec* CAmSocketHandler::insertTime(timespec& buffertime) { if (!mListActiveTimer.empty()) @@ -421,14 +516,5 @@ inline timespec* CAmSocketHandler::insertTime(timespec& buffertime) } } -/** - * functor to easy substract from each countdown - * @param t value to substract from - */ -void CAmSocketHandler::CAmShSubstractTime::operator ()(sh_timer_s & t) const -{ - t.countdown = timespecSub(t.countdown, param); -} - } diff --git a/AudioManagerDaemon/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerDaemon/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index 19e4772..d6aec07 100644 --- a/AudioManagerDaemon/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerDaemon/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -68,18 +68,18 @@ void am::CAmTimerCb::timer1Callback(sh_timerHandle_t handle, void* userData) timespec timeout; timeout.tv_nsec = 0; timeout.tv_sec = 1; - mSocketHandler->restartTimer(handle,timeout); + mSocketHandler->updateTimer(handle,timeout); } void am::CAmTimerCb::timer2Callback(sh_timerHandle_t handle, void* userData) { (void) handle; (void) userData; - // std::cout << "callback2 called" << std::endl; + std::cout << "callback2 called" << std::endl; timespec timeout; timeout.tv_nsec = 011110000; - timeout.tv_sec = 0; - mSocketHandler->restartTimer(handle,timeout); + timeout.tv_sec = 1; + mSocketHandler->updateTimer(handle,timeout); } void am::CAmTimerCb::timer3Callback(sh_timerHandle_t, void* userData) @@ -117,7 +117,6 @@ void* playWithUnixSocketServer(void* data) TEST(CAmSocketHandlerTest,playWithTimers) { - gDispatchDone = 0; CAmSocketHandler myHandler; CAmTimerCb testCallback(&myHandler); timespec timeoutTime, timeout2, timeout3, timeout4; @@ -129,15 +128,11 @@ TEST(CAmSocketHandlerTest,playWithTimers) timeout3.tv_sec = 3; timeout4.tv_nsec = 0; timeout4.tv_sec = 20; - IAmShTimerCallBack* buf = &testCallback.pTimer1Callback; - IAmShTimerCallBack* buf2 = &testCallback.pTimer2Callback; - IAmShTimerCallBack* buf3 = &testCallback.pTimer3Callback; - IAmShTimerCallBack* buf4 = &testCallback.pTimer4Callback; sh_timerHandle_t handle; - myHandler.addTimer(timeoutTime, buf, handle, NULL); - myHandler.addTimer(timeout2, buf2, handle, NULL); - myHandler.addTimer(timeout3, buf3, handle, NULL); - myHandler.addTimer(timeout4, buf4, handle, NULL); + myHandler.addTimer(timeoutTime, &testCallback.pTimer1Callback, handle, NULL); + myHandler.addTimer(timeout2, &testCallback.pTimer2Callback, handle, NULL); + myHandler.addTimer(timeout3, &testCallback.pTimer3Callback, handle, NULL); + myHandler.addTimer(timeout4, &testCallback.pTimer4Callback, handle, NULL); myHandler.start_listenting(); } -- cgit v1.2.1