From da78ca5c2eb7e2ff2f9153361774156f8a454daa Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Tue, 14 Mar 2017 14:55:31 +0100 Subject: CAmSerializer interface extended to support std::function. Signed-off-by: Christian Linke Change-Id: I8b4c2c436ac9fbc37c76a21145c731f327cab0e4 --- AudioManagerCore/src/CAmCommandSender.cpp | 44 +- AudioManagerUtilities/include/CAmSerializer.h | 1351 ++++++++------------ AudioManagerUtilities/include/CAmSocketHandler.h | 7 +- AudioManagerUtilities/src/CAmSocketHandler.cpp | 118 +- .../test/AmSerializerTest/CAmSerializerTest.cpp | 158 +++ .../test/AmSerializerTest/CAmSerializerTest.h | 99 ++ .../test/AmSerializerTest/CMakeLists.txt | 47 + .../AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 8 +- .../AmSocketHandlerTest/CAmSocketHandlerTest.h | 216 ++-- AudioManagerUtilities/test/CMakeLists.txt | 4 +- 10 files changed, 1053 insertions(+), 999 deletions(-) create mode 100644 AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.cpp create mode 100644 AudioManagerUtilities/test/AmSerializerTest/CAmSerializerTest.h create mode 100644 AudioManagerUtilities/test/AmSerializerTest/CMakeLists.txt 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& listOfPluginD } dboNewMainConnection = [&](const am_MainConnectionType_s& mainConnection) { - mSerializer.asyncCall(this, &CAmCommandSender::cbNewMainConnection, mainConnection); + mSerializer.asyncCall(this, &CAmCommandSender::cbNewMainConnection, mainConnection); }; dboRemovedMainConnection = [&](const am_mainConnectionID_t mainConnection) { - mSerializer.asyncCall(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& listOfPluginD s.sinkClassID = sink.sinkClassID; s.sinkID = sink.sinkID; s.volume = sink.mainVolume; - mSerializer.asyncCall(this, &CAmCommandSender::cbNewSink, s); + typedef void(CAmCommandSender::*TMeth)(am::am_SinkType_s) ; + mSerializer.asyncCall(this, &CAmCommandSender::cbNewSink, s); } }; dboNewSource = [&](const am_Source_s& source) { @@ -189,64 +190,65 @@ CAmCommandSender::CAmCommandSender(const std::vector& listOfPluginD s.name = source.name; s.sourceClassID = source.sourceClassID; s.sourceID = source.sourceID; - mSerializer.asyncCall(this, &CAmCommandSender::cbNewSource, s); + typedef void(CAmCommandSender::*TMeth)(am::am_SourceType_s) ; + mSerializer.asyncCall(this, &CAmCommandSender::cbNewSource, s); } }; dboRemovedSink = [&](const am_sinkID_t sinkID, const bool visible) { if (visible) - mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSink, sinkID); + mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSink, sinkID); }; dboRemovedSource = [&](const am_sourceID_t sourceID, const bool visible) { if (visible) - mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSource, sourceID); + mSerializer.asyncCall(this, &CAmCommandSender::cbRemovedSource, sourceID); }; dboNumberOfSinkClassesChanged = [&]() { - mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSinkClassesChanged); + mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSinkClassesChanged); }; dboNumberOfSourceClassesChanged = [&]() { - mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSourceClassesChanged); + mSerializer.asyncCall(this, &CAmCommandSender::cbNumberOfSourceClassesChanged); }; dboMainConnectionStateChanged = [&](const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState) { - mSerializer.asyncCall(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(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(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(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(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(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(this, &CAmCommandSender::cbSinkMuteStateChanged, sinkID, muteState); + mSerializer.asyncCall(this, &CAmCommandSender::cbSinkMuteStateChanged, sinkID, muteState); }; dboSystemPropertyChanged = [&](const am_SystemProperty_s& SystemProperty) { - mSerializer.asyncCall(this, &CAmCommandSender::cbSystemPropertyChanged, SystemProperty); + mSerializer.asyncCall(this, &CAmCommandSender::cbSystemPropertyChanged, SystemProperty); }; dboTimingInformationChanged = [&](const am_mainConnectionID_t mainConnection, const am_timeSync_t time) { - mSerializer.asyncCall(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& listMainSoundProperties, const bool visible) { if (visible) - mSerializer.asyncCall >(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& listMainSoundProperties, const bool visible) { if (visible) - mSerializer.asyncCall >(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 (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(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 -#include -#include -#include -#include -#include -#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 CAmDelegateAsyncImpl : public CAmDelegate - { - Class mInstance; - Method mMethod; - Tuple mArguments; - public: - friend class CAmSerializer; - static void call(Class instance, Method method, Tuple && arguments) - { - CAmDelegateAsyncImpl::call(instance, method, std::forward(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(mArguments)); - return (AsyncCallType); - }; - }; - - /** - * Prototype for a delegate with variadic template arguments. - */ - template - class CAmDelegateAsyncImpl : 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(std::forward(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(mArguments)); - return (AsyncCallType); - }; - }; - - /** - * Prototype for a delegate with variadic template arguments in conjunction with the following class. - */ - template - 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::call(instance, method, result, std::forward(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(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 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 && t) - { - result = (*instance.*method)(std::get(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(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 - void doAsyncCall(Class intsance, Method method, Tuple & arguments) - { - typedef typename std::decay::type ttype; - typedef CAmDelegateAsyncImpl::value, std::tuple_size::value> AsyncDelegate; - AsyncDelegate *pImp = new AsyncDelegate(intsance, method, std::forward(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 - void doSyncCall(Class intsance, Method method, Return & result, Tuple & arguments) - { - typedef typename std::decay::type ttype; - typedef CAmDelegateSyncImpl::value, std::tuple_size::value> SyncDelegate; - SyncDelegate *pImp = new SyncDelegate(intsance, method, std::forward(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 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(&anInstance,&MyGreatClass::AGreatMethod, result, 100); - * @endcode - */ - template - 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(&anInstance,&MyGreatClass::AGreatMethod, 100); - * @endcode - */ - template - 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(&instanceMyClass,&myClass::myfunction); - * @endcode - */ - template - 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(&instanceMyClass,&myClass::myfunction,k); - * @endcode - * - */ - template - 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(&instanceMyClass,&myClass::myfunction,k); - * @endcode - * - */ - template - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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(&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 - 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(&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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 receiverCallbackT; - TAmShPollDispatch dispatcherCallbackT; - TAmShPollCheck 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 +#include +#include +#include +#include +#include +#include "CAmDltWrapper.h" +#include "CAmSocketHandler.h" + +/*! + * \brief Helper structures used within std::bind for automatically identification of all placeholders. + */ +template +struct indices +{ +}; + +template +struct build_indices: build_indices +{ +}; + +template +struct build_indices<0, Is...> : indices +{ +}; + +template struct placeholder +{ +}; + +namespace std +{ + template + struct is_placeholder<::placeholder> : std::integral_constant + { + }; +} + +/** + * 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 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 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 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 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 + void asyncInvocation(TFunc invocation) + { + static_assert(std::is_bind_expression::value,"The type is not produced by std::bind"); + typedef CAmDelegateAsyncImpl AsyncDelegate; + AsyncDelegate *pImp = new AsyncDelegate(std::forward(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 + void asyncCall(TClass* instance, TMeth method, TArgs && ... arguments) + { + auto invocation = std::bind(method, instance, std::forward(arguments)...); + asyncInvocation(invocation); + } + + template + void asyncCall(TClass* instance, TMeth method, TArgs && ... arguments) + { + auto invocation = std::bind(method, instance, std::forward(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 + void syncInvocation(TFunc invocation, TRet && result) + { + static_assert(std::is_bind_expression::value,"The type is not produced by std::bind"); + + typedef CAmDelegateSyncImpl SyncDelegate; + + SyncDelegate *pImp = new SyncDelegate(std::forward(invocation), std::forward(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 + void syncInvocation(TFunc invocation) + { + static_assert(std::is_bind_expression::value,"The type is not produced by std::bind"); + + typedef CAmDelegateSyncVoidImpl SyncDelegate; + + SyncDelegate *pImp = new SyncDelegate(std::forward(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 + void syncCall(TClass* instance, TMeth method, TRet & result, TArgs && ... arguments) + { + auto invocation = std::bind(method, instance, std::ref(arguments)...); + syncInvocation(invocation, result); + } + + template + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 receiverCallbackT; + TAmShPollDispatch dispatcherCallbackT; + TAmShPollCheck 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 #include "audiomanagertypes.h" - #ifdef WITH_TIMERFD #include @@ -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; //! mSetPollKeys; //!A set of all used ppoll keys VectorListPoll_t mListPoll; //! 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include +#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 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 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(mExpected).count() << "ms, current:" << std::chrono::duration(durationLast).count() << "ms ]"; - EXPECT_GT(diff, -TIMERS_CB_TOLERANCE) << mDebugText << " [ expected:" << std::chrono::duration(mExpected).count() << "ms, current:" << std::chrono::duration(durationLast).count() << "ms ]"; + if (diff > TIMERS_CB_TOLERANCE) + std::cout << mDebugText << " Warning [ expected:" << std::chrono::duration(mExpected).count() << "ms, current:" << std::chrono::duration(durationLast).count() << "ms ]" << std::endl; + if (diff < -TIMERS_CB_TOLERANCE) + std::cout << mDebugText << " Warning [ expected:" << std::chrono::duration(mExpected).count() << "ms, current:" << std::chrono::duration(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 connectFiredCB; + TAmShPollFired receiveFiredCB; + TAmShPollDispatch sampleDispatchCB; + TAmShPollCheck sampleCheckCB; + + private: + CAmSocketHandler *mSocketHandler; + sh_pollHandle_t mConnecthandle, mReceiveHandle; + std::queue 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 connectFiredCB; - TAmShPollFired receiveFiredCB; - TAmShPollDispatch sampleDispatchCB; - TAmShPollCheck sampleCheckCB; - -private: - CAmSocketHandler *mSocketHandler; - sh_pollHandle_t mConnecthandle, mReceiveHandle; - std::queue 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 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 pTimerCallback; -}; - -class CAmTimerMeasurment: public MockIAmTimerCb -{ - CAmSocketHandler *mSocketHandler; - timespec mUpdateTimeout; - std::chrono::time_point mUpdateTimePoint; - std::chrono::time_point mLastInvocationTime; - std::chrono::duration> 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 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 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 pTimerCallback; + }; + + class CAmTimerMeasurment: public MockIAmTimerCb + { + CAmSocketHandler *mSocketHandler; + timespec mUpdateTimeout; + std::chrono::time_point mUpdateTimePoint; + std::chrono::time_point mLastInvocationTime; + std::chrono::duration> 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 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) -- cgit v1.2.1