summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksandar Donchev <Aleksander.Donchev@partner.bmw.de>2017-03-14 14:55:31 +0100
committerChristian Linke <christian.linke@bmw.de>2017-05-02 06:25:51 -0700
commitda78ca5c2eb7e2ff2f9153361774156f8a454daa (patch)
treefd166672b42da293fc7c41bd9f858e95d590db26
parent99c3edf827a16d4bdc1c40a5df7c18bf8626afa3 (diff)
downloadaudiomanager-da78ca5c2eb7e2ff2f9153361774156f8a454daa.tar.gz
CAmSerializer interface extended to support std::function.
Signed-off-by: Christian Linke <christian.linke@bmw.de> Change-Id: I8b4c2c436ac9fbc37c76a21145c731f327cab0e4
-rw-r--r--AudioManagerCore/src/CAmCommandSender.cpp44
-rw-r--r--AudioManagerUtilities/include/CAmSerializer.h1351
-rw-r--r--AudioManagerUtilities/include/CAmSocketHandler.h7
-rw-r--r--AudioManagerUtilities/src/CAmSocketHandler.cpp118
-rw-r--r--AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp158
-rw-r--r--AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.h99
-rw-r--r--AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt47
-rw-r--r--AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp8
-rw-r--r--AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h216
-rw-r--r--AudioManagerUtilities/test/CMakeLists.txt4
10 files changed, 1053 insertions, 999 deletions
diff --git a/AudioManagerCore/src/CAmCommandSender.cpp b/AudioManagerCore/src/CAmCommandSender.cpp
index ea0d749..6626bdb 100644
--- a/AudioManagerCore/src/CAmCommandSender.cpp
+++ b/AudioManagerCore/src/CAmCommandSender.cpp
@@ -163,10 +163,10 @@ CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginD
}
dboNewMainConnection = [&](const am_MainConnectionType_s& mainConnection) {
- mSerializer.asyncCall<CAmCommandSender, const am_MainConnectionType_s>(this, &CAmCommandSender::cbNewMainConnection, mainConnection);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbNewMainConnection, mainConnection);
};
dboRemovedMainConnection = [&](const am_mainConnectionID_t mainConnection) {
- mSerializer.asyncCall<CAmCommandSender, const am_mainConnectionID_t>(this, &CAmCommandSender::cbRemovedMainConnection, mainConnection);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedMainConnection, mainConnection);
};
dboNewSink = [&](const am_Sink_s& sink) {
if (sink.visible)
@@ -178,7 +178,8 @@ CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginD
s.sinkClassID = sink.sinkClassID;
s.sinkID = sink.sinkID;
s.volume = sink.mainVolume;
- mSerializer.asyncCall<CAmCommandSender, const am_SinkType_s>(this, &CAmCommandSender::cbNewSink, s);
+ typedef void(CAmCommandSender::*TMeth)(am::am_SinkType_s) ;
+ mSerializer.asyncCall<CAmCommandSender, TMeth, am::am_SinkType_s>(this, &CAmCommandSender::cbNewSink, s);
}
};
dboNewSource = [&](const am_Source_s& source) {
@@ -189,64 +190,65 @@ CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginD
s.name = source.name;
s.sourceClassID = source.sourceClassID;
s.sourceID = source.sourceID;
- mSerializer.asyncCall<CAmCommandSender, const am_SourceType_s>(this, &CAmCommandSender::cbNewSource, s);
+ typedef void(CAmCommandSender::*TMeth)(am::am_SourceType_s) ;
+ mSerializer.asyncCall<CAmCommandSender, TMeth, am::am_SourceType_s>(this, &CAmCommandSender::cbNewSource, s);
}
};
dboRemovedSink = [&](const am_sinkID_t sinkID, const bool visible) {
if (visible)
- mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t>(this, &CAmCommandSender::cbRemovedSink, sinkID);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSink, sinkID);
};
dboRemovedSource = [&](const am_sourceID_t sourceID, const bool visible) {
if (visible)
- mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t>(this, &CAmCommandSender::cbRemovedSource, sourceID);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSource, sourceID);
};
dboNumberOfSinkClassesChanged = [&]() {
- mSerializer.asyncCall<CAmCommandSender>(this, &CAmCommandSender::cbNumberOfSinkClassesChanged);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSinkClassesChanged);
};
dboNumberOfSourceClassesChanged = [&]() {
- mSerializer.asyncCall<CAmCommandSender>(this, &CAmCommandSender::cbNumberOfSourceClassesChanged);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSourceClassesChanged);
};
dboMainConnectionStateChanged = [&](const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState) {
- mSerializer.asyncCall<CAmCommandSender, const am_connectionID_t, const am_ConnectionState_e>(this, &CAmCommandSender::cbMainConnectionStateChanged, connectionID, connectionState);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbMainConnectionStateChanged, connectionID, connectionState);
};
dboMainSinkSoundPropertyChanged = [&](const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty) {
- mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_MainSoundProperty_s>(this, &CAmCommandSender::cbMainSinkSoundPropertyChanged, sinkID, SoundProperty);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbMainSinkSoundPropertyChanged, sinkID, SoundProperty);
};
dboMainSourceSoundPropertyChanged = [&](const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty) {
- mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t, const am_MainSoundProperty_s>(this, &CAmCommandSender::cbMainSourceSoundPropertyChanged, sourceID, SoundProperty);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbMainSourceSoundPropertyChanged, sourceID, SoundProperty);
};
dboSinkAvailabilityChanged = [&](const am_sinkID_t sinkID, const am_Availability_s & availability) {
- mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_Availability_s>(this, &CAmCommandSender::cbSinkAvailabilityChanged, sinkID, availability);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbSinkAvailabilityChanged, sinkID, availability);
};
dboSourceAvailabilityChanged = [&](const am_sourceID_t sourceID, const am_Availability_s & availability) {
- mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t, const am_Availability_s>(this, &CAmCommandSender::cbSourceAvailabilityChanged, sourceID, availability);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbSourceAvailabilityChanged, sourceID, availability);
};
dboVolumeChanged = [&](const am_sinkID_t sinkID, const am_mainVolume_t volume) {
- mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_mainVolume_t>(this, &CAmCommandSender::cbVolumeChanged, sinkID, volume);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbVolumeChanged, sinkID, volume);
};
dboSinkMuteStateChanged = [&](const am_sinkID_t sinkID, const am_MuteState_e muteState) {
- mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_MuteState_e>(this, &CAmCommandSender::cbSinkMuteStateChanged, sinkID, muteState);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbSinkMuteStateChanged, sinkID, muteState);
};
dboSystemPropertyChanged = [&](const am_SystemProperty_s& SystemProperty) {
- mSerializer.asyncCall<CAmCommandSender, const am_SystemProperty_s>(this, &CAmCommandSender::cbSystemPropertyChanged, SystemProperty);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbSystemPropertyChanged, SystemProperty);
};
dboTimingInformationChanged = [&](const am_mainConnectionID_t mainConnection, const am_timeSync_t time) {
- mSerializer.asyncCall<CAmCommandSender, const am_mainConnectionID_t, const am_timeSync_t>(this, &CAmCommandSender::cbTimingInformationChanged, mainConnection, time);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbTimingInformationChanged, mainConnection, time);
};
dboSinkUpdated = [&](const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible) {
if (visible)
- mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_sinkClass_t, const std::vector<am_MainSoundProperty_s> >(this, &CAmCommandSender::cbSinkUpdated, sinkID, sinkClassID, listMainSoundProperties);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbSinkUpdated, sinkID, sinkClassID, listMainSoundProperties);
};
dboSourceUpdated = [&](const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible) {
if (visible)
- mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t, const am_sourceClass_t, const std::vector<am_MainSoundProperty_s> >(this, &CAmCommandSender::cbSinkUpdated, sourceID, sourceClassID, listMainSoundProperties);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbSinkUpdated, sourceID, sourceClassID, listMainSoundProperties);
};
dboSinkMainNotificationConfigurationChanged = [&](const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration) {
- mSerializer.asyncCall<CAmCommandSender, const am_sinkID_t, const am_NotificationConfiguration_s> (this, &CAmCommandSender::cbSinkMainNotificationConfigurationChanged, sinkID, mainNotificationConfiguration);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbSinkMainNotificationConfigurationChanged, sinkID, mainNotificationConfiguration);
};
dboSourceMainNotificationConfigurationChanged = [&](const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration) {
- mSerializer.asyncCall<CAmCommandSender, const am_sourceID_t, const am_NotificationConfiguration_s>(this, &CAmCommandSender::cbSourceMainNotificationConfigurationChanged, sourceID, mainNotificationConfiguration);
+ mSerializer.asyncCall(this, &CAmCommandSender::cbSourceMainNotificationConfigurationChanged, sourceID, mainNotificationConfiguration);
};
}
diff --git a/AudioManagerUtilities/include/CAmSerializer.h b/AudioManagerUtilities/include/CAmSerializer.h
index b0cd70e..8e1015f 100644
--- a/AudioManagerUtilities/include/CAmSerializer.h
+++ b/AudioManagerUtilities/include/CAmSerializer.h
@@ -1,805 +1,546 @@
-/**
- * SPDX license identifier: MPL-2.0
- *
- * Copyright (C) 2012, BMW AG
- *
- * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
- * \author Alesksandar Donchev, aleksander.donchev@partner.bmw.de BMW 2015
- *
- * \copyright
- * This Source Code Form is subject to the terms of the
- * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
- * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * \file CAmSerializer.h
- * For further information see http://www.genivi.org/.
- */
-
-#ifndef CAMSERIALIZER_H_
-#define CAMSERIALIZER_H_
-
-#include <pthread.h>
-#include <deque>
-#include <cassert>
-#include <memory>
-#include <stdexcept>
-#include <unistd.h>
-#include "CAmDltWrapper.h"
-#include "CAmSocketHandler.h"
-
-/**
- * todo: performance improvement we could implement a memory pool that is more efficient here and avoids
- * allocation and deallocation times.
- */
-
-namespace am
-{
-/**
- * magic class that does the serialization of functions calls
- * The constructor must be called within the main threadcontext, after that using the
- * overloaded template function call will serialize all calls and call them within the
- * main thread context.\n
- * More details can be found here: \ref util
- * \warning asynchronous calls may be used in the mainthread context, but if you want to use synchronous calls make sure that you use one
- * instance of this class per thread otherwise you could be lost in never returning calls.\n
- * Examples of the usage can be found in IAmCommandReceiverShadow of the ControlPlugin or IAmRoutingReceiverShadow of the
- * PluginRoutingInterfaceAsync.
- *
- */
-class CAmSerializer
-{
-private:
-
- /**
- * Prototype for a delegate
- */
- class CAmDelegate
- {
- public:
-
- typedef enum:bool {
- SyncCallType = false,
- AsyncCallType = true
- } CallType;
-
- virtual ~CAmDelegate()
- {};
- virtual CallType call(int* pipe)=0;
-
- };
-
- /**
- * Prototype for a delegate with variadic template arguments in conjunction with the following class.
- */
- template <class Class, typename Method, typename Tuple, bool Done, int Total, int... N>
- class CAmDelegateAsyncImpl : public CAmDelegate
- {
- Class mInstance;
- Method mMethod;
- Tuple mArguments;
- public:
- friend class CAmSerializer;
- static void call(Class instance, Method method, Tuple && arguments)
- {
- CAmDelegateAsyncImpl<Class, Method, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(instance, method, std::forward<Tuple>(arguments));
- }
-
- CAmDelegateAsyncImpl(Class instance, Method method, Tuple && arguments)
- {
- mInstance = instance;
- mMethod = method;
- mArguments = std::move(arguments);
- }
-
- CallType call(int* pipe)
- {
- (void) pipe;
- call(mInstance, mMethod, std::forward<Tuple>(mArguments));
- return (AsyncCallType);
- };
- };
-
- /**
- * Prototype for a delegate with variadic template arguments.
- */
- template <class Class, typename Method, typename Tuple, int Total, int... N>
- class CAmDelegateAsyncImpl<Class, Method, Tuple, true, Total, N...> : public CAmDelegate
- {
- Class mInstance;
- Method mMethod;
- Tuple mArguments;
- public:
- friend class CAmSerializer;
- static void call(Class instance, Method method, Tuple && t)
- {
- (*instance.*method)(std::get<N>(std::forward<Tuple>(t))...);
- }
-
- CAmDelegateAsyncImpl(Class instance, Method method, Tuple && arguments)
- {
- mInstance = instance;
- mMethod = method;
- mArguments = std::move(arguments);
- }
-
- CallType call(int* pipe)
- {
- (void) pipe;
- call(mInstance, mMethod, std::forward<Tuple>(mArguments));
- return (AsyncCallType);
- };
- };
-
- /**
- * Prototype for a delegate with variadic template arguments in conjunction with the following class.
- */
- template <class Class, typename Method, typename Return, typename Tuple, bool Done, int Total, int... N>
- class CAmDelegateSyncImpl : public CAmDelegate
- {
- Class mInstance;
- Method mMethod;
- Tuple mArguments;
- Return mReturn;
- public:
- friend class CAmSerializer;
- static void call(Class instance,Method method, Return & result, Tuple && arguments)
- {
- CAmDelegateSyncImpl<Class, Method, Return, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(instance, method, result, std::forward<Tuple>(arguments));
- }
-
- CAmDelegateSyncImpl(Class instance, Method method, Tuple && arguments)
- {
- mInstance = instance;
- mMethod = method;
- mArguments = std::move(arguments);
- }
-
- CallType call(int* pipe)
- {
- call(mInstance, mMethod, mReturn, std::forward<Tuple>(mArguments));
- ssize_t result(-1);
- result = write(pipe[1], this, sizeof(this));
- if (result == -1)
- logError("CAmSerializer: Problem writing into pipe! Error No:",errno);
- return (SyncCallType);
- };
- };
-
- /**
- * Prototype for a delegate with variadic template arguments.
- */
- template <class Class, typename Method, typename Return, typename Tuple, int Total, int... N>
- class CAmDelegateSyncImpl<Class, Method, Return, Tuple, true, Total, N...> : public CAmDelegate
- {
- Class mInstance;
- Method mMethod;
- Tuple mArguments;
- Return mReturn;
- public:
- friend class CAmSerializer;
- static void call(Class instance, Method method, Return & result, Tuple && t)
- {
- result = (*instance.*method)(std::get<N>(t)...);
- }
-
- CAmDelegateSyncImpl(Class instance, Method method, Tuple && arguments)
- {
- mInstance = instance;
- mMethod = method;
- mArguments = std::move(arguments);
- }
-
- CallType call(int* pipe)
- {
- call(mInstance, mMethod, mReturn, std::forward<Tuple>(mArguments));
- ssize_t result(-1);
- result = write(pipe[1], this, sizeof(this));
- if (result == -1)
- logError("CAmSerializer: Problem writing into pipe! Error No:",errno);
- return (SyncCallType);
- };
- };
-
- typedef CAmDelegate* CAmDelegagePtr; //!< pointer to a delegate
-
-public:
- /**
- * instantiates a async delegate with given arguments and sends the delegate pointer over the pipe
- */
- template <typename Class, typename Method, typename Tuple>
- void doAsyncCall(Class intsance, Method method, Tuple & arguments)
- {
- typedef typename std::decay<Tuple>::type ttype;
- typedef CAmDelegateAsyncImpl<Class, Method, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value> AsyncDelegate;
- AsyncDelegate *pImp = new AsyncDelegate(intsance, method, std::forward<Tuple>(arguments));
- send(pImp);
- //Do not delete the pointer. It will be deleted automatically later.
- }
-
- /**
- * instantiates a sync delegate with given arguments and sends the delegate pointer over the pipe
- */
- template <typename Class, typename Method, typename Return, typename Tuple>
- void doSyncCall(Class intsance, Method method, Return & result, Tuple & arguments)
- {
- typedef typename std::decay<Tuple>::type ttype;
- typedef CAmDelegateSyncImpl<Class, Method, Return, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value> SyncDelegate;
- SyncDelegate *pImp = new SyncDelegate(intsance, method, std::forward<Tuple>(arguments));
- send(pImp);
- int numReads;
- SyncDelegate *p = NULL;
- if ((numReads = read(mReturnPipe[0], &p, sizeof(p))) == -1)
- {
- logError("CAmSerializer::doSyncCall could not read pipe!");
- throw std::runtime_error("CAmSerializer Could not read pipe!");
- }
- result = std::move(pImp->mReturn);
- arguments = std::move(pImp->mArguments);
- //Delete the pointer.
- delete pImp;
- }
-private:
-
- /**
- * rings the line of the pipe and adds the delegate pointer to the queue
- * @param p delegate pointer
- */
- inline void send(CAmDelegagePtr p)
- {
- if (write(mPipe[1], &p, sizeof(p)) == -1)
- {
- throw std::runtime_error("could not write to pipe !");
- }
- }
-
- int mPipe[2]; //!< the pipe
- int mReturnPipe[2]; //!< pipe handling returns
- sh_pollHandle_t mHandle;
- CAmSocketHandler* mpSocketHandler;
- std::deque<CAmDelegagePtr> mListDelegatePoiters; //!< intermediate queue to store the pipe results
-
-public:
-
- /**
- * get the size of delegate pointers
- */
- int getListDelegatePoiters()
- {
- return mListDelegatePoiters.size();
- }
-
- /**
- * calls a function with variadic arguments threadsafe
- * @param instance the instance of the class that shall be called
- * @param function the function that shall be called as member function pointer.
- * @param output variable.
- * @tparam TClass the type of the Class to be called
- * @tparam TRet the type of the result
- * @tparam TArgs argument list
- * \section ex Example:
- * @code
- * class MyGreatClass
- * {
- * public:
- * int AGreatMethod(int x);
- * }
- * CAmSerializer serial(&Sockethandler);
- * MyGreatClass anInstance;
- * int result;
- * serial.syncCall<MyGreatClass, int, int>(&anInstance,&MyGreatClass::AGreatMethod, result, 100);
- * @endcode
- */
- template<class TClass, class TRet, class ... TArgs>
- void syncCall(TClass* instance, TRet (TClass::*method)(TArgs ...), TRet & result, TArgs & ... arguments)
- {
- auto t = std::make_tuple(arguments...);
- doSyncCall(instance, method, result, t);
- std::tie(arguments...) = t;
- }
-
- /**
- * calls a function with variadic arguments threadsafe
- * @param instance the instance of the class that shall be called
- * @param function the function that shall be called as member function pointer.
- * @tparam TClass the type of the Class to be called
- * @tparam TRet the type of the result
- * @tparam TArgs argument list
- * \section ex Example:
- * @code
- * class MyGreatClass
- * {
- * public:
- * int AGreatMethod(int x);
- * }
- * CAmSerializer serial(&Sockethandler);
- * MyGreatClass anInstance;
- * serial.asyncCall<MyGreatClass, void, int>(&anInstance,&MyGreatClass::AGreatMethod, 100);
- * @endcode
- */
- template<class TClass, class TRet, class ... TArgs>
- void asyncCall(TClass* instance, TRet (TClass::*method)(TArgs ...), TArgs & ... arguments)
- {
- auto t = std::make_tuple(arguments...);
- doAsyncCall(instance, method, t);
- }
-
- /**
- * calls a function with no arguments threadsafe
- * @param instance the instance of the class that shall be called
- * @param function the function that shall be called as memberfunction pointer.
- * @tparam TClass1 the type of the Class to be called
- * \section ex Example:
- * @code
- * class myClass
- * {
- * public:
- * void myfunction();
- * }
- * CAmSerializer serial(&Sockethandler);
- * myClass instanceMyClass;
- * serial<CommandSender>(&instanceMyClass,&myClass::myfunction);
- * @endcode
- */
- template<class TClass>
- void asyncCall(TClass* instance, void (TClass::*function)())
- {
- auto t = std::make_tuple();
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with one arguments asynchronously threadsafe
- * @param instance the instance of the class that shall be called
- * @param function the function that shall be called as memberfunction pointer.
- * @param argument the argument
- * @tparam TClass1 the type of the Class to be called
- * @tparam Targ the type of the argument to be called
- * \section ex Example:
- * @code
- * class myClass
- * {
- * public:
- * void myfunction(int k);
- * }
- * CAmSerializer serial(&Sockethandler);
- * myClass instanceMyClass;
- * serial<CommandSender,int>(&instanceMyClass,&myClass::myfunction,k);
- * @endcode
- *
- */
- template<class TClass1, class Targ>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ), Targ argument)
- {
- auto t = std::make_tuple(argument);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with one argument called by reference asynchronously threadsafe
- * @param instance the instance of the class that shall be called
- * @param function the function that shall be called as memberfunction pointer.
- * @param argument the argument
- * @tparam TClass1 the type of the Class to be called
- * @tparam Targ the type of the argument to be called
- * \section ex Example:
- * @code
- * class myClass
- * {
- * public:
- * void myfunction(int k);
- * }
- * CAmSerializer serial(&Sockethandler);
- * myClass instanceMyClass;
- * serial<CommandSender,int>(&instanceMyClass,&myClass::myfunction,k);
- * @endcode
- *
- */
- template<class TClass1, class Targ>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ&), Targ& argument)
- {
- auto t = std::make_tuple(argument);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with two arguments asynchronously threadsafe. for more see asyncCall with one argument
- * @param instance pointer to the instance of the class
- * @param function memberfunction poitner
- * @param argument the first argument
- * @param argument1 the second argument
- * @tparam TClass1 the type of the Class to be called
- * @tparam Targ the type of the argument to be called
- * @tparam Targ1 the type of the first argument to be called
- */
- template<class TClass1, class Targ, class Targ1>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1), Targ argument, Targ1 argument1)
- {
- auto t = std::make_tuple(argument,argument1);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with two arguments asynchronously threadsafe, first argument is a reference. for more see asyncCall with one argument
- * @param instance pointer to the instance of the class
- * @param function memberfunction poitner
- * @param argument the first argument
- * @param argument1 the second argument
- * @tparam TClass1 the type of the Class to be called
- * @tparam Targ the type of the argument to be called
- * @tparam Targ1 the type of the first argument to be called
- */
- template<class TClass1, class Targ, class Targ1>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1 argument1), Targ& argument, Targ1 argument1)
- {
- auto t = std::make_tuple(argument,argument1);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with two arguments asynchronously threadsafe, second argument is a reference. for more see asyncCall with one argument
- * @param instance pointer to the instance of the class
- * @param function memberfunction poitner
- * @param argument the first argument
- * @param argument1 the second argument
- * @tparam TClass1 the type of the Class to be called
- * @tparam Targ the type of the argument to be called
- * @tparam Targ1 the type of the first argument to be called
- */
- template<class TClass1, class Targ, class Targ1>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1& argument1), Targ argument, Targ1& argument1)
- {
- auto t = std::make_tuple(argument,argument1);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with two arguments asynchronously threadsafe, both arguments are references. for more see asyncCall with one argument
- * @param instance pointer to the instance of the class
- * @param function memberfunction poitner
- * @param argument the first argument
- * @param argument1 the second argument
- * @tparam TClass1 the type of the Class to be called
- * @tparam Targ the type of the argument to be called
- * @tparam Targ1 the type of the first argument to be called
- */
- template<class TClass1, class Targ, class Targ1>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1& argument1), Targ& argument, Targ1& argument1)
- {
- auto t = std::make_tuple(argument,argument1);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with three arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1, Targ2 argument2), Targ argument, Targ1 argument1, Targ2 argument2)
- {
- auto t = std::make_tuple(argument,argument1, argument2);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with three arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1 argument1, Targ2 argument2), Targ& argument, Targ1 argument1, Targ2 argument2)
- {
- auto t = std::make_tuple(argument,argument1, argument2);
- doAsyncCall(instance, function, t);
- }
-
-
- /**
- * calls a function with three arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1& argument1, Targ2 argument2), Targ argument, Targ1& argument1, Targ2 argument2)
- {
- auto t = std::make_tuple(argument,argument1, argument2);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with three arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1, Targ2& argument2), Targ argument, Targ1 argument1, Targ2& argument2)
- {
- auto t = std::make_tuple(argument,argument1, argument2);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with three arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1& argument1, Targ2& argument2), Targ argument, Targ1& argument1, Targ2& argument2)
- {
- auto t = std::make_tuple(argument,argument1, argument2);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with three arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1& argument1, Targ2& argument2), Targ& argument, Targ1& argument1, Targ2& argument2)
- {
- auto t = std::make_tuple(argument,argument1, argument2);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with three arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1& argument1, Targ2 argument2), Targ& argument, Targ1& argument1, Targ2 argument2)
- {
- auto t = std::make_tuple(argument,argument1, argument2);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with three arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1 argument1, Targ2& argument2), Targ& argument, Targ1 argument1, Targ2& argument2)
- {
- auto t = std::make_tuple(argument,argument1, argument2);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a function with four arguments asynchronously threadsafe. for more see other asycCall
- */
- template<class TClass1, class Targ, class Targ1, class Targ2, class Targ3>
- void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3), Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3)
- {
- auto t = std::make_tuple(argument,argument1, argument2,argument3);
- doAsyncCall(instance, function, t);
- }
-
- /**
- * calls a synchronous function with no arguments threadsafe
- * @param instance the instance of the class that shall be called
- * @param function the function that shall be called as memberfunction pointer.
- * @param retVal the return parameter, no const allowed !
- * @tparam TClass1 the type of the class to be called
- * @tparam TretVal the type of the return parameter
- * \section ex Example:
- * @code
- * class myClass
- * {
- * public:
- * am_Error_e myfunction();
- * }
- * CAmSerializer serial(&Sockethandler);
- * myClass instanceMyClass;
- * am_Error_e error;
- * serial<CommandSender,am_Error_e>(&instanceMyClass,&myClass::myfunction, error);
- * @endcode
- * All arguments given to synchronous functions must be non-const since the results of the operations will be written back to the arguments.
- *
- */
- template<class TClass1, class TretVal>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(), TretVal& retVal)
- {
- auto t = std::make_tuple();
- doSyncCall(instance, function, retVal, t);
- }
-
- /**
- * calls a function with one argument synchronous threadsafe
- * @param instance the instance of the class that shall be called
- * @param function the function that shall be called as memberfunction pointer.
- * @param retVal the return parameter, no const allowed !
- * @param argument the argument, no const allowed !
- * @tparam TClass1 the type of the class to be called
- * @tparam TretVal the type of the return parameter
- * @tparam TargCall the type of the argument like in the function to be called. here all references and const must be
- * respected!
- * @tparam Targ the type of the argument, here no const and no references allowed !
- * \section ex Example:
- * @code
- * class myClass
- * {
- * public:
- * am_Error_e myfunction(int k);
- * }
- * CAmSerializer serial(&Sockethandler);
- * myClass instanceMyClass;
- * am_Error_e error;
- * int l;
- * serial<CommandSender,am_Error_e,int>(&instanceMyClass,&myClass::myfunction,error,l);
- * @endcode
- * All arguments given to synchronous functions must be non-const since the results of the operations will be written back to the arguments.
- */
- template<class TClass1, class TretVal, class TargCall, class Targ>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall), TretVal& retVal, Targ& argument)
- {
- auto t = std::make_tuple(argument);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument) = t;
- }
-
- /**
- * calls a function with one argument synchronous threadsafe for const functions. For more see syncCall with one argument
- */
- template<class TClass1, class TretVal, class TargCall, class Targ>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall) const, TretVal& retVal, Targ& argument)
- {
- auto t = std::make_tuple(argument);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument) = t;
- }
-
- /**
- * calls a function with two arguments synchronously threadsafe. For more see syncCall with one argument
- */
- template<class TClass1, class TretVal, class TargCall, class Targ1Call, class Targ, class Targ1>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, Targ1Call), TretVal& retVal, Targ& argument, Targ1& argument1)
- {
- auto t = std::make_tuple(argument, argument1);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument, argument1) = t;
- }
- /**
- * calls a function with two arguments synchronously threadsafe const. For more see syncCall with one argument
- */
- template<class TClass1, class TretVal, class TargCall, class Targ1Call, class Targ, class Targ1>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, Targ1Call) const, TretVal& retVal, Targ& argument, Targ1& argument1)
- {
- auto t = std::make_tuple(argument, argument1);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument, argument1) = t;
- }
-
- /**
- * calls a function with three arguments synchronously threadsafe. for more see syncCall with one argument
- */
- template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class Targ, class Targ1, class Targ2>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2)
- {
- auto t = std::make_tuple(argument, argument1, argument2);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument, argument1,argument2) = t;
- }
-
- /**
- * calls a const function with three arguments synchronously threadsafe. for more see syncCall with one argument
- */
- template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class Targ, class Targ1, class Targ2>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2) const, TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2)
- {
- auto t = std::make_tuple(argument, argument1, argument2);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument, argument1,argument2) = t;
- }
-
- /**
- * calls a function with four arguments synchronously threadsafe. for more see syncCall with one argument
- */
- template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class Targ, class Targ1, class Targ2, class Targ3>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3)
- {
- auto t = std::make_tuple(argument, argument1, argument2, argument3);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument, argument1,argument2, argument3) = t;
- }
-
- /**
- * calls a function with five arguments synchronously threadsafe. for more see syncCall with one argument
- */
- template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class TargCall4, class Targ, class Targ1, class Targ2, class Targ3, class Targ4>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3, TargCall4), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3, Targ4& argument4)
- {
- auto t = std::make_tuple(argument, argument1, argument2, argument3, argument4);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument, argument1,argument2, argument3, argument4) = t;
- }
-
- /**
- * calls a function with six arguments synchronously threadsafe. for more see syncCall with one argument
- */
- template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class TargCall4, class TargCall5, class Targ, class Targ1, class Targ2, class Targ3, class Targ4, class Targ5>
- void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3, TargCall4, TargCall5), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3, Targ4& argument4, Targ5& argument5)
- {
- auto t = std::make_tuple(argument, argument1, argument2, argument3, argument4, argument5);
- doSyncCall(instance, function, retVal, t);
- std::tie(argument, argument1,argument2, argument3, argument4, argument5) = t;
- }
-
- /**
- * receiver callback for sockethandling, for more, see CAmSocketHandler
- */
- void receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
- {
- (void) handle;
- (void) userData;
- int numReads;
- CAmDelegagePtr listPointers[3];
- if ((numReads = read(pollfd.fd, &listPointers, sizeof(listPointers))) == -1)
- {
- logError("CAmSerializer::receiverCallback could not read pipe!");
- throw std::runtime_error("CAmSerializer Could not read pipe!");
- }
- mListDelegatePoiters.assign(listPointers, listPointers + (numReads / sizeof(CAmDelegagePtr)));
- }
-
- /**
- * checker callback for sockethandling, for more, see CAmSocketHandler
- */
- bool checkerCallback(const sh_pollHandle_t handle, void* userData)
- {
- (void) handle;
- (void) userData;
- if (mListDelegatePoiters.empty())
- return (false);
- return (true);
- }
-
- /**
- * dispatcher callback for sockethandling, for more, see CAmSocketHandler
- */
- bool dispatcherCallback(const sh_pollHandle_t handle, void* userData)
- {
- (void) handle;
- (void) userData;
- CAmDelegagePtr delegatePoiter = mListDelegatePoiters.front();
- mListDelegatePoiters.pop_front();
- if (delegatePoiter->call(mReturnPipe))
- delete delegatePoiter;
- if (mListDelegatePoiters.empty())
- return (false);
- return (true);
- }
-
- TAmShPollFired<CAmSerializer> receiverCallbackT;
- TAmShPollDispatch<CAmSerializer> dispatcherCallbackT;
- TAmShPollCheck<CAmSerializer> checkerCallbackT;
-
- /**
- * The constructor must be called in the mainthread context !
- * @param iSocketHandler pointer to the CAmSocketHandler
- */
- CAmSerializer(CAmSocketHandler *iSocketHandler) :
- mPipe(), //
- mReturnPipe(),//
- mHandle(),
- mpSocketHandler(iSocketHandler),
- mListDelegatePoiters(), //
- receiverCallbackT(this, &CAmSerializer::receiverCallback), //
- dispatcherCallbackT(this, &CAmSerializer::dispatcherCallback), //
- checkerCallbackT(this, &CAmSerializer::checkerCallback)
- {
- assert(NULL!=iSocketHandler);
-
- if (pipe(mPipe) == -1)
- {
- logError("CAmSerializer could not create pipe!");
- throw std::runtime_error("CAmSerializer Could not open pipe!");
- }
-
- if (pipe(mReturnPipe) == -1)
- {
- logError("CAmSerializer could not create mReturnPipe!");
- throw std::runtime_error("CAmSerializer Could not open mReturnPipe!");
- }
-
- short event = 0;
- event |= POLLIN;
- mpSocketHandler->addFDPoll(mPipe[0], event, NULL, &receiverCallbackT, &checkerCallbackT, &dispatcherCallbackT, NULL, mHandle);
- }
-
- ~CAmSerializer()
- {
- mpSocketHandler->removeFDPoll(mHandle);
- close(mPipe[0]);
- close(mPipe[1]);
- close(mReturnPipe[0]);
- close(mReturnPipe[1]);
- }
-};
-} /* namespace am */
-#endif /* CAMSERIALIZER_H_ */
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ * \author Alesksandar Donchev, aleksander.donchev@partner.bmw.de BMW 2015
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file CAmSerializer.h
+ * For further information see http://www.genivi.org/.
+ */
+
+#ifndef CAMSERIALIZER_H_
+#define CAMSERIALIZER_H_
+
+#include <pthread.h>
+#include <deque>
+#include <cassert>
+#include <memory>
+#include <stdexcept>
+#include <unistd.h>
+#include "CAmDltWrapper.h"
+#include "CAmSocketHandler.h"
+
+/*!
+ * \brief Helper structures used within std::bind for automatically identification of all placeholders.
+ */
+template<std::size_t ... Is>
+struct indices
+{
+};
+
+template<std::size_t N, std::size_t ... Is>
+struct build_indices: build_indices<N - 1, N - 1, Is...>
+{
+};
+
+template<std::size_t ... Is>
+struct build_indices<0, Is...> : indices<Is...>
+{
+};
+
+template<int I> struct placeholder
+{
+};
+
+namespace std
+{
+ template<int I>
+ struct is_placeholder<::placeholder<I>> : std::integral_constant<int, I>
+ {
+ };
+}
+
+/**
+ * todo: performance improvement we could implement a memory pool that is more efficient here and avoids
+ * allocation and deallocation times.
+ */
+
+namespace am
+{
+
+ /**
+ * magic class that does the serialization of functions calls
+ * The constructor must be called within the main threadcontext, after that using the
+ * overloaded template function call will serialize all calls and call them within the
+ * main thread context.\n
+ * More details can be found here: \ref util
+ * \warning asynchronous calls may be used in the mainthread context, but if you want to use synchronous calls make sure that you use one
+ * instance of this class per thread otherwise you could be lost in never returning calls.\n
+ * Examples of the usage can be found in IAmCommandReceiverShadow of the ControlPlugin or IAmRoutingReceiverShadow of the
+ * PluginRoutingInterfaceAsync.
+ *
+ */
+ class CAmSerializer
+ {
+ /**
+ * Prototype for a delegate
+ */
+ class CAmDelegate
+ {
+ public:
+ typedef enum
+ :bool
+ {
+ SyncCallType = false, AsyncCallType = true
+ } CallType;
+
+ virtual ~CAmDelegate()
+ {
+ }
+ ;
+ virtual CallType call(int* pipe)=0;
+ };
+
+ /**
+ * Prototype for a delegate with variadic template arguments.
+ */
+ template<class TInvocation>
+ class CAmDelegateAsyncImpl: public CAmDelegate
+ {
+ TInvocation mInvocation;
+ public:
+ friend class CAmSerializer;
+ CAmDelegateAsyncImpl(TInvocation && invocation) :
+ mInvocation(std::move(invocation))
+ {
+ }
+
+ CallType call(int* pipe)
+ {
+ (void) pipe;
+ mInvocation();
+ return (AsyncCallType);
+ }
+ ;
+ };
+
+ template<class TInvocation, class TRet>
+ class CAmDelegateSyncImpl: public CAmDelegate
+ {
+ TInvocation mInvocation;
+ TRet & mReturn;
+ public:
+ friend class CAmSerializer;
+ CAmDelegateSyncImpl(TInvocation && invocation, TRet && ret) :
+ mInvocation(std::move(invocation)), mReturn(ret)
+ {
+ }
+
+ CallType call(int* pipe)
+ {
+ mReturn = mInvocation();
+ ssize_t result(-1);
+ result = write(pipe[1], this, sizeof(this));
+ if (result == -1)
+ logError("CAmSerializer: Problem writing into pipe! Error No:", errno);
+ return (SyncCallType);
+ }
+ ;
+ };
+
+ template<class TInvocation>
+ class CAmDelegateSyncVoidImpl: public CAmDelegate
+ {
+ TInvocation mInvocation;
+ public:
+ friend class CAmSerializer;
+ CAmDelegateSyncVoidImpl(TInvocation && invocation) :
+ mInvocation(std::move(invocation))
+ {
+ }
+
+ CallType call(int* pipe)
+ {
+ mInvocation();
+ ssize_t result(-1);
+ result = write(pipe[1], this, sizeof(this));
+ if (result == -1)
+ logError("CAmSerializer: Problem writing into pipe! Error No:", errno);
+ return (SyncCallType);
+ }
+ ;
+ };
+
+ typedef CAmDelegate* CAmDelegagePtr; //!< pointer to a delegate
+
+ void sendSync(CAmDelegagePtr pDelegate)
+ {
+ send(pDelegate);
+ int numReads;
+ CAmDelegagePtr *p = NULL;
+ if ((numReads = read(mReturnPipe[0], &p, sizeof(p))) == -1)
+ {
+ logError("CAmSerializer::doSyncCall could not read pipe!");
+ throw std::runtime_error("CAmSerializer Could not read pipe!");
+ }
+ }
+
+ /**
+ * rings the line of the pipe and adds the delegate pointer to the queue
+ * @param p delegate pointer
+ */
+ inline void send(CAmDelegagePtr p)
+ {
+ if (write(mPipe[1], &p, sizeof(p)) == -1)
+ {
+ throw std::runtime_error("could not write to pipe !");
+ }
+ }
+
+ int mPipe[2]; //!< the pipe
+ int mReturnPipe[2]; //!< pipe handling returns
+ sh_pollHandle_t mHandle;
+ CAmSocketHandler* mpSocketHandler;
+ std::deque<CAmDelegagePtr> mListDelegatePoiters; //!< intermediate queue to store the pipe results
+
+ public:
+
+ /**
+ * get the size of delegate pointers
+ */
+ int getListDelegatePoiters()
+ {
+ return mListDelegatePoiters.size();
+ }
+
+ /**
+ * calls a function with variadic arguments threadsafe
+ * @param invocation is a type is produced by std::bind
+ * \section ex Example:
+ * @code
+ * CAmSerializer serial(&Sockethandler);
+ * serial.asyncInvocation(std::bind([]()->bool{return true;}));
+ * @endcode
+ */
+ template<class TFunc>
+ void asyncInvocation(TFunc invocation)
+ {
+ static_assert(std::is_bind_expression<TFunc>::value,"The type is not produced by std::bind");
+ typedef CAmDelegateAsyncImpl<TFunc> AsyncDelegate;
+ AsyncDelegate *pImp = new AsyncDelegate(std::forward<TFunc>(invocation));
+ send(pImp);
+ //Do not delete the pointer. It will be deleted automatically later.
+ }
+
+ /**
+ * calls a function with variadic arguments threadsafe
+ * @param instance the instance of the class that shall be called
+ * @param function the function that shall be called as member function pointer.
+ * @tparam TClass the type of the Class to be called
+ * @tparam TRet the type of the result
+ * @tparam TArgs argument list
+ * \section ex Example:
+ * @code
+ * class AClass
+ * {
+ * public:
+ * void instanceMethod(int x);
+ * }
+ * CAmSerializer serial(&Sockethandler);
+ * AClass anInstance;
+ * serial.asyncCall(&anInstance,&AClass::instanceMethod, 100);
+ * @endcode
+ */
+ template<class TClass, class TMeth, class TRet, class ... TArgs>
+ void asyncCall(TClass* instance, TMeth method, TArgs && ... arguments)
+ {
+ auto invocation = std::bind(method, instance, std::forward<TArgs>(arguments)...);
+ asyncInvocation(invocation);
+ }
+
+ template<class TClass, class TMeth, class ... TArgs>
+ void asyncCall(TClass* instance, TMeth method, TArgs && ... arguments)
+ {
+ auto invocation = std::bind(method, instance, std::forward<TArgs>(arguments)...);
+ asyncInvocation(invocation);
+ }
+
+ /**
+ * calls a function with variadic arguments threadsafe
+ * @param invocation is a type is produced by std::bind
+ * @param result from type TRet
+ * \section ex Example:
+ * @code
+ * CAmSerializer serial(&Sockethandler);
+ * bool result;
+ * serial.syncCall(std::bind([]()->bool{return true;}), result);
+ * @endcode
+ */
+ template<class TFunc, class TRet>
+ void syncInvocation(TFunc invocation, TRet && result)
+ {
+ static_assert(std::is_bind_expression<TFunc>::value,"The type is not produced by std::bind");
+
+ typedef CAmDelegateSyncImpl<TFunc, TRet> SyncDelegate;
+
+ SyncDelegate *pImp = new SyncDelegate(std::forward<TFunc>(invocation), std::forward<TRet>(result));
+ sendSync(pImp);
+ //Delete the pointer.
+ delete pImp;
+ }
+
+ /**
+ * calls a function with variadic arguments threadsafe
+ * @param invocation is a type is produced by std::bind
+ * \section ex Example:
+ * @code
+ * CAmSerializer serial(&Sockethandler);
+ * serial.syncCall(std::bind([]()->bool{return true;}));
+ * @endcode
+ */
+ template<class TFunc>
+ void syncInvocation(TFunc invocation)
+ {
+ static_assert(std::is_bind_expression<TFunc>::value,"The type is not produced by std::bind");
+
+ typedef CAmDelegateSyncVoidImpl<TFunc> SyncDelegate;
+
+ SyncDelegate *pImp = new SyncDelegate(std::forward<TFunc>(invocation));
+ sendSync(pImp);
+ //Delete the pointer.
+ delete pImp;
+ }
+ /**
+ * calls a function with variadic arguments threadsafe
+ * @param instance the instance of the class that shall be called
+ * @param function the function that shall be called as member function pointer.
+ * @param output variable.
+ * @tparam TClass the type of the Class to be called
+ * @tparam TRet the type of the result
+ * @tparam TArgs argument list
+ * \section ex Example:
+ * @code
+ * class AClass
+ * {
+ * public:
+ * int instanceMethod(int x);
+ * }
+ * CAmSerializer serial(&Sockethandler);
+ * AClass anInstance;
+ * int result;
+ * serial.syncCall(&anInstance,&AClass::instanceMethod, result, 100);
+ * @endcode
+ */
+ template<class TClass, class TMeth, class TRet, class ... TArgs>
+ void syncCall(TClass* instance, TMeth method, TRet & result, TArgs && ... arguments)
+ {
+ auto invocation = std::bind(method, instance, std::ref(arguments)...);
+ syncInvocation(invocation, result);
+ }
+
+ template<class TClass, class TMeth, class ... TArgs>
+ void syncCall(TClass* instance, TMeth method, TArgs && ... arguments)
+ {
+ auto invocation = std::bind(method, instance, std::ref(arguments)...);
+ syncInvocation(invocation);
+ }
+
+ /**************************************** Obsolete interface! ****************************************/
+
+ /**
+ * calls a function without arguments synchronously threadsafe.
+ */
+ template<class TClass1, class TretVal>
+ void __attribute__ ((deprecated)) syncCall(TClass1* instance, TretVal (TClass1::*function)(), TretVal& retVal)
+ {
+ auto invocation = std::bind(function, instance);
+ syncInvocation(invocation, retVal);
+ }
+ /**
+ * calls a function with one arguments synchronously threadsafe.
+ */
+ template<class TClass1, class TretVal, class TargCall, class Targ>
+ void __attribute__ ((deprecated)) syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall), TretVal& retVal, Targ& argument)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument));
+ syncInvocation(invocation, retVal);
+ }
+ /**
+ * calls a function with two arguments synchronously threadsafe.
+ */
+ template<class TClass1, class TretVal, class TargCall, class TargCall1, class Targ, class Targ1>
+ void __attribute__ ((deprecated)) syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1), TretVal& retVal, Targ& argument, Targ1& argument1)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument), std::ref(argument1));
+ syncInvocation(invocation, retVal);
+ }
+ /**
+ * calls a function with three arguments synchronously threadsafe.
+ */
+ template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class Targ, class Targ1, class Targ2>
+ void __attribute__ ((deprecated)) syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument), std::ref(argument1), std::ref(argument2));
+ syncInvocation(invocation, retVal);
+ }
+
+ /**
+ * calls a function with four arguments synchronously threadsafe.
+ */
+ template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class Targ, class Targ1, class Targ2, class Targ3>
+ void __attribute__ ((deprecated)) syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument), std::ref(argument1), std::ref(argument2), std::ref(argument3));
+ syncInvocation(invocation, retVal);
+ }
+
+ /**
+ * calls a function with five arguments synchronously threadsafe.
+ */
+ template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class TargCall4, class Targ, class Targ1, class Targ2, class Targ3, class Targ4>
+ void __attribute__ ((deprecated)) syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3, TargCall4), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3,
+ Targ4& argument4)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument), std::ref(argument1), std::ref(argument2), std::ref(argument3), std::ref(argument4));
+ syncInvocation(invocation, retVal);
+ }
+ /**
+ * calls a function with six arguments synchronously threadsafe.
+ */
+ template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class TargCall4, class TargCall5, class Targ, class Targ1, class Targ2, class Targ3, class Targ4, class Targ5>
+ void __attribute__ ((deprecated)) syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3, TargCall4, TargCall5), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2&& argument2,
+ Targ3& argument3, Targ4& argument4, Targ5& argument5)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument), std::ref(argument1), std::ref(argument2), std::ref(argument3), std::ref(argument4), std::ref(argument5));
+ syncInvocation(invocation, retVal);
+ }
+
+ /**
+ * calls a function with one argument asynchronously threadsafe.
+ */
+ template<class TClass1, class Targ>
+ void __attribute__ ((deprecated)) asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument), Targ &argument)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument));
+ asyncInvocation(invocation);
+ }
+ /**
+ * calls a function with two arguments asynchronously threadsafe.
+ */
+ template<class TClass1, class Targ, class Targ1>
+ void __attribute__ ((deprecated)) asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1), Targ& argument, Targ1& argument1)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument), std::ref(argument1));
+ asyncInvocation(invocation);
+ }
+ /**
+ * calls a function with three arguments asynchronously threadsafe.
+ */
+ template<class TClass1, class Targ, class Targ1, class Targ2>
+ void __attribute__ ((deprecated)) asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1, Targ2 argument2), Targ& argument, Targ1& argument1, Targ2& argument2)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument), std::ref(argument1), std::ref(argument2));
+ asyncInvocation(invocation);
+ }
+
+ /**
+ * calls a function with four arguments asynchronously threadsafe.
+ */
+ template<class TClass1, class Targ, class Targ1, class Targ2, class Targ3>
+ void __attribute__ ((deprecated)) asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3), Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3)
+ {
+ auto invocation = std::bind(function, instance, std::ref(argument), std::ref(argument1), std::ref(argument2), std::ref(argument3));
+ asyncInvocation(invocation);
+ }
+
+ /**
+ * receiver callback for sockethandling, for more, see CAmSocketHandler
+ */
+ void receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
+ {
+ (void) handle;
+ (void) userData;
+ int numReads;
+ CAmDelegagePtr listPointers[3];
+ if ((numReads = read(pollfd.fd, &listPointers, sizeof(listPointers))) == -1)
+ {
+ logError("CAmSerializer::receiverCallback could not read pipe!");
+ throw std::runtime_error("CAmSerializer Could not read pipe!");
+ }
+ mListDelegatePoiters.assign(listPointers, listPointers + (numReads / sizeof(CAmDelegagePtr)));
+ }
+
+ /**
+ * checker callback for sockethandling, for more, see CAmSocketHandler
+ */
+ bool checkerCallback(const sh_pollHandle_t handle, void* userData)
+ {
+ (void) handle;
+ (void) userData;
+ if (mListDelegatePoiters.empty())
+ return (false);
+ return (true);
+ }
+
+ /**
+ * dispatcher callback for sockethandling, for more, see CAmSocketHandler
+ */
+ bool dispatcherCallback(const sh_pollHandle_t handle, void* userData)
+ {
+ (void) handle;
+ (void) userData;
+ CAmDelegagePtr delegatePoiter = mListDelegatePoiters.front();
+ mListDelegatePoiters.pop_front();
+ if (delegatePoiter->call(mReturnPipe))
+ delete delegatePoiter;
+ if (mListDelegatePoiters.empty())
+ return (false);
+ return (true);
+ }
+
+ TAmShPollFired<CAmSerializer> receiverCallbackT;
+ TAmShPollDispatch<CAmSerializer> dispatcherCallbackT;
+ TAmShPollCheck<CAmSerializer> checkerCallbackT;
+
+ /**
+ * The constructor must be called in the mainthread context !
+ * @param iSocketHandler pointer to the CAmSocketHandler
+ */
+ CAmSerializer(CAmSocketHandler *iSocketHandler) :
+ mPipe(), //
+ mReturnPipe(), //
+ mHandle(),
+ mpSocketHandler(iSocketHandler),
+ mListDelegatePoiters(), //
+ receiverCallbackT(this, &CAmSerializer::receiverCallback), //
+ dispatcherCallbackT(this, &CAmSerializer::dispatcherCallback), //
+ checkerCallbackT(this, &CAmSerializer::checkerCallback)
+ {
+ assert(NULL!=iSocketHandler);
+
+ if (pipe(mPipe) == -1)
+ {
+ logError("CAmSerializer could not create pipe!");
+ throw std::runtime_error("CAmSerializer Could not open pipe!");
+ }
+
+ if (pipe(mReturnPipe) == -1)
+ {
+ logError("CAmSerializer could not create mReturnPipe!");
+ throw std::runtime_error("CAmSerializer Could not open mReturnPipe!");
+ }
+
+ short event = 0;
+ event |= POLLIN;
+ mpSocketHandler->addFDPoll(mPipe[0], event, NULL, &receiverCallbackT, &checkerCallbackT, &dispatcherCallbackT, NULL, mHandle);
+ }
+
+ ~CAmSerializer()
+ {
+ mpSocketHandler->removeFDPoll(mHandle);
+ close(mPipe[0]);
+ close(mPipe[1]);
+ close(mReturnPipe[0]);
+ close(mReturnPipe[1]);
+ }
+ };
+} /* namespace am */
+#endif /* CAMSERIALIZER_H_ */
+
diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h
index d7d4b38..4519c0c 100644
--- a/AudioManagerUtilities/include/CAmSocketHandler.h
+++ b/AudioManagerUtilities/include/CAmSocketHandler.h
@@ -30,7 +30,6 @@
#include <audiomanagerconfig.h>
#include "audiomanagertypes.h"
-
#ifdef WITH_TIMERFD
#include <stdio.h>
@@ -427,7 +426,7 @@ namespace am
* @return
*/
inline static void prepare(am::CAmSocketHandler::sh_poll_s& row);
-
+
/**
* functor to return all fired events
* @param a
@@ -435,14 +434,12 @@ namespace am
*/
inline static void fire(sh_poll_s* a);
-
/**
* functor to return all fired events
* @param a
* @return
*/
inline static bool eventFired(const pollfd& a);
-
/**
* functor to help find the items that do not need dispatching
@@ -464,7 +461,7 @@ namespace am
* @return
*/
inline static void callTimer(sh_timer_s& a);
-
+
VectorListPollfd_t mfdPollingArray; //!<the polling array for ppoll
std::set<sh_pollHandle_t> mSetPollKeys; //!A set of all used ppoll keys
VectorListPoll_t mListPoll; //!<list that holds all information for the ppoll
diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp
index 9ee7996..44c041e 100644
--- a/AudioManagerUtilities/src/CAmSocketHandler.cpp
+++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp
@@ -63,7 +63,9 @@ namespace am
short event = 0;
sh_pollHandle_t handle;
event |= POLLIN;
- addFDPoll(mPipe[0], event, NULL, [](const pollfd pollfd, const sh_pollHandle_t, void*){}, [](const sh_pollHandle_t, void*){ return (false);}, NULL, NULL, handle);
+ addFDPoll(mPipe[0], event, NULL, [](const pollfd pollfd, const sh_pollHandle_t, void*)
+ {}, [](const sh_pollHandle_t, void*)
+ { return (false);}, NULL, NULL, handle);
}
CAmSocketHandler::~CAmSocketHandler()
@@ -102,6 +104,7 @@ namespace am
//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;
VectorListPoll_t::iterator listmPollIt;
+ VectorListPollfd_t::iterator itMfdPollingArray;
auto preparePollfd = [&](const sh_poll_s& row)
{
@@ -149,7 +152,7 @@ namespace am
//todo: here could be a timer that makes sure naughty plugins return!
listPoll.clear();
//stage 0+1, call firedCB
- for (VectorListPollfd_t::iterator itMfdPollingArray = mfdPollingArray.begin(); itMfdPollingArray != mfdPollingArray.end(); itMfdPollingArray++)
+ for (itMfdPollingArray = mfdPollingArray.begin(); itMfdPollingArray != mfdPollingArray.end(); itMfdPollingArray++)
{
if (CAmSocketHandler::eventFired(*itMfdPollingArray))
{
@@ -409,8 +412,9 @@ namespace am
mListTimer.pop_back();
return err;
}
-
- static auto actionPoll = [](const pollfd pollfd, const sh_pollHandle_t handle, void* userData){
+
+ static auto actionPoll = [](const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
+ {
uint64_t mExpirations;
if (read(pollfd.fd, &mExpirations, sizeof(uint64_t)) == -1)
{
@@ -418,8 +422,9 @@ namespace am
read(pollfd.fd, &mExpirations, sizeof(uint64_t));
}
};
-
- err = addFDPoll(timerItem.fd, POLLIN, NULL, actionPoll, [callback](const sh_pollHandle_t handle, void* userData)->bool{
+
+ err = addFDPoll(timerItem.fd, POLLIN, NULL, actionPoll, [callback](const sh_pollHandle_t handle, void* userData)->bool
+ {
callback(handle, userData);
return false;
},
@@ -794,69 +799,68 @@ namespace am
}
}
#endif
-
- /**
- * prepare for poll
- */
- void CAmSocketHandler::prepare(am::CAmSocketHandler::sh_poll_s& row)
- {
- if (row.prepareCB)
- {
- try
- {
- row.prepareCB(row.handle, row.userData);
- } catch (std::exception& e)
- {
- logError("Sockethandler: Exception in Preparecallback,caught", e.what());
- }
- }
- }
-
- /**
- * fire callback
- */
- void CAmSocketHandler::fire(sh_poll_s* a)
+ /**
+ * prepare for poll
+ */
+ void CAmSocketHandler::prepare(am::CAmSocketHandler::sh_poll_s& row)
+ {
+ if (row.prepareCB)
{
try
{
- a->firedCB(a->pollfdValue, a->handle, a->userData);
+ row.prepareCB(row.handle, row.userData);
} catch (std::exception& e)
{
- logError("Sockethandler: Exception in FireCallback,caught", e.what());
+ logError("Sockethandler: Exception in Preparecallback,caught", e.what());
}
}
-
- /**
- * event triggered
- */
- bool CAmSocketHandler::eventFired(const pollfd& a)
- {
- return (a.revents == 0 ? false : true);
- }
+ }
- /**
- * should disptach
- */
- bool CAmSocketHandler::noDispatching(const sh_poll_s* a)
+ /**
+ * fire callback
+ */
+ void CAmSocketHandler::fire(sh_poll_s* a)
+ {
+ try
{
- //remove from list of there is no checkCB
- if (!a->checkCB)
- return (true);
- return (!a->checkCB(a->handle, a->userData));
- }
-
- /**
- * disptach
- */
- bool CAmSocketHandler::dispatchingFinished(const sh_poll_s* a)
+ a->firedCB(a->pollfdValue, a->handle, a->userData);
+ } catch (std::exception& e)
{
- //remove from list of there is no dispatchCB
- if (!a->dispatchCB)
- return (true);
- return (!a->dispatchCB(a->handle, a->userData));
+ logError("Sockethandler: Exception in FireCallback,caught", e.what());
}
-
+ }
+
+ /**
+ * event triggered
+ */
+ bool CAmSocketHandler::eventFired(const pollfd& a)
+ {
+ return (a.revents == 0 ? false : true);
+ }
+
+ /**
+ * should disptach
+ */
+ bool CAmSocketHandler::noDispatching(const sh_poll_s* a)
+ {
+ //remove from list of there is no checkCB
+ if (!a->checkCB)
+ return (true);
+ return (!a->checkCB(a->handle, a->userData));
+ }
+
+ /**
+ * disptach
+ */
+ bool CAmSocketHandler::dispatchingFinished(const sh_poll_s* a)
+ {
+ //remove from list of there is no dispatchCB
+ if (!a->dispatchCB)
+ return (true);
+ return (!a->dispatchCB(a->handle, a->userData));
+ }
+
/**
* is used to set the pointer for the ppoll command
* @param buffertime
diff --git a/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp b/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp
new file mode 100644
index 0000000..06488ea
--- /dev/null
+++ b/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp
@@ -0,0 +1,158 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include <cstdio>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <sys/un.h>
+#include <sys/poll.h>
+
+#include "CAmSocketHandler.h"
+#include "CAmSerializer.h"
+#include "CAmSerializerTest.h"
+
+using namespace testing;
+using namespace am;
+
+CAmTimerSockethandlerController::CAmTimerSockethandlerController(CAmSocketHandler *myHandler, const timespec &timeout) :
+ MockIAmTimerCb(), mpSocketHandler(myHandler), mUpdateTimeout(timeout), pTimerCallback(this, &CAmTimerSockethandlerController::timerCallback)
+{
+}
+
+am::CAmTimerSockethandlerController::~CAmTimerSockethandlerController()
+{
+}
+
+void am::CAmTimerSockethandlerController::timerCallback(sh_timerHandle_t handle, void* userData)
+{
+ MockIAmTimerCb::timerCallback(handle, userData);
+ mpSocketHandler->stop_listening();
+}
+
+CAmSerializerTest::CAmSerializerTest()
+{
+}
+
+CAmSerializerTest::~CAmSerializerTest()
+{
+}
+
+void CAmSerializerTest::SetUp()
+{
+
+}
+
+void CAmSerializerTest::TearDown()
+{
+}
+
+struct SerializerData
+{
+
+ std::string testStr;
+ int result;
+ MockIAmSerializerCb *pSerCb;
+ CAmSocketHandler *pSocketHandler;
+ CAmSerializer *pSerializer;
+};
+
+void* ptSerializer(void* data)
+{
+ SerializerData *pData = (SerializerData*) data;
+ std::string testStr(pData->testStr);
+ bool result = false;
+ int r = 0;
+ const uint32_t ten = 10;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ pData->pSerializer->syncCall(pData->pSerCb, &MockIAmSerializerCb::check);
+ pData->pSerializer->syncCall(pData->pSerCb, &MockIAmSerializerCb::checkInt, pData->result);
+ pData->pSerializer->syncCall(pData->pSerCb, &MockIAmSerializerCb::dispatchData, result, ten, pData->testStr);
+
+ for (uint32_t i = 0; i < 5; i++)
+ pData->pSerializer->asyncCall(pData->pSerCb, &MockIAmSerializerCb::dispatchData, i, testStr);
+
+ pData->pSerializer->asyncInvocation(std::bind([]()->bool
+ { return 1;}));
+ pData->pSerializer->asyncInvocation(std::bind([](const int i, int & result)
+ { result = i*10;}, 1, std::ref(r)));
+
+ pData->pSerializer->asyncCall(pData->pSerCb, &MockIAmSerializerCb::check);
+ pData->pSerializer->asyncCall(pData->pSerCb, &MockIAmSerializerCb::check);
+
+ pData->pSerializer->asyncCall(pData->pSerCb, &MockIAmSerializerCb::checkInt);
+#pragma GCC diagnostic pop
+ return (NULL);
+}
+
+ACTION(ActionDispatchData){
+arg1="DispatchData";
+}
+
+TEST(CAmSerializerTest, serializerTest)
+{
+ pthread_t serThread;
+
+ MockIAmSerializerCb serCb;
+ CAmSocketHandler myHandler;
+ std::string testStr("testStr");
+ CAmSerializer serializer(&myHandler);
+ sh_timerHandle_t handle;
+ timespec timeout4;
+ timeout4.tv_nsec = 0;
+ timeout4.tv_sec = 3;
+ CAmTimerSockethandlerController testCallback4(&myHandler, timeout4);
+ myHandler.addTimer(timeout4, &testCallback4.pTimerCallback, handle, NULL);
+ EXPECT_CALL(testCallback4,timerCallback(handle,NULL)).Times(1);
+
+ SerializerData serializerData;
+ serializerData.result = 0;
+ serializerData.testStr = testStr;
+ serializerData.pSerCb = &serCb;
+ serializerData.pSocketHandler = &myHandler;
+ serializerData.pSerializer = &serializer;
+ pthread_create(&serThread, NULL, ptSerializer, &serializerData);
+
+ EXPECT_CALL(serCb,check()).Times(3);
+ EXPECT_CALL(serCb,checkInt()).Times(2).WillRepeatedly(Return(100));
+
+ EXPECT_CALL(serCb,dispatchData(10,testStr)).WillOnce(DoAll(ActionDispatchData(), Return(true)));
+ for (int i = 0; i < 5; i++)
+ EXPECT_CALL(serCb,dispatchData(i,testStr)).WillOnce(DoAll(ActionDispatchData(), Return(true)));
+ myHandler.start_listenting();
+
+ pthread_join(serThread, NULL);
+ ASSERT_TRUE(serializerData.testStr == "DispatchData");
+ ASSERT_TRUE(serializerData.result == 100);
+}
+
+int main(int argc, char **argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
diff --git a/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.h b/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.h
new file mode 100644
index 0000000..8ae3737
--- /dev/null
+++ b/AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.h
@@ -0,0 +1,99 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2012, BMW AG
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+ *
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#ifndef SERIALIZERTEST_H_
+#define SERIALIZERTEST_H_
+
+#define WITH_DLT
+
+#include <ctime>
+#include <chrono>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include <queue>
+#include "CAmSocketHandler.h"
+
+namespace am
+{
+
+ class IAmSerializerCb
+ {
+ public:
+ virtual ~IAmSerializerCb()
+ {
+ }
+ virtual bool dispatchData(const uint32_t handle, std::string & outString)=0;
+ virtual void check()=0;
+ virtual int checkInt()=0;
+ };
+
+ class IAmTimerCb
+ {
+ public:
+ virtual ~IAmTimerCb()
+ {
+ }
+ virtual void timerCallback(sh_timerHandle_t handle, void * userData)=0;
+ };
+
+ class MockIAmTimerCb: public IAmTimerCb
+ {
+ public:
+ MOCK_CONST_METHOD2(timerCallback,
+ void(sh_timerHandle_t handle, void *userData));
+ };
+
+ class CAmTimerSockethandlerController: public MockIAmTimerCb
+ {
+ CAmSocketHandler *mpSocketHandler;
+ timespec mUpdateTimeout;
+ public:
+ explicit CAmTimerSockethandlerController(CAmSocketHandler *SocketHandler, const timespec &timeout);
+ virtual ~CAmTimerSockethandlerController();
+
+ void timerCallback(sh_timerHandle_t handle, void * userData);
+
+ TAmShTimerCallBack<CAmTimerSockethandlerController> pTimerCallback;
+ };
+
+ class MockIAmSerializerCb: public IAmSerializerCb
+ {
+ public:
+ MOCK_METHOD2(dispatchData,
+ bool(const uint32_t handle, std::string & outString));
+ MOCK_METHOD0(check,
+ void());
+ MOCK_METHOD0(checkInt,
+ int());
+ };
+
+ class CAmSerializerTest: public ::testing::Test
+ {
+ public:
+ CAmSerializerTest();
+ ~CAmSerializerTest();
+ void SetUp();
+ void TearDown();
+ };
+
+} /* namespace am */
+#endif /* SOCKETHANDLERTEST_H_ */
diff --git a/AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt b/AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt
new file mode 100644
index 0000000..3e89267
--- /dev/null
+++ b/AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2012, BMW AG
+#
+# This file is part of GENIVI Project AudioManager.
+#
+# Contributions are licensed to the GENIVI Alliance under one or more
+# Contribution License Agreements.
+#
+# copyright
+# This Source Code Form is subject to the terms of the
+# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+# this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# author Christian Linke, christian.linke@bmw.de BMW 2011,2012
+#
+# For further information see http://www.genivi.org/.
+#
+
+cmake_minimum_required(VERSION 3.0)
+
+project(AmSerializerTest LANGUAGES CXX VERSION ${DAEMONVERSION})
+
+INCLUDE_DIRECTORIES(
+ ${AUDIOMANAGER_UTILITIES_INCLUDE}
+ ${GMOCK_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS})
+
+file(GLOB Socket_SRCS_CXX
+ "*.cpp"
+)
+
+ADD_EXECUTABLE(AmSerializerTest ${Socket_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(AmSerializerTest
+ ${GTEST_LIBRARIES}
+ ${GMOCK_LIBRARIES}
+ AudioManagerUtilities
+)
+
+ADD_DEPENDENCIES(AmSerializerTest AudioManagerUtilities)
+
+INSTALL(TARGETS AmSerializerTest
+ DESTINATION ${TEST_EXECUTABLE_INSTALL_PATH}
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ COMPONENT tests
+)
+
+
diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp
index 6f4f184..d443c89 100644
--- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp
+++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp
@@ -120,7 +120,7 @@ void am::CAmTimerMeasurment::timerCallback(sh_timerHandle_t handle, void* userDa
{
MockIAmTimerCb::timerCallback(handle, userData);
- std::chrono::time_point < std::chrono::high_resolution_clock > t_end = std::chrono::high_resolution_clock::now();
+ std::chrono::time_point<std::chrono::high_resolution_clock> t_end = std::chrono::high_resolution_clock::now();
if (TP_ZERO != mLastInvocationTime)
{
auto durationLast = t_end - mLastInvocationTime;
@@ -133,8 +133,10 @@ void am::CAmTimerMeasurment::timerCallback(sh_timerHandle_t handle, void* userDa
", diff:" << diff << "ms ] " <<
std::endl;
#endif
- EXPECT_LT(diff, TIMERS_CB_TOLERANCE) << mDebugText << " [ expected:" << std::chrono::duration<double, std::milli>(mExpected).count() << "ms, current:" << std::chrono::duration<double, std::milli>(durationLast).count() << "ms ]";
- EXPECT_GT(diff, -TIMERS_CB_TOLERANCE) << mDebugText << " [ expected:" << std::chrono::duration<double, std::milli>(mExpected).count() << "ms, current:" << std::chrono::duration<double, std::milli>(durationLast).count() << "ms ]";
+ if (diff > TIMERS_CB_TOLERANCE)
+ std::cout << mDebugText << " Warning [ expected:" << std::chrono::duration<double, std::milli>(mExpected).count() << "ms, current:" << std::chrono::duration<double, std::milli>(durationLast).count() << "ms ]" << std::endl;
+ if (diff < -TIMERS_CB_TOLERANCE)
+ std::cout << mDebugText << " Warning [ expected:" << std::chrono::duration<double, std::milli>(mExpected).count() << "ms, current:" << std::chrono::duration<double, std::milli>(durationLast).count() << "ms ]" << std::endl;
mLastInvocationTime = t_end;
if (--mRepeats > 0)
diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h
index b7d2a09..63f79cf 100644
--- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h
+++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h
@@ -34,122 +34,128 @@
#undef ENABLED_SOCKETHANDLER_TEST_OUTPUT
#undef ENABLED_TIMERS_TEST_OUTPUT
-#define TIMERS_CB_TOLERANCE 10.f
+#define TIMERS_CB_TOLERANCE 8.f
namespace am
{
- class IAmTimerCb
- {
- public:
- virtual void timerCallback(sh_timerHandle_t handle, void * userData)=0;
- };
-
- class IAmSocketHandlerCb
- {
- public:
- virtual void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)=0;
- virtual bool dispatchData(const sh_pollHandle_t handle, void* userData)=0;
- virtual bool check(const sh_pollHandle_t handle, void* userData)=0;
- };
-
- class MockIAmTimerCb : public IAmTimerCb
- {
- public:
+ class IAmTimerCb
+ {
+ public:
+ virtual ~IAmTimerCb()
+ {
+ }
+ virtual void timerCallback(sh_timerHandle_t handle, void * userData)=0;
+ };
+
+ class IAmSocketHandlerCb
+ {
+ public:
+ virtual ~IAmSocketHandlerCb()
+ {
+ }
+ virtual void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)=0;
+ virtual bool dispatchData(const sh_pollHandle_t handle, void* userData)=0;
+ virtual bool check(const sh_pollHandle_t handle, void* userData)=0;
+ };
+
+ class MockIAmTimerCb: public IAmTimerCb
+ {
+ public:
MOCK_CONST_METHOD2(timerCallback,
- void(sh_timerHandle_t handle, void *userData));
- };
-
- class MockSocketHandlerCb : public IAmSocketHandlerCb
- {
- public:
+ void(sh_timerHandle_t handle, void *userData));
+ };
+
+ class MockSocketHandlerCb: public IAmSocketHandlerCb
+ {
+ public:
MOCK_CONST_METHOD3(receiveData,
- void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData));
+ void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData));
MOCK_CONST_METHOD2(dispatchData,
- void(const sh_pollHandle_t handle, void* userData));
+ void(const sh_pollHandle_t handle, void* userData));
MOCK_CONST_METHOD2(check,
- void(const sh_pollHandle_t handle, void* userData));
+ void(const sh_pollHandle_t handle, void* userData));
};
-
-class CAmSamplePlugin : public MockSocketHandlerCb
-{
-public:
- enum sockType_e
+
+ class CAmSamplePlugin: public MockSocketHandlerCb
{
- UNIX, INET
+ public:
+ enum sockType_e
+ {
+ UNIX, INET
+ };
+ CAmSamplePlugin(CAmSocketHandler *mySocketHandler, sockType_e socketType);
+ ~CAmSamplePlugin()
+ {
+ }
+ ;
+ void connectSocket(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
+ void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
+ bool dispatchData(const sh_pollHandle_t handle, void* userData);
+ bool check(const sh_pollHandle_t handle, void* userData);
+ TAmShPollFired<CAmSamplePlugin> connectFiredCB;
+ TAmShPollFired<CAmSamplePlugin> receiveFiredCB;
+ TAmShPollDispatch<CAmSamplePlugin> sampleDispatchCB;
+ TAmShPollCheck<CAmSamplePlugin> sampleCheckCB;
+
+ private:
+ CAmSocketHandler *mSocketHandler;
+ sh_pollHandle_t mConnecthandle, mReceiveHandle;
+ std::queue<std::string> msgList;
};
- CAmSamplePlugin(CAmSocketHandler *mySocketHandler, sockType_e socketType);
- ~CAmSamplePlugin()
+
+ class CAmTimerSockethandlerController: public MockIAmTimerCb
{
- }
- ;
- void connectSocket(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
- void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
- bool dispatchData(const sh_pollHandle_t handle, void* userData);
- bool check(const sh_pollHandle_t handle, void* userData);
- TAmShPollFired<CAmSamplePlugin> connectFiredCB;
- TAmShPollFired<CAmSamplePlugin> receiveFiredCB;
- TAmShPollDispatch<CAmSamplePlugin> sampleDispatchCB;
- TAmShPollCheck<CAmSamplePlugin> sampleCheckCB;
-
-private:
- CAmSocketHandler *mSocketHandler;
- sh_pollHandle_t mConnecthandle, mReceiveHandle;
- std::queue<std::string> msgList;
-};
-
-class CAmTimerSockethandlerController: public MockIAmTimerCb
-{
- CAmSocketHandler *mpSocketHandler;
- timespec mUpdateTimeout;
-public:
- explicit CAmTimerSockethandlerController(CAmSocketHandler *SocketHandler, const timespec &timeout);
- virtual ~CAmTimerSockethandlerController();
-
- void timerCallback(sh_timerHandle_t handle, void * userData);
-
- TAmShTimerCallBack<CAmTimerSockethandlerController> pTimerCallback;
-};
-
-class CAmTimer: public MockIAmTimerCb
-{
- CAmSocketHandler *mpSocketHandler;
- timespec mUpdateTimeout;
- int32_t mRepeats;
-public:
- explicit CAmTimer(CAmSocketHandler *SocketHandler, const timespec &timeout, const int32_t repeats = 0u);
- virtual ~CAmTimer();
-
- void timerCallback(sh_timerHandle_t handle, void * userData);
-
- TAmShTimerCallBack<CAmTimer> pTimerCallback;
-};
-
-class CAmTimerMeasurment: public MockIAmTimerCb
-{
- CAmSocketHandler *mSocketHandler;
- timespec mUpdateTimeout;
- std::chrono::time_point<std::chrono::high_resolution_clock> mUpdateTimePoint;
- std::chrono::time_point<std::chrono::high_resolution_clock> mLastInvocationTime;
- std::chrono::duration<long, std::ratio<1l, 1000000000l>> mExpected;
- int32_t mRepeats;
- void * mpUserData;
- std::string mDebugText;
-public:
- explicit CAmTimerMeasurment(CAmSocketHandler *SocketHandler, const timespec &timeout, const std::string & label, const int32_t repeats = 0u, void * userData = NULL);
- virtual ~CAmTimerMeasurment();
-
- void timerCallback(sh_timerHandle_t handle, void * userData);
- TAmShTimerCallBack<CAmTimerMeasurment> pTimerCallback;
-};
-
-class CAmSocketHandlerTest: public ::testing::Test
-{
-public:
- CAmSocketHandlerTest();
- ~CAmSocketHandlerTest();
- void SetUp();
- void TearDown();
-};
+ CAmSocketHandler *mpSocketHandler;
+ timespec mUpdateTimeout;
+ public:
+ explicit CAmTimerSockethandlerController(CAmSocketHandler *SocketHandler, const timespec &timeout);
+ virtual ~CAmTimerSockethandlerController();
+
+ void timerCallback(sh_timerHandle_t handle, void * userData);
+
+ TAmShTimerCallBack<CAmTimerSockethandlerController> pTimerCallback;
+ };
+
+ class CAmTimer: public MockIAmTimerCb
+ {
+ CAmSocketHandler *mpSocketHandler;
+ timespec mUpdateTimeout;
+ int32_t mRepeats;
+ public:
+ explicit CAmTimer(CAmSocketHandler *SocketHandler, const timespec &timeout, const int32_t repeats = 0u);
+ virtual ~CAmTimer();
+
+ void timerCallback(sh_timerHandle_t handle, void * userData);
+
+ TAmShTimerCallBack<CAmTimer> pTimerCallback;
+ };
+
+ class CAmTimerMeasurment: public MockIAmTimerCb
+ {
+ CAmSocketHandler *mSocketHandler;
+ timespec mUpdateTimeout;
+ std::chrono::time_point<std::chrono::high_resolution_clock> mUpdateTimePoint;
+ std::chrono::time_point<std::chrono::high_resolution_clock> mLastInvocationTime;
+ std::chrono::duration<long, std::ratio<1l, 1000000000l>> mExpected;
+ int32_t mRepeats;
+ void * mpUserData;
+ std::string mDebugText;
+ public:
+ explicit CAmTimerMeasurment(CAmSocketHandler *SocketHandler, const timespec &timeout, const std::string & label, const int32_t repeats = 0u, void * userData = NULL);
+ virtual ~CAmTimerMeasurment();
+
+ void timerCallback(sh_timerHandle_t handle, void * userData);
+ TAmShTimerCallBack<CAmTimerMeasurment> pTimerCallback;
+ };
+
+ class CAmSocketHandlerTest: public ::testing::Test
+ {
+ public:
+ CAmSocketHandlerTest();
+ ~CAmSocketHandlerTest();
+ void SetUp();
+ void TearDown();
+ };
} /* namespace am */
#endif /* SOCKETHANDLERTEST_H_ */
diff --git a/AudioManagerUtilities/test/CMakeLists.txt b/AudioManagerUtilities/test/CMakeLists.txt
index fb55831..414e199 100644
--- a/AudioManagerUtilities/test/CMakeLists.txt
+++ b/AudioManagerUtilities/test/CMakeLists.txt
@@ -1,4 +1,2 @@
add_subdirectory (AmSocketHandlerTest)
-
-
-
+add_subdirectory (AmSerializerTest)