root / trunk / Windows / libs / poco / include / Poco / Net / SocketReactor.h @ 3

View | Annotate | Download (8.6 KB)

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