4
// $Id: //poco/1.2/Net/include/Poco/Net/SocketReactor.h#2 $
8
// Module: SocketReactor
10
// Definition of the SocketReactor class.
12
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
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:
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.
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.
39
#ifndef Net_SocketReactor_INCLUDED
40
#define Net_SocketReactor_INCLUDED
43
#include "Poco/Net/Net.h"
44
#include "Poco/Net/Socket.h"
45
#include "Poco/Runnable.h"
46
#include "Poco/Timespan.h"
47
#include "Poco/Observer.h"
48
#include "Poco/AutoPtr.h"
57
class SocketNotification;
61
class Net_API SocketReactor: public Poco::Runnable
62
/// This class, which is part of the Reactor pattern,
63
/// implements the "Initiation Dispatcher".
65
/// The Reactor pattern has been described in the book
66
/// "Pattern Languages of Program Design" by Jim Coplien
67
/// and Douglas C. Schmidt (Addison Wesley, 1995).
69
/// The Reactor design pattern handles service requests that
70
/// are delivered concurrently to an application by one or more
71
/// clients. Each service in an application may consist of several
72
/// methods and is represented by a separate event handler. The event
73
/// handler is responsible for servicing service-specific requests.
74
/// The SocketReactor dispatches the event handlers.
76
/// Event handlers (any class can be an event handler - there
77
/// is no base class for event handlers) can be registered
78
/// with the addEventHandler() method and deregistered with
79
/// the removeEventHandler() method.
81
/// An event handler is always registered for a certain socket,
82
/// which is given in the call to addEventHandler(). Any method
83
/// of the event handler class can be registered to handle the
84
/// event - the only requirement is that the method takes
85
/// a pointer to an instance of SocketNotification (or a subclass of it)
88
/// Once started, the SocketReactor waits for events
89
/// on the registered sockets, using Socket::select().
90
/// If an event is detected, the corresponding event handler
91
/// is invoked. There are five event types (and corresponding
92
/// notification classes) defined: ReadableNotification, WritableNotification,
93
/// ErrorNotification, TimeoutNotification and ShutdownNotification.
95
/// The ReadableNotification will be dispatched if a socket becomes
96
/// readable. The WritableNotification will be dispatched if a socket
97
/// becomes writable. The ErrorNotification will be dispatched if
98
/// there is an error condition on a socket.
100
/// If the timeout expires and no event has occured, a
101
/// TimeoutNotification will be dispatched to all event handlers
102
/// registered for it. This is done in the onTimeout() method
103
/// which can be overridded by subclasses to perform custom
104
/// timeout processing.
106
/// Finally, when the SocketReactor is about to shut down (as a result
107
/// of stop() being called), it dispatches a ShutdownNotification
108
/// to all event handlers. This is done in the onShutdown() method
109
/// which can be overridded by subclasses to perform custom
110
/// shutdown processing.
112
/// The SocketReactor is implemented so that it can
113
/// run in its own thread. It is also possible to run
114
/// multiple SocketReactors in parallel, as long as
115
/// they work on different sockets.
117
/// It is safe to call addEventHandler() and removeEventHandler()
118
/// from another thread while the SocketReactor is running. Also,
119
/// it is safe to call addEventHandler() and removeEventHandler()
120
/// from event handlers.
124
/// Creates the SocketReactor.
126
SocketReactor(const Poco::Timespan& timeout);
127
/// Creates the SocketReactor, using the given timeout.
129
virtual ~SocketReactor();
130
/// Destroys the SocketReactor.
133
/// Runs the SocketReactor. The reactor will run
134
/// until stop() is called (in a separate thread).
137
/// Stops the SocketReactor.
139
/// The reactor will be stopped when the next event
140
/// (including a timeout event) occurs.
142
void setTimeout(const Poco::Timespan& timeout);
143
/// Sets the timeout.
145
/// If no other event occurs for the given timeout
146
/// interval, a timeout event is sent to all event listeners.
148
/// The default timeout is 250 milliseconds;
150
/// The timeout is passed to the Socket::select()
153
const Poco::Timespan& getTimeout() const;
154
/// Returns the timeout.
156
void addEventHandler(const Socket& socket, const Poco::AbstractObserver& observer);
157
/// Registers an event handler with the SocketReactor.
160
/// Poco::Observer<MyEventHandler, SocketNotification> obs(*this, &MyEventHandler::handleMyEvent);
161
/// reactor.addEventHandler(obs);
163
void removeEventHandler(const Socket& socket, const Poco::AbstractObserver& observer);
164
/// Unregisters an event handler with the SocketReactor.
167
/// Poco::Observer<MyEventHandler, SocketNotification> obs(*this, &MyEventHandler::handleMyEvent);
168
/// reactor.removeEventHandler(obs);
171
virtual void onTimeout();
172
/// Called if the timeout expires and no other events are available.
174
/// Can be overridden by subclasses. The default implementation
175
/// dispatches the TimeoutNotification and thus should be called by overriding
178
virtual void onShutdown();
179
/// Called when the SocketReactor is about to terminate.
181
/// Can be overridden by subclasses. The default implementation
182
/// dispatches the ShutdownNotification and thus should be called by overriding
185
void dispatch(const Socket& socket, SocketNotification* pNotification);
186
/// Dispatches the given notification to all observers
187
/// registered for the given socket.
189
void dispatch(SocketNotification* pNotification);
190
/// Dispatches the given notification to all observers.
193
typedef Poco::AutoPtr<SocketNotifier> NotifierPtr;
194
typedef Poco::AutoPtr<SocketNotification> NotificationPtr;
195
typedef std::map<Socket, NotifierPtr> EventHandlerMap;
197
void dispatch(NotifierPtr& pNotifier, SocketNotification* pNotification);
201
DEFAULT_TIMEOUT = 250000
205
Poco::Timespan _timeout;
206
EventHandlerMap _handlers;
207
NotificationPtr _pReadableNotification;
208
NotificationPtr _pWritableNotification;
209
NotificationPtr _pErrorNotification;
210
NotificationPtr _pTimeoutNotification;
211
NotificationPtr _pShutdownNotification;
212
Poco::FastMutex _mutex;
214
friend class SocketNotifier;
218
} } // namespace Poco::Net
221
#endif // Net_SocketReactor_INCLUDED