summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AudioManagerUtilities/include/CAmCommonAPIWrapper.h46
-rw-r--r--AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp268
2 files changed, 198 insertions, 116 deletions
diff --git a/AudioManagerUtilities/include/CAmCommonAPIWrapper.h b/AudioManagerUtilities/include/CAmCommonAPIWrapper.h
index a83b5b3..0f770c4 100644
--- a/AudioManagerUtilities/include/CAmCommonAPIWrapper.h
+++ b/AudioManagerUtilities/include/CAmCommonAPIWrapper.h
@@ -22,6 +22,7 @@
#include <string>
#include <list>
#include <map>
+#include <unordered_map>
#include <queue>
#include <memory>
#include <cassert>
@@ -48,29 +49,37 @@ class CAmSocketHandler;
class CAmCommonAPIWrapper
{
- void commonPrepareCallback(const sh_pollHandle_t handle, void* userData);
+ void commonPrepareCallback ( const sh_pollHandle_t, void* );
TAmShPollPrepare<CAmCommonAPIWrapper> pCommonPrepareCallback;
- bool commonDispatchCallback(const sh_pollHandle_t handle, void* userData);
- TAmShPollDispatch<CAmCommonAPIWrapper> pCommonDispatchCallback;
-
void commonFireCallback(const pollfd pollfd, const sh_pollHandle_t, void*);
TAmShPollFired<CAmCommonAPIWrapper> pCommonFireCallback;
bool commonCheckCallback(const sh_pollHandle_t handle, void*);
TAmShPollCheck<CAmCommonAPIWrapper> pCommonCheckCallback;
+
+ bool commonDispatchCallback(const sh_pollHandle_t handle, void* userData);
+ TAmShPollDispatch<CAmCommonAPIWrapper> pCommonDispatchCallback;
void commonTimerCallback(sh_timerHandle_t handle, void* userData);
TAmShTimerCallBack<CAmCommonAPIWrapper> pCommonTimerCallback;
- struct timerHandles
- {
- sh_timerHandle_t handle;
- CommonAPI::Timeout* timeout;
- };
-
CAmSocketHandler *mpSocketHandler; //!< pointer to the sockethandler
+ typedef std::vector<CommonAPI::DispatchSource*> ArrayDispatchSources;
+ typedef ArrayDispatchSources::iterator IteratorArrayDispatchSources;
+ typedef std::unordered_map<am::sh_pollHandle_t, CommonAPI::Watch*> MapWatches;
+ typedef MapWatches::iterator IteratorMapWatches;
+ typedef std::unordered_map<am::sh_pollHandle_t,std::list<CommonAPI::DispatchSource*>> MapDispatchSources;
+ typedef MapDispatchSources::iterator IteratorDispatchSources;
+ typedef std::unordered_map<am::sh_pollHandle_t, CommonAPI::Timeout*> MapTimeouts;
+ typedef MapTimeouts::iterator IteratorMapTimeouts;
+
+ ArrayDispatchSources mRegisteredDispatchSources;
+ MapWatches mMapWatches;
+ MapDispatchSources mSourcesToDispatch;
+ MapTimeouts mListTimerhandles;
+
std::shared_ptr<CommonAPI::Runtime> mRuntime;
std::shared_ptr<CommonAPI::MainLoopContext> mContext;
@@ -78,22 +87,23 @@ class CAmCommonAPIWrapper
CommonAPI::WatchListenerSubscription mWatchListenerSubscription;
CommonAPI::TimeoutSourceListenerSubscription mTimeoutSourceListenerSubscription;
CommonAPI::WakeupListenerSubscription mWakeupListenerSubscription;
- std::multimap<CommonAPI::DispatchPriority, CommonAPI::DispatchSource*> mRegisteredDispatchSources;
- std::map<int,CommonAPI::Watch*> mMapWatches;
- CommonAPI::Watch* mWatchToCheck;
- std::list<CommonAPI::DispatchSource*> mSourcesToDispatch;
- std::vector<timerHandles> mpListTimerhandles;
+
void registerDispatchSource(CommonAPI::DispatchSource* dispatchSource, const CommonAPI::DispatchPriority dispatchPriority);
void deregisterDispatchSource(CommonAPI::DispatchSource* dispatchSource);
+ void deregisterAllDispatchSource();
void registerWatch(CommonAPI::Watch* watch, const CommonAPI::DispatchPriority dispatchPriority);
void deregisterWatch(CommonAPI::Watch* watch);
+ void deregisterAllWatches();
void registerTimeout(CommonAPI::Timeout* timeout, const CommonAPI::DispatchPriority dispatchPriority);
void deregisterTimeout(CommonAPI::Timeout* timeout);
- void wakeup();
-
+ void deregisterAllTimeouts();
+
+ CommonAPI::Watch* watchWithHandle(const sh_pollHandle_t handle);
+ CommonAPI::Timeout* timeoutWithHandle(const sh_pollHandle_t handle);
+
protected:
- CAmCommonAPIWrapper(CAmSocketHandler* socketHandler, const std::string & applicationName = "") ;
+ CAmCommonAPIWrapper ( CAmSocketHandler* socketHandler, const std::string& applicationName = "" ) ;
public:
diff --git a/AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp b/AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp
index caa7aa8..702d384 100644
--- a/AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp
+++ b/AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp
@@ -36,21 +36,47 @@ namespace am
static CAmCommonAPIWrapper* pSingleCommonAPIInstance = NULL;
+bool timeoutToTimespec(const int64_t & localTimeout, timespec & pollTimeout)
+{
+ if(CommonAPI::TIMEOUT_INFINITE == localTimeout)//dispatch never
+ {
+ return false;
+ }
+ else
+ {
+ if(CommonAPI::TIMEOUT_NONE==localTimeout)//dispatch immediately
+ {
+ pollTimeout.tv_sec = 0;
+ pollTimeout.tv_nsec = 5000000;//5 ms
+ }
+ else
+ {
+ pollTimeout.tv_sec = localTimeout / 1000;
+ pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000;
+ }
+ return true;
+ }
+}
+
+
CAmCommonAPIWrapper::CAmCommonAPIWrapper(CAmSocketHandler* socketHandler, const std::string & applicationName):
pCommonPrepareCallback(this,&CAmCommonAPIWrapper::commonPrepareCallback), //
- pCommonDispatchCallback(this, &CAmCommonAPIWrapper::commonDispatchCallback), //
pCommonFireCallback(this, &CAmCommonAPIWrapper::commonFireCallback), //
pCommonCheckCallback(this, &CAmCommonAPIWrapper::commonCheckCallback), //
+ pCommonDispatchCallback(this, &CAmCommonAPIWrapper::commonDispatchCallback), //
pCommonTimerCallback(this, &CAmCommonAPIWrapper::commonTimerCallback), //
- mpSocketHandler(socketHandler), //
- mWatchToCheck(NULL)
+ mpSocketHandler(socketHandler),
+ mRegisteredDispatchSources(),
+ mMapWatches(),
+ mSourcesToDispatch(),
+ mListTimerhandles()
{
assert(NULL!=socketHandler);
//Get the runtime
mRuntime = CommonAPI::Runtime::get();
assert(NULL!=mRuntime);
- //Create the context
+//Create the context
if(applicationName.size())
mContext = std::make_shared<CommonAPI::MainLoopContext>(applicationName);
else
@@ -75,9 +101,11 @@ CAmCommonAPIWrapper::~CAmCommonAPIWrapper()
mContext->unsubscribeForDispatchSources(mDispatchSourceListenerSubscription);
mContext->unsubscribeForWatches(mWatchListenerSubscription);
mContext->unsubscribeForTimeouts(mTimeoutSourceListenerSubscription);
+ deregisterAllDispatchSource();
+ deregisterAllTimeouts();
+ deregisterAllWatches();
mContext.reset();
mpSocketHandler = NULL;
- mWatchToCheck = NULL;
}
CAmCommonAPIWrapper* CAmCommonAPIWrapper::instantiateOnce(CAmSocketHandler* socketHandler, const std::string & applicationName)
@@ -115,170 +143,214 @@ CAmCommonAPIWrapper* CAmCommonAPIWrapper::getInstance()
return pSingleCommonAPIInstance;
}
-bool CAmCommonAPIWrapper::commonDispatchCallback(const sh_pollHandle_t handle, void *userData)
+void CAmCommonAPIWrapper::commonPrepareCallback(const sh_pollHandle_t, void*)
{
- (void) handle;
- (void) userData;
-
- std::list<CommonAPI::DispatchSource*>::iterator iterator(mSourcesToDispatch.begin());
- for(;iterator!=mSourcesToDispatch.end();)
+ for (auto dispatchSourceIterator = mRegisteredDispatchSources.begin();
+ dispatchSourceIterator != mRegisteredDispatchSources.end();
+ dispatchSourceIterator++)
{
- CommonAPI::DispatchSource* source = *iterator;
- if (!source->dispatch()) {
- iterator=mSourcesToDispatch.erase(iterator);
+ int64_t dispatchTimeout(CommonAPI::TIMEOUT_INFINITE);
+ if((*dispatchSourceIterator)->prepare(dispatchTimeout))
+ {
+ while ((*dispatchSourceIterator)->dispatch());
}
- else
- iterator++;
}
- if (!mSourcesToDispatch.empty())
- return (true);
+}
- return false;
+void CAmCommonAPIWrapper::commonFireCallback(const pollfd pollfd, const sh_pollHandle_t handle, void *)
+{
+ CommonAPI::Watch* pWatchToCheck = watchWithHandle(handle);
+ if( pWatchToCheck )
+ pWatchToCheck->dispatch(pollfd.revents);
}
-bool CAmCommonAPIWrapper::commonCheckCallback(const sh_pollHandle_t, void *)
+bool CAmCommonAPIWrapper::commonCheckCallback(const sh_pollHandle_t handle, void *)
{
- std::vector<CommonAPI::DispatchSource*> vecDispatch=mWatchToCheck->getDependentDispatchSources();
- mSourcesToDispatch.insert(mSourcesToDispatch.end(), vecDispatch.begin(), vecDispatch.end());
+ CommonAPI::Watch* pWatchToCheck = watchWithHandle(handle);
+ if( pWatchToCheck )
+ {
+ const ArrayDispatchSources & vecDispatch = pWatchToCheck->getDependentDispatchSources();
+ if(vecDispatch.size()>0)
+ {
+ mSourcesToDispatch[handle].insert(mSourcesToDispatch[handle].end(), vecDispatch.begin(), vecDispatch.end());
+ return true;
+ }
+ }
+ return false;
+}
- return (mWatchToCheck || !mSourcesToDispatch.empty());
+bool CAmCommonAPIWrapper::commonDispatchCallback(const sh_pollHandle_t handle, void *)
+{
+ CommonAPI::Watch* pWatchToCheck = watchWithHandle(handle);
+ if( pWatchToCheck )
+ {
+ std::list<CommonAPI::DispatchSource*> & srcList = mSourcesToDispatch[handle];
+ for(auto it = srcList.begin();it!=srcList.end();)
+ {
+ if (false==(*it)->dispatch())
+ it=srcList.erase(it);
+ else
+ it++;
+ }
+ if (!srcList.empty())
+ return (true);
+ }
+ mSourcesToDispatch.erase(handle);
+ return false;
}
-void CAmCommonAPIWrapper::commonFireCallback(const pollfd pollfd, const sh_pollHandle_t, void *)
+void CAmCommonAPIWrapper::commonTimerCallback(sh_timerHandle_t handle, void *)
{
- mWatchToCheck=NULL;
- try
+ CommonAPI::Timeout* pTimeout = timeoutWithHandle(handle);
+
+ if( NULL==pTimeout )
{
- mWatchToCheck=mMapWatches.at(pollfd.fd);
+ //erroneous call because deregisterTimeout has been called, so try to remove the timer from the sockethandler
+ mpSocketHandler->removeTimer(handle);
}
- catch (const std::out_of_range& error) {
- logInfo(__PRETTY_FUNCTION__,error.what());
- return;
+ else
+ {
+ if ( false==pTimeout->dispatch() ) //it should be removed
+ {
+ mpSocketHandler->removeTimer(handle);
+ mListTimerhandles.erase(handle);
+ }
+ #ifndef WITH_TIMERFD
+ else //the timeout should be rescheduled
+ mpSocketHandler->restartTimer(handle);
+ #endif
}
+}
- mWatchToCheck->dispatch(pollfd.revents);
+void CAmCommonAPIWrapper::registerDispatchSource(CommonAPI::DispatchSource* dispatchSource, const CommonAPI::DispatchPriority)
+{
+ mRegisteredDispatchSources.push_back(dispatchSource);
}
-void CAmCommonAPIWrapper::commonPrepareCallback(const sh_pollHandle_t, void*)
+void CAmCommonAPIWrapper::deregisterDispatchSource(CommonAPI::DispatchSource* dispatchSource)
{
- for (auto dispatchSourceIterator = mRegisteredDispatchSources.begin();
- dispatchSourceIterator != mRegisteredDispatchSources.end();
- dispatchSourceIterator++)
+ for(IteratorArrayDispatchSources dispatchSourceIterator = mRegisteredDispatchSources.begin(); dispatchSourceIterator != mRegisteredDispatchSources.end(); dispatchSourceIterator++)
{
- int64_t dispatchTimeout(CommonAPI::TIMEOUT_INFINITE);
- if(dispatchSourceIterator->second->prepare(dispatchTimeout))
+ if( *dispatchSourceIterator == dispatchSource )
{
- while (dispatchSourceIterator->second->dispatch());
+ mRegisteredDispatchSources.erase(dispatchSourceIterator);
+ break;
}
}
}
-void CAmCommonAPIWrapper::registerDispatchSource(CommonAPI::DispatchSource* dispatchSource, const CommonAPI::DispatchPriority dispatchPriority)
+void CAmCommonAPIWrapper::deregisterAllDispatchSource()
{
- mRegisteredDispatchSources.insert({dispatchPriority, dispatchSource});
+ mRegisteredDispatchSources.clear();
}
-void CAmCommonAPIWrapper::deregisterDispatchSource(CommonAPI::DispatchSource* dispatchSource)
+void CAmCommonAPIWrapper::registerWatch(CommonAPI::Watch* watch, const CommonAPI::DispatchPriority)
{
- for(auto dispatchSourceIterator = mRegisteredDispatchSources.begin();
- dispatchSourceIterator != mRegisteredDispatchSources.end();
- dispatchSourceIterator++) {
+ logInfo(__PRETTY_FUNCTION__);
+ pollfd pollfd_ (watch->getAssociatedFileDescriptor());
+ sh_pollHandle_t handle (0);
- if(dispatchSourceIterator->second == dispatchSource) {
- mRegisteredDispatchSources.erase(dispatchSourceIterator);
- break;
- }
+ am_Error_e error = mpSocketHandler->addFDPoll(pollfd_.fd, pollfd_.events, &pCommonPrepareCallback, &pCommonFireCallback, &pCommonCheckCallback, &pCommonDispatchCallback, watch, handle);
+
+ //if everything is alright, add the watch and the handle to our map so we know this relationship
+ if (error != am_Error_e::E_OK || handle == 0)
+ {
+ logError(__func__,"entering watch failed");
}
+ else
+ mMapWatches.insert(std::make_pair(handle,watch));
}
void CAmCommonAPIWrapper::deregisterWatch(CommonAPI::Watch* watch)
{
- for(std::map<int,CommonAPI::Watch*>::iterator iter(mMapWatches.begin());iter!=mMapWatches.end();iter++)
+ for(IteratorMapWatches iter=mMapWatches.begin();iter!=mMapWatches.end();iter++)
{
if (iter->second == watch)
{
+ mpSocketHandler->removeFDPoll(iter->first);
mMapWatches.erase(iter);
break;
}
}
}
+void CAmCommonAPIWrapper::deregisterAllWatches()
+{
+ for(IteratorMapWatches iter=mMapWatches.begin();iter!=mMapWatches.end();iter++)
+ mpSocketHandler->removeFDPoll(iter->first);
+ mMapWatches.clear();
+}
+
void CAmCommonAPIWrapper::registerTimeout(CommonAPI::Timeout* timeout, const CommonAPI::DispatchPriority)
{
timespec pollTimeout;
- int64_t localTimeout = timeout->getTimeoutInterval();
-
- if(CommonAPI::TIMEOUT_INFINITE==localTimeout)//dispatch never
- {
- pollTimeout.tv_sec = localTimeout;
- pollTimeout.tv_nsec = 0;
- }
- else if(CommonAPI::TIMEOUT_NONE==localTimeout)//dispatch immediately
+ if(timeoutToTimespec(timeout->getTimeoutInterval(), pollTimeout))
{
- pollTimeout.tv_sec = 0;
- pollTimeout.tv_nsec = 1000000;
- }
- else
- {
- pollTimeout.tv_sec = localTimeout / 1000;
- pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000;
- }
+ //prepare handle and callback. new is eval, but there is no other choice because we need the pointer!
+ sh_timerHandle_t handle;
- //prepare handle and callback. new is eval, but there is no other choice because we need the pointer!
- sh_timerHandle_t handle;
-
- //add the timer to the pollLoop
- am_Error_e error = mpSocketHandler->addTimer(pollTimeout, &pCommonTimerCallback, handle, timeout);
- if (error != am_Error_e::E_OK || handle == 0)
- {
- logError(__func__,"adding timer failed");
- }
- else
- {
- timerHandles myHandle({handle,timeout});
- mpListTimerhandles.push_back(myHandle);
+ //add the timer to the pollLoop
+ am_Error_e error = mpSocketHandler->addTimer(pollTimeout, &pCommonTimerCallback, handle, timeout, true);
+ if (error != am_Error_e::E_OK || handle == 0)
+ {
+ logError(__func__,"adding timer failed");
+ }
+ else
+ {
+ mListTimerhandles.insert(std::make_pair(handle,timeout));
+ }
}
}
void CAmCommonAPIWrapper::deregisterTimeout(CommonAPI::Timeout* timeout)
{
- for( std::vector<timerHandles>::iterator iter(mpListTimerhandles.begin());iter!=mpListTimerhandles.end();iter++)
+ for( IteratorMapTimeouts iter=mListTimerhandles.begin();iter!= mListTimerhandles.end();iter++)
{
- if(iter->timeout==timeout)
+ if(iter->second==timeout)
{
- mpSocketHandler->removeTimer(iter->handle);
+ mpSocketHandler->removeTimer(iter->first);
+ mListTimerhandles.erase(iter->first);
+ break;
}
}
}
-void CAmCommonAPIWrapper::registerWatch(CommonAPI::Watch* watch, const CommonAPI::DispatchPriority)
+void CAmCommonAPIWrapper::deregisterAllTimeouts()
{
- logInfo(__PRETTY_FUNCTION__);
- pollfd pollfd_ (watch->getAssociatedFileDescriptor());
- sh_pollHandle_t handle (0);
-
- am_Error_e error = mpSocketHandler->addFDPoll(pollfd_.fd, pollfd_.events, &pCommonPrepareCallback, &pCommonFireCallback, &pCommonCheckCallback, &pCommonDispatchCallback, watch, handle);
+ for( IteratorMapTimeouts iter=mListTimerhandles.begin();iter!= mListTimerhandles.end();iter++)
+ mpSocketHandler->removeTimer(iter->first);
+ mListTimerhandles.clear();
+}
- //if everything is alright, add the watch and the handle to our map so we know this relationship
- if (error != am_Error_e::E_OK || handle == 0)
+CommonAPI::Watch* CAmCommonAPIWrapper::watchWithHandle(const sh_pollHandle_t handle)
+{
+ CommonAPI::Watch* pWatchToCheck = NULL;
+ try
{
- logError(__func__,"entering watch failed");
+ pWatchToCheck = mMapWatches.at(handle);
}
- else
- mMapWatches.insert(std::make_pair(pollfd_.fd,watch));
+ catch (const std::out_of_range& error)
+ {
+ logInfo(__PRETTY_FUNCTION__,error.what());
+ }
+ return pWatchToCheck;
}
-void CAmCommonAPIWrapper::commonTimerCallback(sh_timerHandle_t handle, void *)
+CommonAPI::Timeout* CAmCommonAPIWrapper::timeoutWithHandle(const sh_pollHandle_t handle)
{
- for( std::vector<timerHandles>::iterator iter(mpListTimerhandles.begin());iter!=mpListTimerhandles.end();iter++)
+ CommonAPI::Timeout* pTimeout = NULL;
+ try
{
- if(iter->handle==handle)
- {
- iter->timeout->dispatch();
- }
+ pTimeout = mListTimerhandles.at(handle);
}
+ catch (const std::out_of_range& error)
+ {
+ logInfo(__PRETTY_FUNCTION__,error.what());
+ }
+ return pTimeout;
}
+
CAmCommonAPIWrapper* (*getCAPI)() = CAmCommonAPIWrapper::getInstance;
}