PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/poco/include/Poco/Net/SocketReactor.h

http://github.com/openframeworks/openFrameworks
C Header | 237 lines | 60 code | 39 blank | 138 comment | 0 complexity | ca3c5751c5833e4cb628223ffc60bb58 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, GPL-2.0, GPL-3.0, BSD-3-Clause
  1. //
  2. // SocketReactor.h
  3. //
  4. // $Id: //poco/1.4/Net/include/Poco/Net/SocketReactor.h#1 $
  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. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Net_SocketReactor_INCLUDED
  18. #define Net_SocketReactor_INCLUDED
  19. #include "Poco/Net/Net.h"
  20. #include "Poco/Net/Socket.h"
  21. #include "Poco/Runnable.h"
  22. #include "Poco/Timespan.h"
  23. #include "Poco/Observer.h"
  24. #include "Poco/AutoPtr.h"
  25. #include <map>
  26. namespace Poco {
  27. class Thread;
  28. namespace Net {
  29. class Socket;
  30. class SocketNotification;
  31. class SocketNotifier;
  32. class Net_API SocketReactor: public Poco::Runnable
  33. /// This class, which is part of the Reactor pattern,
  34. /// implements the "Initiation Dispatcher".
  35. ///
  36. /// The Reactor pattern has been described in the book
  37. /// "Pattern Languages of Program Design" by Jim Coplien
  38. /// and Douglas C. Schmidt (Addison Wesley, 1995).
  39. ///
  40. /// The Reactor design pattern handles service requests that
  41. /// are delivered concurrently to an application by one or more
  42. /// clients. Each service in an application may consist of several
  43. /// methods and is represented by a separate event handler. The event
  44. /// handler is responsible for servicing service-specific requests.
  45. /// The SocketReactor dispatches the event handlers.
  46. ///
  47. /// Event handlers (any class can be an event handler - there
  48. /// is no base class for event handlers) can be registered
  49. /// with the addEventHandler() method and deregistered with
  50. /// the removeEventHandler() method.
  51. ///
  52. /// An event handler is always registered for a certain socket,
  53. /// which is given in the call to addEventHandler(). Any method
  54. /// of the event handler class can be registered to handle the
  55. /// event - the only requirement is that the method takes
  56. /// a pointer to an instance of SocketNotification (or a subclass of it)
  57. /// as argument.
  58. ///
  59. /// Once started, the SocketReactor waits for events
  60. /// on the registered sockets, using Socket::select().
  61. /// If an event is detected, the corresponding event handler
  62. /// is invoked. There are five event types (and corresponding
  63. /// notification classes) defined: ReadableNotification, WritableNotification,
  64. /// ErrorNotification, TimeoutNotification, IdleNotification and
  65. /// ShutdownNotification.
  66. ///
  67. /// The ReadableNotification will be dispatched if a socket becomes
  68. /// readable. The WritableNotification will be dispatched if a socket
  69. /// becomes writable. The ErrorNotification will be dispatched if
  70. /// there is an error condition on a socket.
  71. ///
  72. /// If the timeout expires and no event has occured, a
  73. /// TimeoutNotification will be dispatched to all event handlers
  74. /// registered for it. This is done in the onTimeout() method
  75. /// which can be overridden by subclasses to perform custom
  76. /// timeout processing.
  77. ///
  78. /// If there are no sockets for the SocketReactor to pass to
  79. /// Socket::select(), an IdleNotification will be dispatched to
  80. /// all event handlers registered for it. This is done in the
  81. /// onIdle() method which can be overridden by subclasses
  82. /// to perform custom idle processing. Since onIdle() will be
  83. /// called repeatedly in a loop, it is recommended to do a
  84. /// short sleep or yield in the event handler.
  85. ///
  86. /// Finally, when the SocketReactor is about to shut down (as a result
  87. /// of stop() being called), it dispatches a ShutdownNotification
  88. /// to all event handlers. This is done in the onShutdown() method
  89. /// which can be overridded by subclasses to perform custom
  90. /// shutdown processing.
  91. ///
  92. /// The SocketReactor is implemented so that it can
  93. /// run in its own thread. It is also possible to run
  94. /// multiple SocketReactors in parallel, as long as
  95. /// they work on different sockets.
  96. ///
  97. /// It is safe to call addEventHandler() and removeEventHandler()
  98. /// from another thread while the SocketReactor is running. Also,
  99. /// it is safe to call addEventHandler() and removeEventHandler()
  100. /// from event handlers.
  101. {
  102. public:
  103. SocketReactor();
  104. /// Creates the SocketReactor.
  105. explicit SocketReactor(const Poco::Timespan& timeout);
  106. /// Creates the SocketReactor, using the given timeout.
  107. virtual ~SocketReactor();
  108. /// Destroys the SocketReactor.
  109. void run();
  110. /// Runs the SocketReactor. The reactor will run
  111. /// until stop() is called (in a separate thread).
  112. void stop();
  113. /// Stops the SocketReactor.
  114. ///
  115. /// The reactor will be stopped when the next event
  116. /// (including a timeout event) occurs.
  117. void wakeUp();
  118. /// Wakes up idle reactor.
  119. void setTimeout(const Poco::Timespan& timeout);
  120. /// Sets the timeout.
  121. ///
  122. /// If no other event occurs for the given timeout
  123. /// interval, a timeout event is sent to all event listeners.
  124. ///
  125. /// The default timeout is 250 milliseconds;
  126. ///
  127. /// The timeout is passed to the Socket::select()
  128. /// method.
  129. const Poco::Timespan& getTimeout() const;
  130. /// Returns the timeout.
  131. void addEventHandler(const Socket& socket, const Poco::AbstractObserver& observer);
  132. /// Registers an event handler with the SocketReactor.
  133. ///
  134. /// Usage:
  135. /// Poco::Observer<MyEventHandler, SocketNotification> obs(*this, &MyEventHandler::handleMyEvent);
  136. /// reactor.addEventHandler(obs);
  137. bool hasEventHandler(const Socket& socket, const Poco::AbstractObserver& observer);
  138. /// Returns true if the observer is reistered with SocketReactor for the given socket.
  139. void removeEventHandler(const Socket& socket, const Poco::AbstractObserver& observer);
  140. /// Unregisters an event handler with the SocketReactor.
  141. ///
  142. /// Usage:
  143. /// Poco::Observer<MyEventHandler, SocketNotification> obs(*this, &MyEventHandler::handleMyEvent);
  144. /// reactor.removeEventHandler(obs);
  145. protected:
  146. virtual void onTimeout();
  147. /// Called if the timeout expires and no other events are available.
  148. ///
  149. /// Can be overridden by subclasses. The default implementation
  150. /// dispatches the TimeoutNotification and thus should be called by overriding
  151. /// implementations.
  152. virtual void onIdle();
  153. /// Called if no sockets are available to call select() on.
  154. ///
  155. /// Can be overridden by subclasses. The default implementation
  156. /// dispatches the IdleNotification and thus should be called by overriding
  157. /// implementations.
  158. virtual void onShutdown();
  159. /// Called when the SocketReactor is about to terminate.
  160. ///
  161. /// Can be overridden by subclasses. The default implementation
  162. /// dispatches the ShutdownNotification and thus should be called by overriding
  163. /// implementations.
  164. virtual void onBusy();
  165. /// Called when the SocketReactor is busy and at least one notification
  166. /// has been dispatched.
  167. ///
  168. /// Can be overridden by subclasses to perform additional
  169. /// periodic tasks. The default implementation does nothing.
  170. void dispatch(const Socket& socket, SocketNotification* pNotification);
  171. /// Dispatches the given notification to all observers
  172. /// registered for the given socket.
  173. void dispatch(SocketNotification* pNotification);
  174. /// Dispatches the given notification to all observers.
  175. private:
  176. typedef Poco::AutoPtr<SocketNotifier> NotifierPtr;
  177. typedef Poco::AutoPtr<SocketNotification> NotificationPtr;
  178. typedef std::map<Socket, NotifierPtr> EventHandlerMap;
  179. void dispatch(NotifierPtr& pNotifier, SocketNotification* pNotification);
  180. enum
  181. {
  182. DEFAULT_TIMEOUT = 250000
  183. };
  184. bool _stop;
  185. Poco::Timespan _timeout;
  186. EventHandlerMap _handlers;
  187. NotificationPtr _pReadableNotification;
  188. NotificationPtr _pWritableNotification;
  189. NotificationPtr _pErrorNotification;
  190. NotificationPtr _pTimeoutNotification;
  191. NotificationPtr _pIdleNotification;
  192. NotificationPtr _pShutdownNotification;
  193. Poco::FastMutex _mutex;
  194. Poco::Thread* _pThread;
  195. friend class SocketNotifier;
  196. };
  197. } } // namespace Poco::Net
  198. #endif // Net_SocketReactor_INCLUDED