/** * SPDX license identifier: MPL-2.0 * * Copyright (C) 2012, BMW AG * * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012 * * \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: virtual ~CAmDelegate() {}; virtual bool call(int* pipe)=0; }; typedef CAmDelegate* CAmDelegagePtr; //!< pointer to a delegate /** * delegate template for no argument */ template class CAmNoArgDelegate: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(); public: CAmNoArgDelegate(TClass* instance, void (TClass::*function)()) : mInstance(instance), // mFunction(function) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(); return (true); }; }; /** * delegate template for one argument */ template class CAmOneArgDelegate: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ); Targ mArgument; public: CAmOneArgDelegate(TClass* instance, void (TClass::*function)(Targ), Targ argument) : mInstance(instance), // mFunction(function), // mArgument(argument) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument); return (true); }; }; /** * delegate template for one argument */ template class CAmOneArgDelegateRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ&); Targ mArgument; public: CAmOneArgDelegateRef(TClass* instance, void (TClass::*function)(Targ&), Targ& argument) : mInstance(instance), // mFunction(function), // mArgument(argument) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument); return (true); }; }; /** * delegate template for two arguments */ template class CAmTwoArgDelegate: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ argument, Targ1 argument1); Targ mArgument; Targ1 mArgument1; public: CAmTwoArgDelegate(TClass* instance, void (TClass::*function)(Targ argument, Targ1 argument1), Targ argument, Targ1 argument1) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1) { }; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1); return (true); }; }; /** * delegate template for two arguments */ template class CAmTwoArgDelegateFirstRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ& argument, Targ1 argument1); Targ mArgument; Targ1 mArgument1; public: CAmTwoArgDelegateFirstRef(TClass* instance, void (TClass::*function)(Targ& argument, Targ1 argument1), Targ& argument, Targ1 argument1) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1) { }; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1); return (true); }; }; template class CAmTwoArgDelegateSecondRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ argument, Targ1& argument1); Targ mArgument; Targ1 mArgument1; public: CAmTwoArgDelegateSecondRef(TClass* instance, void (TClass::*function)(Targ argument, Targ1& argument1), Targ argument, Targ1& argument1) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1); return (true); }; }; /** * delegate template for two arguments */ template class CAmTwoArgDelegateAllRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ& argument, Targ1& argument1); Targ mArgument; Targ1 mArgument1; public: CAmTwoArgDelegateAllRef(TClass* instance, void (TClass::*function)(Targ& argument, Targ1& argument1), Targ& argument, Targ1& argument1) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1) { }; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1); return (true); }; }; /** * delegate template for three arguments */ template class CAmThreeArgDelegate: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ argument, Targ1 argument1, Targ2 argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; public: CAmThreeArgDelegate(TClass* instance, void (TClass::*function)(Targ argument, Targ1 argument1, Targ2 argument2), Targ argument, Targ1 argument1, Targ2 argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2) { } ; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); return (true); } ; }; /** * delegate template for three arguments */ template class CAmThreeArgDelegateFirstRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ& argument, Targ1 argument1, Targ2 argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; public: CAmThreeArgDelegateFirstRef(TClass* instance, void (TClass::*function)(Targ& argument, Targ1 argument1, Targ2 argument2), Targ& argument, Targ1 argument1, Targ2 argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); return (true); }; }; /** * delegate template for three arguments */ template class CAmThreeArgDelegateSecondRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ argument, Targ1& argument1, Targ2 argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; public: CAmThreeArgDelegateSecondRef(TClass* instance, void (TClass::*function)(Targ argument, Targ1& argument1, Targ2 argument2), Targ argument, Targ1& argument1, Targ2 argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); return (true); }; }; /** * delegate template for three arguments */ template class CAmThreeArgDelegateThirdRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ argument, Targ1 argument1, Targ2& argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; public: CAmThreeArgDelegateThirdRef(TClass* instance, void (TClass::*function)(Targ argument, Targ1 argument1, Targ2& argument2), Targ argument, Targ1 argument1, Targ2& argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); return (true); }; }; /** * delegate template for three arguments */ template class CAmThreeArgDelegateFirstSecondRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ& argument, Targ1& argument1, Targ2 argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; public: CAmThreeArgDelegateFirstSecondRef(TClass* instance, void (TClass::*function)(Targ& argument, Targ1& argument1, Targ2 argument2), Targ& argument, Targ1& argument1, Targ2 argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); return (true); }; }; /** * delegate template for three arguments */ template class CAmThreeArgDelegateFirstThirdRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ& argument, Targ1 argument1, Targ2& argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; public: CAmThreeArgDelegateFirstThirdRef(TClass* instance, void (TClass::*function)(Targ& argument, Targ1 argument1, Targ2& argument2), Targ& argument, Targ1 argument1, Targ2& argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); return (true); }; }; /** * delegate template for three arguments */ template class CAmThreeArgDelegateSecondThirdRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ argument, Targ1& argument1, Targ2& argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; public: CAmThreeArgDelegateSecondThirdRef(TClass* instance, void (TClass::*function)(Targ argument, Targ1& argument1, Targ2& argument2), Targ argument, Targ1& argument1, Targ2& argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); return (true); }; }; /** * delegate template for three arguments */ template class CAmThreeArgDelegateAllRef: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ& argument, Targ1& argument1, Targ2& argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; public: CAmThreeArgDelegateAllRef(TClass* instance, void (TClass::*function)(Targ& argument, Targ1& argument1, Targ2& argument2), Targ& argument, Targ1& argument1, Targ2& argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2) {}; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); return (true); }; }; /** * delegate template for four arguments */ template class CAmFourArgDelegate: public CAmDelegate { private: TClass* mInstance; void (TClass::*mFunction)(Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; Targ3 mArgument3; public: CAmFourArgDelegate(TClass* instance, void (TClass::*function)(Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3), Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2), // mArgument3(argument3) { } ; bool call(int* pipe) { (void) pipe; (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2, mArgument3); return (true); } ; }; /** * Template for synchronous calls with no argument */ template class CAmSyncNoArgDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(); TretVal mRetval; public: friend class CAmSerializer; CAmSyncNoArgDelegate(TClass* instance, TretVal (TClass::*function)()) : mInstance(instance), // mFunction(function), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults() { return (mRetval); } }; /** * template for synchronous calls with one argument */ template class CAmSyncOneArgDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCall argument); Targ mArgument; TretVal mRetval; public: friend class CAmSerializer; CAmSyncOneArgDelegate(TClass* instance, TretVal (TClass::*function)(TargCall argument), Targ argument) : mInstance(instance), // mFunction(function), // mArgument(argument), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument) { argument = mArgument; return (mRetval); } }; /** * template for synchronous calls with one argument on a const function */ template class CAmSyncOneArgConstDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCall argument) const; Targ mArgument; TretVal mRetval; public: friend class CAmSerializer; CAmSyncOneArgConstDelegate(TClass* instance, TretVal (TClass::*function)(TargCall argument) const, Targ argument) : mInstance(instance), // mFunction(function), // mArgument(argument), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument) { argument = mArgument; return (mRetval); } }; /** * template for synchronous calls with two arguments */ template class CAmSyncTwoArgDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCall, TargCall1); Targ mArgument; Targ1 mArgument1; TretVal mRetval; public: friend class CAmSerializer; CAmSyncTwoArgDelegate(TClass* instance, TretVal (TClass::*function)(TargCall, TargCall1), Targ& argument, Targ1& argument1) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument, mArgument1); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument, Targ1& argument1) { argument = mArgument; argument1 = mArgument1; return (mRetval); } }; /** * template for synchronous calls with two arguments on a const function */ template class CAmSyncTwoArgConstDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCall, TargCall1) const; Targ mArgument; Targ1 mArgument1; TretVal mRetval; public: friend class CAmSerializer; CAmSyncTwoArgConstDelegate(TClass* instance, TretVal (TClass::*function)(TargCall, TargCall1) const, Targ& argument, Targ1& argument1) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument, mArgument1); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument, Targ1& argument1) { argument = mArgument; argument1 = mArgument1; return (mRetval); } }; /** * template for synchronous calls with three arguments */ template class CAmSyncThreeArgDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCall argument, TargCall1 argument1, TargCall2 argument2); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; TretVal mRetval; public: CAmSyncThreeArgDelegate(TClass* instance, TretVal (TClass::*function)(TargCall argument, TargCall1 argument1, TargCall2 argument2), Targ argument, Targ1 argument1, Targ2 argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument, Targ1& argument1, Targ2& argument2) { argument = mArgument; argument1 = mArgument1; argument2 = mArgument2; return (mRetval); } }; /** * template for synchronous const calls with three arguments */ template class CAmSyncThreeArgConstDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCall argument, TargCall1 argument1, TargCall2 argument2) const; Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; TretVal mRetval; public: CAmSyncThreeArgConstDelegate(TClass* instance, TretVal (TClass::*function)(TargCall argument, TargCall1 argument1, TargCall2 argument2) const, Targ argument, Targ1 argument1, Targ2 argument2) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument, Targ1& argument1, Targ2& argument2) { argument = mArgument; argument1 = mArgument1; argument2 = mArgument2; return (mRetval); } }; /** * template for synchronous calls with four arguments */ template class CAmSyncFourArgDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCAll argument, TargCall1 argument1, TargCall2 argument2, TargCall3 argument3); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; Targ3 mArgument3; TretVal mRetval; public: CAmSyncFourArgDelegate(TClass* instance, TretVal (TClass::*function)(TargCAll argument, TargCall1 argument1, TargCall2 argument2, TargCall3 argument3), Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2), // mArgument3(argument3), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2, mArgument3); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3) { argument = mArgument; argument1 = mArgument1; argument2 = mArgument2; argument3 = mArgument3; return (mRetval); } }; /** * delegate template for five arguments */ template class CAmSyncFiveArgDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCAll argument, TargCall1 argument1, TargCall2 argument2, TargCall3 argument3, TargCall4); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; Targ3 mArgument3; Targ4 mArgument4; TretVal mRetval; public: CAmSyncFiveArgDelegate(TClass* instance, TretVal (TClass::*function)(TargCAll argument, TargCall1 argument1, TargCall2 argument2, TargCall3 argument3, TargCall4 argument4), Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3, Targ4 argument4) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2), // mArgument3(argument3), // mArgument4(argument4), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2, mArgument3, mArgument4); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3, Targ4& argument4) { argument = mArgument; argument1 = mArgument1; argument2 = mArgument2; argument3 = mArgument3; argument4 = mArgument4; return (mRetval); } }; /** * template for synchronous calls with six arguments */ template class CAmSyncSixArgDelegate: public CAmDelegate { private: TClass* mInstance; TretVal (TClass::*mFunction)(TargCAll argument, TargCall1 argument1, TargCall2 argument2, TargCall3 argument3, TargCall4, TargCall5); Targ mArgument; Targ1 mArgument1; Targ2 mArgument2; Targ3 mArgument3; Targ4 mArgument4; Targ5 mArgument5; TretVal mRetval; CAmSyncSixArgDelegate(TClass* instance, TretVal (TClass::*function)(TargCAll, TargCall1, TargCall2, TargCall3, TargCall4, TargCall5), Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3, Targ4 argument4, Targ5 argument5) : mInstance(instance), // mFunction(function), // mArgument(argument), // mArgument1(argument1), // mArgument2(argument2), // mArgument3(argument3), // mArgument4(argument4), // mArgument5(argument5), // mRetval() { } ; bool call(int* pipe) { mRetval = (*mInstance.*mFunction)(mArgument, mArgument1, mArgument2, mArgument3, mArgument4, mArgument5); write(pipe[1], this, sizeof(this)); return (false); } ; TretVal returnResults(Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3, Targ4& argument4, Targ5& argument5) { argument = mArgument; argument1 = mArgument1; argument2 = mArgument2; argument3 = mArgument3; argument4 = mArgument4; argument5 = mArgument5; return (mRetval); } }; /** * 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 std::deque mListDelegatePoiters; //!< intermediate queue to store the pipe results public: /** * 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)()) { CAmDelegagePtr p(new CAmNoArgDelegate(instance, function)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmOneArgDelegate(instance, function, argument)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmOneArgDelegateRef(instance, function, argument)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmTwoArgDelegate(instance, function, argument, argument1)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmTwoArgDelegateFirstRef(instance, function, argument, argument1)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmTwoArgDelegateSecondRef(instance, function, argument, argument1)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmTwoArgDelegateAllRef(instance, function, argument, argument1)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmThreeArgDelegate(instance, function, argument, argument1, argument2)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmThreeArgDelegateFirstRef(instance, function, argument, argument1, argument2)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmThreeArgDelegateSecondRef(instance, function, argument, argument1, argument2)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmThreeArgDelegateThirdRef(instance, function, argument, argument1, argument2)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmThreeArgDelegateSecondThirdRef(instance, function, argument, argument1, argument2)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmThreeArgDelegateAllRef(instance, function, argument, argument1, argument2)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmThreeArgDelegateFirstSecondRef(instance, function, argument, argument1, argument2)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmThreeArgDelegateFirstThirdRef(instance, function, argument, argument1, argument2)); send(p); } /** * 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) { CAmDelegagePtr p(new CAmFourArgDelegate(instance, function, argument, argument1, argument2, argument3)); send(p); } /** * 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) { CAmSyncNoArgDelegate* p(new CAmSyncNoArgDelegate(instance, function)); send(static_cast(p)); int numReads; CAmDelegagePtr ptr; if ((numReads = read(mReturnPipe[0], &ptr, sizeof(ptr))) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } //working with friend class here is not the finest of all programming stiles but it works... retVal = p->returnResults(); delete p; } /** * 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) { CAmSyncOneArgDelegate* p(new CAmSyncOneArgDelegate(instance, function, argument)); send(static_cast(p)); int numReads; CAmDelegagePtr ptr; if ((numReads = read(mReturnPipe[0], &ptr, sizeof(ptr))) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } //working with friend class here is not the finest of all programming stiles but it works... retVal = p->returnResults(argument); delete p; } /** * 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) { CAmSyncOneArgConstDelegate* p(new CAmSyncOneArgConstDelegate(instance, function, argument)); send(static_cast(p)); int numReads; CAmDelegagePtr ptr; if ((numReads = read(mReturnPipe[0], &ptr, sizeof(ptr))) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } //working with friend class here is not the finest of all programming stiles but it works... retVal = p->returnResults(argument); delete p; } /** * 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) { CAmSyncTwoArgDelegate* p(new CAmSyncTwoArgDelegate(instance, function, argument, argument1)); send(dynamic_cast(p)); CAmDelegagePtr ptr; if (read(mReturnPipe[0], &ptr, sizeof(ptr)) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } retVal = p->returnResults(argument, argument1); delete p; } /** * 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) { CAmSyncTwoArgConstDelegate* p(new CAmSyncTwoArgConstDelegate(instance, function, argument, argument1)); send(dynamic_cast(p)); CAmDelegagePtr ptr; if (read(mReturnPipe[0], &ptr, sizeof(ptr)) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } retVal = p->returnResults(argument, argument1); delete p; } /** * 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) { CAmSyncThreeArgDelegate* p(new CAmSyncThreeArgDelegate(instance, function, argument, argument1, argument2)); send(static_cast(p)); int numReads; CAmDelegagePtr ptr; if ((numReads = read(mReturnPipe[0], &ptr, sizeof(ptr))) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } //working with friend class here is not the finest of all programming stiles but it worCAmTwoArgDelegateks... retVal = p->returnResults(argument, argument1, argument2); delete p; } /** * 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) { CAmSyncThreeArgConstDelegate* p(new CAmSyncThreeArgConstDelegate(instance, function, argument, argument1, argument2)); send(static_cast(p)); int numReads; CAmDelegagePtr ptr; if ((numReads = read(mReturnPipe[0], &ptr, sizeof(ptr))) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } //working with friend class here is not the finest of all programming stiles but it worCAmTwoArgDelegateks... retVal = p->returnResults(argument, argument1, argument2); delete p; } /** * 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) { CAmSyncFourArgDelegate* p(new CAmSyncFourArgDelegate(instance, function, argument, argument1, argument2, argument3)); send(static_cast(p)); int numReads; CAmDelegagePtr ptr; if ((numReads = read(mReturnPipe[0], &ptr, sizeof(ptr))) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } //working with friend class here is not the finest of all programming stiles but it works... retVal = p->returnResults(argument, argument1, argument2, argument3); delete p; } /** * 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) { CAmSyncFiveArgDelegate* p(new CAmSyncFiveArgDelegate(instance, function, argument, argument1, argument2, argument3, argument4)); send(static_cast(p)); int numReads; CAmDelegagePtr ptr; if ((numReads = read(mReturnPipe[0], &ptr, sizeof(ptr))) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } //working with friend class here is not the finest of all programming stiles but it works... retVal = p->returnResults(argument, argument1, argument2, argument3, argument4); delete p; } /** * 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) { CAmSyncSixArgDelegate* p(new CAmSyncSixArgDelegate(instance, function, argument, argument1, argument2, argument3, argument4, argument5)); send(static_cast(p)); int numReads; CAmDelegagePtr ptr; if ((numReads = read(mReturnPipe[0], &ptr, sizeof(ptr))) == -1) { logError("CAmSerializer::receiverCallback could not read pipe!"); throw std::runtime_error("CAmSerializer Could not read pipe!"); } //working with friend class here is not the finest of all programming stiles but it works... retVal = p->returnResults(argument, argument1, argument2, argument3, argument4, argument5); delete p; } /** * 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(), // mListDelegatePoiters(), // receiverCallbackT(this, &CAmSerializer::receiverCallback), // dispatcherCallbackT(this, &CAmSerializer::dispatcherCallback), // checkerCallbackT(this, &CAmSerializer::checkerCallback) { 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; sh_pollHandle_t handle; event |= POLLIN; iSocketHandler->addFDPoll(mPipe[0], event, NULL, &receiverCallbackT, &checkerCallbackT, &dispatcherCallbackT, NULL, handle); } ~CAmSerializer() { } }; } /* namespace am */ #endif /* CAMSERIALIZER_H_ */