PageRenderTime 22ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/labo/2009.08.17/poco-1.3.5-mingw/Net/include/Poco/Net/SocketReactor.h

http://mingw-lib.googlecode.com/
C++ Header | 238 lines | 55 code | 32 blank | 151 comment | 0 complexity | 9c7044631547d425c45c3fd1fb240da6 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, MPL-2.0-no-copyleft-exception
  1. //
  2. // SocketReactor.h
  3. //
  4. // $Id: //poco/1.3/Net/include/Poco/Net/SocketReactor.h#3 $
  5. //
  6. // Library: Net
  7. // Package: Reactor
  8. // Module: SocketReactor
  9. //
  10. // Definition of the SocketReactor class.
  11. //
  12. // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // Permission is hereby granted, free of charge, to any person or organization
  16. // obtaining a copy of the software and accompanying documentation covered by
  17. // this license (the "Software") to use, reproduce, display, distribute,
  18. // execute, and transmit the Software, and to prepare derivative works of the
  19. // Software, and to permit third-parties to whom the Software is furnished to
  20. // do so, all subject to the following:
  21. //
  22. // The copyright notices in the Software and this entire statement, including
  23. // the above license grant, this restriction and the following disclaimer,
  24. // must be included in all copies of the Software, in whole or in part, and
  25. // all derivative works of the Software, unless such copies or derivative
  26. // works are solely in the form of machine-executable object code generated by
  27. // a source language processor.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  32. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  33. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  34. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  35. // DEALINGS IN THE SOFTWARE.
  36. //
  37. #ifndef Net_SocketReactor_INCLUDED
  38. #define Net_SocketReactor_INCLUDED
  39. #include "Poco/Net/Net.h"
  40. #include "Poco/Net/Socket.h"
  41. #include "Poco/Runnable.h"
  42. #include "Poco/Timespan.h"
  43. #include "Poco/Observer.h"
  44. #include "Poco/AutoPtr.h"
  45. #include <map>
  46. namespace Poco {
  47. namespace Net {
  48. class Socket;
  49. class SocketNotification;
  50. class SocketNotifier;
  51. class Net_API SocketReactor: public Poco::Runnable
  52. /// This class, which is part of the Reactor pattern,
  53. /// implements the "Initiation Dispatcher".
  54. ///
  55. /// The Reactor pattern has been described in the book
  56. /// "Pattern Languages of Program Design" by Jim Coplien
  57. /// and Douglas C. Schmidt (Addison Wesley, 1995).
  58. ///
  59. /// The Reactor design pattern handles service requests that
  60. /// are delivered concurrently to an application by one or more
  61. /// clients. Each service in an application may consist of several
  62. /// methods and is represented by a separate event handler. The event
  63. /// handler is responsible for servicing service-specific requests.
  64. /// The SocketReactor dispatches the event handlers.
  65. ///
  66. /// Event handlers (any class can be an event handler - there
  67. /// is no base class for event handlers) can be registered
  68. /// with the addEventHandler() method and deregistered with
  69. /// the removeEventHandler() method.
  70. ///
  71. /// An event handler is always registered for a certain socket,
  72. /// which is given in the call to addEventHandler(). Any method
  73. /// of the event handler class can be registered to handle the
  74. /// event - the only requirement is that the method takes
  75. /// a pointer to an instance of SocketNotification (or a subclass of it)
  76. /// as argument.
  77. ///
  78. /// Once started, the SocketReactor waits for events
  79. /// on the registered sockets, using Socket::select().
  80. /// If an event is detected, the corresponding event handler
  81. /// is invoked. There are five event types (and corresponding
  82. /// notification classes) defined: ReadableNotification, WritableNotification,
  83. /// ErrorNotification, TimeoutNotification, IdleNotification and
  84. /// ShutdownNotification.
  85. ///
  86. /// The ReadableNotification will be dispatched if a socket becomes
  87. /// readable. The WritableNotification will be dispatched if a socket
  88. /// becomes writable. The ErrorNotification will be dispatched if
  89. /// there is an error condition on a socket.
  90. ///
  91. /// If the timeout expires and no event has occured, a
  92. /// TimeoutNotification will be dispatched to all event handlers
  93. /// registered for it. This is done in the onTimeout() method
  94. /// which can be overridden by subclasses to perform custom
  95. /// timeout processing.
  96. ///
  97. /// If there are no sockets for the SocketReactor to pass to
  98. /// Socket::select(), an IdleNotification will be dispatched to
  99. /// all event handlers registered for it. This is done in the
  100. /// onIdle() method which can be overridden by subclasses
  101. /// to perform custom idle processing. Since onIdle() will be
  102. /// called repeatedly in a loop, it is recommended to do a
  103. /// short sleep or yield in the event handler.
  104. ///
  105. /// Finally, when the SocketReactor is about to shut down (as a result
  106. /// of stop() being called), it dispatches a ShutdownNotification
  107. /// to all event handlers. This is done in the onShutdown() method
  108. /// which can be overridded by subclasses to perform custom
  109. /// shutdown processing.
  110. ///
  111. /// The SocketReactor is implemented so that it can
  112. /// run in its own thread. It is also possible to run
  113. /// multiple SocketReactors in parallel, as long as
  114. /// they work on different sockets.
  115. ///
  116. /// It is safe to call addEventHandler() and removeEventHandler()
  117. /// from another thread while the SocketReactor is running. Also,
  118. /// it is safe to call addEventHandler() and removeEventHandler()
  119. /// from event handlers.
  120. {
  121. public:
  122. SocketReactor();
  123. /// Creates the SocketReactor.
  124. explicit SocketReactor(const Poco::Timespan& timeout);
  125. /// Creates the SocketReactor, using the given timeout.
  126. virtual ~SocketReactor();
  127. /// Destroys the SocketReactor.
  128. void run();
  129. /// Runs the SocketReactor. The reactor will run
  130. /// until stop() is called (in a separate thread).
  131. void stop();
  132. /// Stops the SocketReactor.
  133. ///
  134. /// The reactor will be stopped when the next event
  135. /// (including a timeout event) occurs.
  136. void setTimeout(const Poco::Timespan& timeout);
  137. /// Sets the timeout.
  138. ///
  139. /// If no other event occurs for the given timeout
  140. /// interval, a timeout event is sent to all event listeners.
  141. ///
  142. /// The default timeout is 250 milliseconds;
  143. ///
  144. /// The timeout is passed to the Socket::select()
  145. /// method.
  146. const Poco::Timespan& getTimeout() const;
  147. /// Returns the timeout.
  148. void addEventHandler(const Socket& socket, const Poco::AbstractObserver& observer);
  149. /// Registers an event handler with the SocketReactor.
  150. ///
  151. /// Usage:
  152. /// Poco::Observer<MyEventHandler, SocketNotification> obs(*this, &MyEventHandler::handleMyEvent);
  153. /// reactor.addEventHandler(obs);
  154. void removeEventHandler(const Socket& socket, const Poco::AbstractObserver& observer);
  155. /// Unregisters an event handler with the SocketReactor.
  156. ///
  157. /// Usage:
  158. /// Poco::Observer<MyEventHandler, SocketNotification> obs(*this, &MyEventHandler::handleMyEvent);
  159. /// reactor.removeEventHandler(obs);
  160. protected:
  161. virtual void onTimeout();
  162. /// Called if the timeout expires and no other events are available.
  163. ///
  164. /// Can be overridden by subclasses. The default implementation
  165. /// dispatches the TimeoutNotification and thus should be called by overriding
  166. /// implementations.
  167. virtual void onIdle();
  168. /// Called if no sockets are available to call select() on.
  169. ///
  170. /// Can be overridden by subclasses. The default implementation
  171. /// dispatches the IdleNotification and thus should be called by overriding
  172. /// implementations.
  173. virtual void onShutdown();
  174. /// Called when the SocketReactor is about to terminate.
  175. ///
  176. /// Can be overridden by subclasses. The default implementation
  177. /// dispatches the ShutdownNotification and thus should be called by overriding
  178. /// implementations.
  179. void dispatch(const Socket& socket, SocketNotification* pNotification);
  180. /// Dispatches the given notification to all observers
  181. /// registered for the given socket.
  182. void dispatch(SocketNotification* pNotification);
  183. /// Dispatches the given notification to all observers.
  184. private:
  185. typedef Poco::AutoPtr<SocketNotifier> NotifierPtr;
  186. typedef Poco::AutoPtr<SocketNotification> NotificationPtr;
  187. typedef std::map<Socket, NotifierPtr> EventHandlerMap;
  188. void dispatch(NotifierPtr& pNotifier, SocketNotification* pNotification);
  189. enum
  190. {
  191. DEFAULT_TIMEOUT = 250000
  192. };
  193. bool _stop;
  194. Poco::Timespan _timeout;
  195. EventHandlerMap _handlers;
  196. NotificationPtr _pReadableNotification;
  197. NotificationPtr _pWritableNotification;
  198. NotificationPtr _pErrorNotification;
  199. NotificationPtr _pTimeoutNotification;
  200. NotificationPtr _pIdleNotification;
  201. NotificationPtr _pShutdownNotification;
  202. Poco::FastMutex _mutex;
  203. friend class SocketNotifier;
  204. };
  205. } } // namespace Poco::Net
  206. #endif // Net_SocketReactor_INCLUDED