AudioManager  7.6.6
Native Application Runtime Environment
CAmSerializer.h
Go to the documentation of this file.
1 
18 #ifndef CAMSERIALIZER_H_
19 #define CAMSERIALIZER_H_
20 
21 #include <deque>
22 #include <cassert>
23 #include <memory>
24 #include <stdexcept>
25 #include <unistd.h>
26 #include "CAmDltWrapper.h"
27 #include "CAmSocketHandler.h"
28 
32 template<std::size_t ... Is>
33 struct indices
34 {
35 };
36 
37 template<std::size_t N, std::size_t ... Is>
38 struct build_indices: build_indices<N - 1, N - 1, Is...>
39 {
40 };
41 
42 template<std::size_t ... Is>
43 struct build_indices<0, Is...> : indices<Is...>
44 {
45 };
46 
47 template<int I> struct placeholder
48 {
49 };
50 
51 namespace std
52 {
53  template<int I>
54  struct is_placeholder<::placeholder<I>> : std::integral_constant<int, I>
55  {
56  };
57 }
58 
59 #if defined(__GNUC__)
60 # define DEPRECATED(MSG) __attribute__ ((__deprecated__((#MSG))))
61 #else
62 # define DEPRECATED(MSG)
63 #endif
64 
65 namespace am
66 {
85  namespace V1
86  {
88  {
89  private:
90 
94  class CAmDelegate
95  {
96  public:
97 
98  typedef enum
99  :bool
100  {
101  SyncCallType = false, AsyncCallType = true
102  } CallType;
103 
104  virtual ~CAmDelegate()
105  {
106  }
107  ;
108  virtual CallType call(int* pipe)=0;
109 
110  };
111 
115  template<class Class, typename Method, typename Tuple, bool Done, int Total, int ... N>
116  class CAmDelegateAsyncImpl: public CAmDelegate
117  {
118  Class mInstance;
119  Method mMethod;
120  Tuple mArguments;
121  public:
122  friend class CAmSerializer;
123  static void call(Class instance, Method method, Tuple && arguments)
124  {
125  CAmDelegateAsyncImpl<Class, Method, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(instance, method, std::forward<Tuple>(arguments));
126  }
127 
128  CAmDelegateAsyncImpl(Class instance, Method method, Tuple && arguments)
129  {
130  mInstance = instance;
131  mMethod = method;
132  mArguments = std::move(arguments);
133  }
134 
135  CallType call(int* pipe)
136  {
137  (void) pipe;
138  call(mInstance, mMethod, std::forward<Tuple>(mArguments));
139  return (AsyncCallType);
140  }
141  ;
142  };
143 
147  template<class Class, typename Method, typename Tuple, int Total, int ... N>
148  class CAmDelegateAsyncImpl<Class, Method, Tuple, true, Total, N...> : public CAmDelegate
149  {
150  Class mInstance;
151  Method mMethod;
152  Tuple mArguments;
153  public:
154  friend class CAmSerializer;
155  static void call(Class instance, Method method, Tuple && t)
156  {
157  (*instance.*method)(std::get<N>(std::forward<Tuple>(t))...);
158  }
159 
160  CAmDelegateAsyncImpl(Class instance, Method method, Tuple && arguments)
161  {
162  mInstance = instance;
163  mMethod = method;
164  mArguments = std::move(arguments);
165  }
166 
167  CallType call(int* pipe)
168  {
169  (void) pipe;
170  call(mInstance, mMethod, std::forward<Tuple>(mArguments));
171  return (AsyncCallType);
172  }
173  ;
174  };
175 
179  template<class Class, typename Method, typename Return, typename Tuple, bool Done, int Total, int ... N>
180  class CAmDelegateSyncImpl: public CAmDelegate
181  {
182  Class mInstance;
183  Method mMethod;
184  Tuple mArguments;
185  Return mReturn;
186  public:
187  friend class CAmSerializer;
188  static void call(Class instance, Method method, Return & result, Tuple && arguments)
189  {
190  CAmDelegateSyncImpl<Class, Method, Return, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(instance, method, result, std::forward<Tuple>(arguments));
191  }
192 
193  CAmDelegateSyncImpl(Class instance, Method method, Tuple && arguments)
194  {
195  mInstance = instance;
196  mMethod = method;
197  mArguments = std::move(arguments);
198  }
199 
200  CallType call(int* pipe)
201  {
202  call(mInstance, mMethod, mReturn, std::forward<Tuple>(mArguments));
203  ssize_t result(-1);
204  result = write(pipe[1], this, sizeof(this));
205  if (result == -1)
206  logError("CAmSerializer: Problem writing into pipe! Error No:", errno);
207  return (SyncCallType);
208  }
209  ;
210  };
211 
215  template<class Class, typename Method, typename Return, typename Tuple, int Total, int ... N>
216  class CAmDelegateSyncImpl<Class, Method, Return, Tuple, true, Total, N...> : public CAmDelegate
217  {
218  Class mInstance;
219  Method mMethod;
220  Tuple mArguments;
221  Return mReturn;
222  public:
223  friend class CAmSerializer;
224  static void call(Class instance, Method method, Return & result, Tuple && t)
225  {
226  result = (*instance.*method)(std::get<N>(t)...);
227  }
228 
229  CAmDelegateSyncImpl(Class instance, Method method, Tuple && arguments)
230  {
231  mInstance = instance;
232  mMethod = method;
233  mArguments = std::move(arguments);
234  }
235 
236  CallType call(int* pipe)
237  {
238  call(mInstance, mMethod, mReturn, std::forward<Tuple>(mArguments));
239  ssize_t result(-1);
240  result = write(pipe[1], this, sizeof(this));
241  if (result == -1)
242  logError("CAmSerializer: Problem writing into pipe! Error No:", errno);
243  return (SyncCallType);
244  }
245  ;
246  };
247 
248  typedef CAmDelegate* CAmDelegagePtr;
249 
250  public:
254  template<typename Class, typename Method, typename Tuple>
255  void doAsyncCall(Class intsance, Method method, Tuple & arguments)
256  {
257  typedef typename std::decay<Tuple>::type ttype;
258  typedef CAmDelegateAsyncImpl<Class, Method, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value> AsyncDelegate;
259  AsyncDelegate *pImp = new AsyncDelegate(intsance, method, std::forward<Tuple>(arguments));
260  send(pImp);
261  //Do not delete the pointer. It will be deleted automatically later.
262  }
263 
267  template<typename Class, typename Method, typename Return, typename Tuple>
268  void doSyncCall(Class intsance, Method method, Return & result, Tuple & arguments)
269  {
270  typedef typename std::decay<Tuple>::type ttype;
271  typedef CAmDelegateSyncImpl<Class, Method, Return, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value> SyncDelegate;
272  SyncDelegate *pImp = new SyncDelegate(intsance, method, std::forward<Tuple>(arguments));
273  send(pImp);
274  int numReads;
275  SyncDelegate *p = NULL;
276  if ((numReads = read(mReturnPipe[0], &p, sizeof(p))) == -1)
277  {
278  logError("CAmSerializer::doSyncCall could not read pipe!");
279  throw std::runtime_error("CAmSerializer Could not read pipe!");
280  }
281  result = std::move(pImp->mReturn);
282  arguments = std::move(pImp->mArguments);
283  //Delete the pointer.
284  delete pImp;
285  }
286  private:
287 
292  inline void send(CAmDelegagePtr p)
293  {
294  if (write(mPipe[1], &p, sizeof(p)) == -1)
295  {
296  throw std::runtime_error("could not write to pipe !");
297  }
298  }
299 
300  int mPipe[2];
301  int mReturnPipe[2];
302  sh_pollHandle_t mHandle;
303  CAmSocketHandler* mpSocketHandler;
304  std::deque<CAmDelegagePtr> mListDelegatePoiters;
305 
306  public:
307 
312  {
313  return mListDelegatePoiters.size();
314  }
315 
337  template<class TClass, class TRet, class ... TArgs>
338  void syncCall(TClass* instance, TRet (TClass::*method)(TArgs ...), TRet & result, TArgs & ... arguments)
339  {
340  auto t = std::make_tuple(arguments...);
341  doSyncCall(instance, method, result, t);
342  std::tie(arguments...) = t;
343  }
344 
364  template<class TClass, class TRet, class ... TArgs>
365  void asyncCall(TClass* instance, TRet (TClass::*method)(TArgs ...), TArgs & ... arguments)
366  {
367  auto t = std::make_tuple(arguments...);
368  doAsyncCall(instance, method, t);
369  }
370 
388  template<class TClass>
389  void asyncCall(TClass* instance, void (TClass::*function)())
390  {
391  auto t = std::make_tuple();
392  doAsyncCall(instance, function, t);
393  }
394 
415  template<class TClass1, class Targ>
416  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ), Targ argument)
417  {
418  auto t = std::make_tuple(argument);
419  doAsyncCall(instance, function, t);
420  }
421 
442  template<class TClass1, class Targ>
443  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ&), Targ& argument)
444  {
445  auto t = std::make_tuple(argument);
446  doAsyncCall(instance, function, t);
447  }
448 
459  template<class TClass1, class Targ, class Targ1>
460  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1), Targ argument, Targ1 argument1)
461  {
462  auto t = std::make_tuple(argument, argument1);
463  doAsyncCall(instance, function, t);
464  }
465 
476  template<class TClass1, class Targ, class Targ1>
477  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1 argument1), Targ& argument, Targ1 argument1)
478  {
479  auto t = std::make_tuple(argument, argument1);
480  doAsyncCall(instance, function, t);
481  }
482 
493  template<class TClass1, class Targ, class Targ1>
494  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1& argument1), Targ argument, Targ1& argument1)
495  {
496  auto t = std::make_tuple(argument, argument1);
497  doAsyncCall(instance, function, t);
498  }
499 
510  template<class TClass1, class Targ, class Targ1>
511  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1& argument1), Targ& argument, Targ1& argument1)
512  {
513  auto t = std::make_tuple(argument, argument1);
514  doAsyncCall(instance, function, t);
515  }
516 
520  template<class TClass1, class Targ, class Targ1, class Targ2>
521  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1, Targ2 argument2), Targ argument, Targ1 argument1, Targ2 argument2)
522  {
523  auto t = std::make_tuple(argument, argument1, argument2);
524  doAsyncCall(instance, function, t);
525  }
526 
530  template<class TClass1, class Targ, class Targ1, class Targ2>
531  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1 argument1, Targ2 argument2), Targ& argument, Targ1 argument1, Targ2 argument2)
532  {
533  auto t = std::make_tuple(argument, argument1, argument2);
534  doAsyncCall(instance, function, t);
535  }
536 
540  template<class TClass1, class Targ, class Targ1, class Targ2>
541  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1& argument1, Targ2 argument2), Targ argument, Targ1& argument1, Targ2 argument2)
542  {
543  auto t = std::make_tuple(argument, argument1, argument2);
544  doAsyncCall(instance, function, t);
545  }
546 
550  template<class TClass1, class Targ, class Targ1, class Targ2>
551  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1, Targ2& argument2), Targ argument, Targ1 argument1, Targ2& argument2)
552  {
553  auto t = std::make_tuple(argument, argument1, argument2);
554  doAsyncCall(instance, function, t);
555  }
556 
560  template<class TClass1, class Targ, class Targ1, class Targ2>
561  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1& argument1, Targ2& argument2), Targ argument, Targ1& argument1, Targ2& argument2)
562  {
563  auto t = std::make_tuple(argument, argument1, argument2);
564  doAsyncCall(instance, function, t);
565  }
566 
570  template<class TClass1, class Targ, class Targ1, class Targ2>
571  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1& argument1, Targ2& argument2), Targ& argument, Targ1& argument1, Targ2& argument2)
572  {
573  auto t = std::make_tuple(argument, argument1, argument2);
574  doAsyncCall(instance, function, t);
575  }
576 
580  template<class TClass1, class Targ, class Targ1, class Targ2>
581  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1& argument1, Targ2 argument2), Targ& argument, Targ1& argument1, Targ2 argument2)
582  {
583  auto t = std::make_tuple(argument, argument1, argument2);
584  doAsyncCall(instance, function, t);
585  }
586 
590  template<class TClass1, class Targ, class Targ1, class Targ2>
591  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ& argument, Targ1 argument1, Targ2& argument2), Targ& argument, Targ1 argument1, Targ2& argument2)
592  {
593  auto t = std::make_tuple(argument, argument1, argument2);
594  doAsyncCall(instance, function, t);
595  }
596 
600  template<class TClass1, class Targ, class Targ1, class Targ2, class Targ3>
601  void asyncCall(TClass1* instance, void (TClass1::*function)(Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3), Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3)
602  {
603  auto t = std::make_tuple(argument, argument1, argument2, argument3);
604  doAsyncCall(instance, function, t);
605  }
606 
629  template<class TClass1, class TretVal>
630  void syncCall(TClass1* instance, TretVal (TClass1::*function)(), TretVal& retVal)
631  {
632  auto t = std::make_tuple();
633  doSyncCall(instance, function, retVal, t);
634  }
635 
662  template<class TClass1, class TretVal, class TargCall, class Targ>
663  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall), TretVal& retVal, Targ& argument)
664  {
665  auto t = std::make_tuple(argument);
666  doSyncCall(instance, function, retVal, t);
667  std::tie(argument) = t;
668  }
669 
673  template<class TClass1, class TretVal, class TargCall, class Targ>
674  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall) const, TretVal& retVal, Targ& argument)
675  {
676  auto t = std::make_tuple(argument);
677  doSyncCall(instance, function, retVal, t);
678  std::tie(argument) = t;
679  }
680 
684  template<class TClass1, class TretVal, class TargCall, class Targ1Call, class Targ, class Targ1>
685  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, Targ1Call), TretVal& retVal, Targ& argument, Targ1& argument1)
686  {
687  auto t = std::make_tuple(argument, argument1);
688  doSyncCall(instance, function, retVal, t);
689  std::tie(argument, argument1) = t;
690  }
694  template<class TClass1, class TretVal, class TargCall, class Targ1Call, class Targ, class Targ1>
695  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, Targ1Call) const, TretVal& retVal, Targ& argument, Targ1& argument1)
696  {
697  auto t = std::make_tuple(argument, argument1);
698  doSyncCall(instance, function, retVal, t);
699  std::tie(argument, argument1) = t;
700  }
701 
705  template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class Targ, class Targ1, class Targ2>
706  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2)
707  {
708  auto t = std::make_tuple(argument, argument1, argument2);
709  doSyncCall(instance, function, retVal, t);
710  std::tie(argument, argument1, argument2) = t;
711  }
712 
716  template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class Targ, class Targ1, class Targ2>
717  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2) const, TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2)
718  {
719  auto t = std::make_tuple(argument, argument1, argument2);
720  doSyncCall(instance, function, retVal, t);
721  std::tie(argument, argument1, argument2) = t;
722  }
723 
727  template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class Targ, class Targ1, class Targ2, class Targ3>
728  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3)
729  {
730  auto t = std::make_tuple(argument, argument1, argument2, argument3);
731  doSyncCall(instance, function, retVal, t);
732  std::tie(argument, argument1, argument2, argument3) = t;
733  }
734 
738  template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class TargCall4, class Targ, class Targ1, class Targ2, class Targ3, class Targ4>
739  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3, TargCall4), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3, Targ4& argument4)
740  {
741  auto t = std::make_tuple(argument, argument1, argument2, argument3, argument4);
742  doSyncCall(instance, function, retVal, t);
743  std::tie(argument, argument1, argument2, argument3, argument4) = t;
744  }
745 
749  template<class TClass1, class TretVal, class TargCall, class TargCall1, class TargCall2, class TargCall3, class TargCall4, class TargCall5, class Targ, class Targ1, class Targ2, class Targ3, class Targ4, class Targ5>
750  void syncCall(TClass1* instance, TretVal (TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3, TargCall4, TargCall5), TretVal& retVal, Targ& argument, Targ1& argument1, Targ2& argument2, Targ3& argument3,
751  Targ4& argument4, Targ5& argument5)
752  {
753  auto t = std::make_tuple(argument, argument1, argument2, argument3, argument4, argument5);
754  doSyncCall(instance, function, retVal, t);
755  std::tie(argument, argument1, argument2, argument3, argument4, argument5) = t;
756  }
757 
761  void receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
762  {
763  (void) handle;
764  (void) userData;
765  int numReads;
766  CAmDelegagePtr listPointers[3];
767  if ((numReads = read(pollfd.fd, &listPointers, sizeof(listPointers))) == -1)
768  {
769  logError("CAmSerializer::receiverCallback could not read pipe!");
770  throw std::runtime_error("CAmSerializer Could not read pipe!");
771  }
772  mListDelegatePoiters.assign(listPointers, listPointers + (numReads / sizeof(CAmDelegagePtr)));
773  }
774 
778  bool checkerCallback(const sh_pollHandle_t handle, void* userData)
779  {
780  (void) handle;
781  (void) userData;
782  if (mListDelegatePoiters.empty())
783  return (false);
784  return (true);
785  }
786 
790  bool dispatcherCallback(const sh_pollHandle_t handle, void* userData)
791  {
792  (void) handle;
793  (void) userData;
794  CAmDelegagePtr delegatePoiter = mListDelegatePoiters.front();
795  mListDelegatePoiters.pop_front();
796  if (delegatePoiter->call(mReturnPipe))
797  delete delegatePoiter;
798  if (mListDelegatePoiters.empty())
799  return (false);
800  return (true);
801  }
802 
806 
811  CAmSerializer(CAmSocketHandler *iSocketHandler) :
812  mPipe(), //
813  mReturnPipe(), //
814  mHandle(),
815  mpSocketHandler(iSocketHandler),
816  mListDelegatePoiters(), //
817  receiverCallbackT(this, &CAmSerializer::receiverCallback), //
818  dispatcherCallbackT(this, &CAmSerializer::dispatcherCallback), //
819  checkerCallbackT(this, &CAmSerializer::checkerCallback)
820  {
821  assert(NULL!=iSocketHandler);
822 
823  if (pipe(mPipe) == -1)
824  {
825  logError("CAmSerializer could not create pipe!");
826  throw std::runtime_error("CAmSerializer Could not open pipe!");
827  }
828 
829  if (pipe(mReturnPipe) == -1)
830  {
831  logError("CAmSerializer could not create mReturnPipe!");
832  throw std::runtime_error("CAmSerializer Could not open mReturnPipe!");
833  }
834 
835  short event = 0;
836  event |= POLLIN;
837  mpSocketHandler->addFDPoll(mPipe[0], event, NULL, &receiverCallbackT, &checkerCallbackT, &dispatcherCallbackT, NULL, mHandle);
838  }
839 
841  {
842  mpSocketHandler->removeFDPoll(mHandle);
843  close(mPipe[0]);
844  close(mPipe[1]);
845  close(mReturnPipe[0]);
846  close(mReturnPipe[1]);
847  }
848  };
849 
850  } /* namespace V1 */
851 
854  namespace V2
855  {
857  {
861  class CAmDelegate
862  {
863  public:
864  typedef enum
865  :bool
866  {
867  SyncCallType = false, AsyncCallType = true
868  } CallType;
869 
870  virtual ~CAmDelegate()
871  {
872  }
873  ;
874  virtual CallType call(int* pipe)=0;
875  };
876 
880  template<class TInvocation>
881  class CAmDelegateAsyncImpl: public CAmDelegate
882  {
883  TInvocation mInvocation;
884  public:
885  friend class CAmSerializer;
886  CAmDelegateAsyncImpl(TInvocation && invocation) :
887  mInvocation(std::move(invocation))
888  {
889  }
890 
891  CallType call(int* pipe)
892  {
893  (void) pipe;
894  mInvocation();
895  return (AsyncCallType);
896  }
897  ;
898  };
899 
900  template<class TInvocation, class TRet>
901  class CAmDelegateSyncImpl: public CAmDelegate
902  {
903  TInvocation mInvocation;
904  TRet & mReturn;
905  public:
906  friend class CAmSerializer;
907  CAmDelegateSyncImpl(TInvocation && invocation, TRet && ret) :
908  mInvocation(std::move(invocation)), mReturn(ret)
909  {
910  }
911 
912  CallType call(int* pipe)
913  {
914  mReturn = mInvocation();
915  ssize_t result(-1);
916  result = write(pipe[1], this, sizeof(this));
917  if (result == -1)
918  logError("CAmSerializer: Problem writing into pipe! Error No:", errno);
919  return (SyncCallType);
920  }
921  ;
922  };
923 
924  template<class TInvocation>
925  class CAmDelegateSyncVoidImpl: public CAmDelegate
926  {
927  TInvocation mInvocation;
928  public:
929  friend class CAmSerializer;
930  CAmDelegateSyncVoidImpl(TInvocation && invocation) :
931  mInvocation(std::move(invocation))
932  {
933  }
934 
935  CallType call(int* pipe)
936  {
937  mInvocation();
938  ssize_t result(-1);
939  result = write(pipe[1], this, sizeof(this));
940  if (result == -1)
941  logError("CAmSerializer: Problem writing into pipe! Error No:", errno);
942  return (SyncCallType);
943  }
944  ;
945  };
946 
947  typedef CAmDelegate* CAmDelegagePtr;
948 
949  void sendSync(CAmDelegagePtr pDelegate)
950  {
951  send(pDelegate);
952  int numReads;
953  CAmDelegagePtr *p = NULL;
954  if ((numReads = read(mReturnPipe[0], &p, sizeof(p))) == -1)
955  {
956  logError("CAmSerializer::doSyncCall could not read pipe!");
957  throw std::runtime_error("CAmSerializer Could not read pipe!");
958  }
959  }
960 
965  inline void send(CAmDelegagePtr p)
966  {
967  if (write(mPipe[1], &p, sizeof(p)) == -1)
968  {
969  throw std::runtime_error("could not write to pipe !");
970  }
971  }
972 
973  int mPipe[2];
974  int mReturnPipe[2];
975  sh_pollHandle_t mHandle;
976  CAmSocketHandler* mpSocketHandler;
977  std::deque<CAmDelegagePtr> mListDelegatePointers;
978 
979  public:
980 
985  {
986  return mListDelegatePointers.size();
987  }
988 
998  template<class TFunc>
999  void asyncInvocation(TFunc invocation)
1000  {
1001  static_assert(std::is_bind_expression<TFunc>::value,"The type is not produced by std::bind");
1002  typedef CAmDelegateAsyncImpl<TFunc> AsyncDelegate;
1003  AsyncDelegate *pImp = new AsyncDelegate(std::forward<TFunc>(invocation));
1004  send(pImp);
1005  //Do not delete the pointer. It will be deleted automatically later.
1006  }
1007 
1027  template<class TClass, class TMeth, class TRet, class ... TArgs>
1028  void asyncCall(TClass* instance, TMeth method, TArgs && ... arguments)
1029  {
1030  auto invocation = std::bind(method, instance, std::forward<TArgs>(arguments)...);
1031  asyncInvocation(invocation);
1032  }
1033 
1034  template<class TClass, class TMeth, class ... TArgs>
1035  void asyncCall(TClass* instance, TMeth method, TArgs && ... arguments)
1036  {
1037  auto invocation = std::bind(method, instance, std::forward<TArgs>(arguments)...);
1038  asyncInvocation(invocation);
1039  }
1040 
1052  template<class TFunc, class TRet>
1053  void syncInvocation(TFunc invocation, TRet && result)
1054  {
1055  static_assert(std::is_bind_expression<TFunc>::value,"The type is not produced by std::bind");
1056 
1057  typedef CAmDelegateSyncImpl<TFunc, TRet> SyncDelegate;
1058 
1059  SyncDelegate *pImp = new SyncDelegate(std::forward<TFunc>(invocation), std::forward<TRet>(result));
1060  sendSync(pImp);
1061  //Delete the pointer.
1062  delete pImp;
1063  }
1064 
1074  template<class TFunc>
1075  void syncInvocation(TFunc invocation)
1076  {
1077  static_assert(std::is_bind_expression<TFunc>::value,"The type is not produced by std::bind");
1078 
1079  typedef CAmDelegateSyncVoidImpl<TFunc> SyncDelegate;
1080 
1081  SyncDelegate *pImp = new SyncDelegate(std::forward<TFunc>(invocation));
1082  sendSync(pImp);
1083  //Delete the pointer.
1084  delete pImp;
1085  }
1107  template<class TClass, class TMeth, class TRet, class ... TArgs>
1108  void syncCall(TClass* instance, TMeth method, TRet & result, TArgs && ... arguments)
1109  {
1110  auto invocation = std::bind(method, instance, std::ref(arguments)...);
1111  syncInvocation(invocation, result);
1112  }
1113 
1114  template<class TClass, class TMeth, class ... TArgs>
1115  void syncCall(TClass* instance, TMeth method, TArgs && ... arguments)
1116  {
1117  auto invocation = std::bind(method, instance, std::ref(arguments)...);
1118  syncInvocation(invocation);
1119  }
1120 
1124  void receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
1125  {
1126  (void) handle;
1127  (void) userData;
1128  int numReads;
1129  CAmDelegagePtr listPointers[3];
1130  if ((numReads = read(pollfd.fd, &listPointers, sizeof(listPointers))) == -1)
1131  {
1132  logError("CAmSerializer::receiverCallback could not read pipe!");
1133  throw std::runtime_error("CAmSerializer Could not read pipe!");
1134  }
1135  mListDelegatePointers.assign(listPointers, listPointers + (numReads / sizeof(CAmDelegagePtr)));
1136  }
1137 
1141  bool checkerCallback(const sh_pollHandle_t handle, void* userData)
1142  {
1143  (void) handle;
1144  (void) userData;
1145  if (mListDelegatePointers.empty())
1146  return (false);
1147  return (true);
1148  }
1149 
1153  bool dispatcherCallback(const sh_pollHandle_t handle, void* userData)
1154  {
1155  (void) handle;
1156  (void) userData;
1157  CAmDelegagePtr delegatePoiter = mListDelegatePointers.front();
1158  mListDelegatePointers.pop_front();
1159  if (delegatePoiter->call(mReturnPipe))
1160  delete delegatePoiter;
1161  if (mListDelegatePointers.empty())
1162  return (false);
1163  return (true);
1164  }
1165 
1169 
1174  CAmSerializer(CAmSocketHandler *iSocketHandler) :
1175  mPipe(), //
1176  mReturnPipe(), //
1177  mHandle(),
1178  mpSocketHandler(iSocketHandler),
1179  mListDelegatePointers(), //
1180  receiverCallbackT(this, &CAmSerializer::receiverCallback), //
1181  dispatcherCallbackT(this, &CAmSerializer::dispatcherCallback), //
1182  checkerCallbackT(this, &CAmSerializer::checkerCallback)
1183  {
1184  assert(NULL!=iSocketHandler);
1185 
1186  if (pipe(mPipe) == -1)
1187  {
1188  logError("CAmSerializer could not create pipe!");
1189  throw std::runtime_error("CAmSerializer Could not open pipe!");
1190  }
1191 
1192  if (pipe(mReturnPipe) == -1)
1193  {
1194  logError("CAmSerializer could not create mReturnPipe!");
1195  throw std::runtime_error("CAmSerializer Could not open mReturnPipe!");
1196  }
1197 
1198  short event = 0;
1199  event |= POLLIN;
1200  mpSocketHandler->addFDPoll(mPipe[0], event, NULL, &receiverCallbackT, &checkerCallbackT, &dispatcherCallbackT, NULL, mHandle);
1201  }
1202 
1204  {
1205  mpSocketHandler->removeFDPoll(mHandle);
1206  close(mPipe[0]);
1207  close(mPipe[1]);
1208  close(mReturnPipe[0]);
1209  close(mReturnPipe[1]);
1210  }
1211  };
1212  } /* namespace V2 */
1213 
1214  typedef V1::CAmSerializer CAmSerializer DEPRECATED("You should use V2::CAmSerializer instead!");
1215 
1216 } /* namespace am */
1217 #endif /* CAMSERIALIZER_H_ */
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ &argument, Targ1 argument1), Targ &argument, Targ1 argument1)
calls a function with two arguments asynchronously threadsafe, first argument is a reference...
void asyncInvocation(TFunc invocation)
calls a function with variadic arguments threadsafe
A Common-API wrapper class, which loads the common-api runtime and instantiates all necessary objects...
TAmShPollFired< CAmSerializer > receiverCallbackT
Helper structures used within std::bind for automatically identification of all placeholders.
Definition: CAmSerializer.h:33
TAmShPollFired< CAmSerializer > receiverCallbackT
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3, TargCall4), TretVal &retVal, Targ &argument, Targ1 &argument1, Targ2 &argument2, Targ3 &argument3, Targ4 &argument4)
calls a function with five arguments synchronously threadsafe.
bool dispatcherCallback(const sh_pollHandle_t handle, void *userData)
dispatcher callback for sockethandling, for more, see CAmSocketHandler
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ argument, Targ1 argument1, Targ2 argument2), Targ argument, Targ1 argument1, Targ2 argument2)
calls a function with three arguments asynchronously threadsafe.
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(), TretVal &retVal)
calls a synchronous function with no arguments threadsafe
template for a callback
TAmShPollDispatch< CAmSerializer > dispatcherCallbackT
size_t getListDelegatePointers()
get the size of delegate pointers
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(TargCall, Targ1Call), TretVal &retVal, Targ &argument, Targ1 &argument1)
calls a function with two arguments synchronously threadsafe.
void asyncCall(TClass *instance, TRet(TClass::*method)(TArgs...), TArgs &...arguments)
calls a function with variadic arguments threadsafe
int getListDelegatePoiters()
get the size of delegate pointers
make private, not public template for a callback
The am::CAmSocketHandler implements a mainloop for the AudioManager.
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3), Targ argument, Targ1 argument1, Targ2 argument2, Targ3 argument3)
calls a function with four arguments asynchronously threadsafe.
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ), Targ argument)
calls a function with one arguments asynchronously threadsafe
STL namespace.
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ &argument, Targ1 argument1, Targ2 argument2), Targ &argument, Targ1 argument1, Targ2 argument2)
calls a function with three arguments asynchronously threadsafe.
void syncCall(TClass *instance, TMeth method, TArgs &&...arguments)
uint16_t sh_pollHandle_t
this is a handle for a filedescriptor to be used with the SocketHandler
SPDX license identifier: MPL-2.0.
void asyncCall(TClass *instance, void(TClass::*function)())
calls a function with no arguments threadsafe
am_Error_e removeFDPoll(const sh_pollHandle_t handle)
removes a filedescriptor from the poll loop
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(TargCall, Targ1Call) const, TretVal &retVal, Targ &argument, Targ1 &argument1)
calls a function with two arguments synchronously threadsafe const.
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(TargCall, TargCall1, TargCall2) const, TretVal &retVal, Targ &argument, Targ1 &argument1, Targ2 &argument2)
calls a const function with three arguments synchronously threadsafe.
CAmSerializer(CAmSocketHandler *iSocketHandler)
The constructor must be called in the mainthread context !
CAmSerializer(CAmSocketHandler *iSocketHandler)
The constructor must be called in the mainthread context !
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ argument, Targ1 &argument1, Targ2 argument2), Targ argument, Targ1 &argument1, Targ2 argument2)
calls a function with three arguments asynchronously threadsafe.
template for a callback
void syncInvocation(TFunc invocation)
calls a function with variadic arguments threadsafe
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(TargCall) const, TretVal &retVal, Targ &argument)
calls a function with one argument synchronous threadsafe for const functions.
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(TargCall, TargCall1, TargCall2, TargCall3), TretVal &retVal, Targ &argument, Targ1 &argument1, Targ2 &argument2, Targ3 &argument3)
calls a function with four arguments synchronously threadsafe.
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ argument, Targ1 &argument1, Targ2 &argument2), Targ argument, Targ1 &argument1, Targ2 &argument2)
calls a function with three arguments asynchronously threadsafe.
#define DEPRECATED(MSG)
Definition: CAmSerializer.h:62
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ &argument, Targ1 &argument1), Targ &argument, Targ1 &argument1)
calls a function with two arguments asynchronously threadsafe, both arguments are references...
bool dispatcherCallback(const sh_pollHandle_t handle, void *userData)
dispatcher callback for sockethandling, for more, see CAmSocketHandler
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)
calls a function with six arguments synchronously threadsafe.
am_Error_e addFDPoll(const int fd, const short event, std::function< void(const sh_pollHandle_t handle, void *userData)> prepare, std::function< void(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)> fired, std::function< bool(const sh_pollHandle_t handle, void *userData)> check, std::function< bool(const sh_pollHandle_t handle, void *userData)> dispatch, void *userData, sh_pollHandle_t &handle)
Adds a filedescriptor to the polling loop.
TAmShPollDispatch< CAmSerializer > dispatcherCallbackT
void doSyncCall(Class intsance, Method method, Return &result, Tuple &arguments)
instantiates a sync delegate with given arguments and sends the delegate pointer over the pipe ...
SPDX license identifier: MPL-2.0.
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(TargCall, TargCall1, TargCall2), TretVal &retVal, Targ &argument, Targ1 &argument1, Targ2 &argument2)
calls a function with three arguments synchronously threadsafe.
void logError(T value, TArgs...args)
logs given values with errorlevel with the default context
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ argument, Targ1 argument1), Targ argument, Targ1 argument1)
calls a function with two arguments asynchronously threadsafe.
void syncCall(TClass1 *instance, TretVal(TClass1::*function)(TargCall), TretVal &retVal, Targ &argument)
calls a function with one argument synchronous threadsafe
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ argument, Targ1 argument1, Targ2 &argument2), Targ argument, Targ1 argument1, Targ2 &argument2)
calls a function with three arguments asynchronously threadsafe.
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ &argument, Targ1 &argument1, Targ2 argument2), Targ &argument, Targ1 &argument1, Targ2 argument2)
calls a function with three arguments asynchronously threadsafe.
void doAsyncCall(Class intsance, Method method, Tuple &arguments)
instantiates a async delegate with given arguments and sends the delegate pointer over the pipe ...
void syncCall(TClass *instance, TRet(TClass::*method)(TArgs...), TRet &result, TArgs &...arguments)
calls a function with variadic arguments threadsafe
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ &), Targ &argument)
calls a function with one argument called by reference asynchronously threadsafe
bool checkerCallback(const sh_pollHandle_t handle, void *userData)
checker callback for sockethandling, for more, see CAmSocketHandler
void receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
receiver callback for sockethandling, for more, see CAmSocketHandler
TAmShPollCheck< CAmSerializer > checkerCallbackT
TAmShPollCheck< CAmSerializer > checkerCallbackT
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ argument, Targ1 &argument1), Targ argument, Targ1 &argument1)
calls a function with two arguments asynchronously threadsafe, second argument is a reference...
void receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
receiver callback for sockethandling, for more, see CAmSocketHandler
bool checkerCallback(const sh_pollHandle_t handle, void *userData)
checker callback for sockethandling, for more, see CAmSocketHandler
void asyncCall(TClass *instance, TMeth method, TArgs &&...arguments)
calls a function with variadic arguments threadsafe
void asyncCall(TClass *instance, TMeth method, TArgs &&...arguments)
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ &argument, Targ1 argument1, Targ2 &argument2), Targ &argument, Targ1 argument1, Targ2 &argument2)
calls a function with three arguments asynchronously threadsafe.
void syncInvocation(TFunc invocation, TRet &&result)
calls a function with variadic arguments threadsafe
void syncCall(TClass *instance, TMeth method, TRet &result, TArgs &&...arguments)
calls a function with variadic arguments threadsafe
void asyncCall(TClass1 *instance, void(TClass1::*function)(Targ &argument, Targ1 &argument1, Targ2 &argument2), Targ &argument, Targ1 &argument1, Targ2 &argument2)
calls a function with three arguments asynchronously threadsafe.