ActiveMethod.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. //
  2. // ActiveMethod.h
  3. //
  4. // Library: Foundation
  5. // Package: Threading
  6. // Module: ActiveObjects
  7. //
  8. // Definition of the ActiveMethod class.
  9. //
  10. // Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #ifndef Foundation_ActiveMethod_INCLUDED
  16. #define Foundation_ActiveMethod_INCLUDED
  17. #include "Poco/Foundation.h"
  18. #include "Poco/ActiveResult.h"
  19. #include "Poco/ActiveRunnable.h"
  20. #include "Poco/ActiveStarter.h"
  21. #include "Poco/AutoPtr.h"
  22. namespace Poco {
  23. template <class ResultType, class ArgType, class OwnerType, class StarterType = ActiveStarter<OwnerType> >
  24. class ActiveMethod
  25. /// An active method is a method that, when called, executes
  26. /// in its own thread. ActiveMethod's take exactly one
  27. /// argument and can return a value. To pass more than one
  28. /// argument to the method, use a struct.
  29. /// The following example shows how to add an ActiveMethod
  30. /// to a class:
  31. ///
  32. /// class ActiveObject
  33. /// {
  34. /// public:
  35. /// ActiveObject():
  36. /// exampleActiveMethod(this, &ActiveObject::exampleActiveMethodImpl)
  37. /// {
  38. /// }
  39. ///
  40. /// ActiveMethod<std::string, std::string, ActiveObject> exampleActiveMethod;
  41. ///
  42. /// protected:
  43. /// std::string exampleActiveMethodImpl(const std::string& arg)
  44. /// {
  45. /// ...
  46. /// }
  47. /// };
  48. ///
  49. /// And following is an example that shows how to invoke an ActiveMethod.
  50. ///
  51. /// ActiveObject myActiveObject;
  52. /// ActiveResult<std::string> result = myActiveObject.exampleActiveMethod("foo");
  53. /// ...
  54. /// result.wait();
  55. /// std::cout << result.data() << std::endl;
  56. ///
  57. /// The way an ActiveMethod is started can be changed by passing a StarterType
  58. /// template argument with a corresponding class. The default ActiveStarter
  59. /// starts the method in its own thread, obtained from a thread pool.
  60. ///
  61. /// For an alternative implementation of StarterType, see ActiveDispatcher.
  62. ///
  63. /// For methods that do not require an argument or a return value, the Void
  64. /// class can be used.
  65. {
  66. public:
  67. typedef ResultType (OwnerType::*Callback)(const ArgType&);
  68. typedef ActiveResult<ResultType> ActiveResultType;
  69. typedef ActiveRunnable<ResultType, ArgType, OwnerType> ActiveRunnableType;
  70. ActiveMethod(OwnerType* pOwner, Callback method):
  71. _pOwner(pOwner),
  72. _method(method)
  73. /// Creates an ActiveMethod object.
  74. {
  75. poco_check_ptr (pOwner);
  76. }
  77. ActiveResultType operator () (const ArgType& arg)
  78. /// Invokes the ActiveMethod.
  79. {
  80. ActiveResultType result(new ActiveResultHolder<ResultType>());
  81. ActiveRunnableBase::Ptr pRunnable(new ActiveRunnableType(_pOwner, _method, arg, result));
  82. StarterType::start(_pOwner, pRunnable);
  83. return result;
  84. }
  85. ActiveMethod(const ActiveMethod& other):
  86. _pOwner(other._pOwner),
  87. _method(other._method)
  88. {
  89. }
  90. ActiveMethod& operator = (const ActiveMethod& other)
  91. {
  92. ActiveMethod tmp(other);
  93. swap(tmp);
  94. return *this;
  95. }
  96. void swap(ActiveMethod& other)
  97. {
  98. std::swap(_pOwner, other._pOwner);
  99. std::swap(_method, other._method);
  100. }
  101. private:
  102. ActiveMethod();
  103. OwnerType* _pOwner;
  104. Callback _method;
  105. };
  106. template <class ResultType, class OwnerType, class StarterType>
  107. class ActiveMethod <ResultType, void, OwnerType, StarterType>
  108. /// An active method is a method that, when called, executes
  109. /// in its own thread. ActiveMethod's take exactly one
  110. /// argument and can return a value. To pass more than one
  111. /// argument to the method, use a struct.
  112. /// The following example shows how to add an ActiveMethod
  113. /// to a class:
  114. ///
  115. /// class ActiveObject
  116. /// {
  117. /// public:
  118. /// ActiveObject():
  119. /// exampleActiveMethod(this, &ActiveObject::exampleActiveMethodImpl)
  120. /// {
  121. /// }
  122. ///
  123. /// ActiveMethod<std::string, std::string, ActiveObject> exampleActiveMethod;
  124. ///
  125. /// protected:
  126. /// std::string exampleActiveMethodImpl(const std::string& arg)
  127. /// {
  128. /// ...
  129. /// }
  130. /// };
  131. ///
  132. /// And following is an example that shows how to invoke an ActiveMethod.
  133. ///
  134. /// ActiveObject myActiveObject;
  135. /// ActiveResult<std::string> result = myActiveObject.exampleActiveMethod("foo");
  136. /// ...
  137. /// result.wait();
  138. /// std::cout << result.data() << std::endl;
  139. ///
  140. /// The way an ActiveMethod is started can be changed by passing a StarterType
  141. /// template argument with a corresponding class. The default ActiveStarter
  142. /// starts the method in its own thread, obtained from a thread pool.
  143. ///
  144. /// For an alternative implementation of StarterType, see ActiveDispatcher.
  145. ///
  146. /// For methods that do not require an argument or a return value, simply use void.
  147. {
  148. public:
  149. typedef ResultType (OwnerType::*Callback)(void);
  150. typedef ActiveResult<ResultType> ActiveResultType;
  151. typedef ActiveRunnable<ResultType, void, OwnerType> ActiveRunnableType;
  152. ActiveMethod(OwnerType* pOwner, Callback method):
  153. _pOwner(pOwner),
  154. _method(method)
  155. /// Creates an ActiveMethod object.
  156. {
  157. poco_check_ptr (pOwner);
  158. }
  159. ActiveResultType operator () (void)
  160. /// Invokes the ActiveMethod.
  161. {
  162. ActiveResultType result(new ActiveResultHolder<ResultType>());
  163. ActiveRunnableBase::Ptr pRunnable(new ActiveRunnableType(_pOwner, _method, result));
  164. StarterType::start(_pOwner, pRunnable);
  165. return result;
  166. }
  167. ActiveMethod(const ActiveMethod& other):
  168. _pOwner(other._pOwner),
  169. _method(other._method)
  170. {
  171. }
  172. ActiveMethod& operator = (const ActiveMethod& other)
  173. {
  174. ActiveMethod tmp(other);
  175. swap(tmp);
  176. return *this;
  177. }
  178. void swap(ActiveMethod& other)
  179. {
  180. std::swap(_pOwner, other._pOwner);
  181. std::swap(_method, other._method);
  182. }
  183. private:
  184. ActiveMethod();
  185. OwnerType* _pOwner;
  186. Callback _method;
  187. };
  188. } // namespace Poco
  189. #endif // Foundation_ActiveMethod_INCLUDED