ActiveMethod.h 5.8 KB

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