forked from pocoproject/poco
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParallelSocketAcceptor.h
More file actions
executable file
·181 lines (153 loc) · 4.82 KB
/
ParallelSocketAcceptor.h
File metadata and controls
executable file
·181 lines (153 loc) · 4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//
// ParallelSocketAcceptor.h
//
// $Id: //poco/1.4/Net/include/Poco/Net/ParallelSocketAcceptor.h#1 $
//
// Library: Net
// Package: Reactor
// Module: ParallelSocketAcceptor
//
// Definition of the ParallelSocketAcceptor class.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Net_ParallelSocketAcceptor_INCLUDED
#define Net_ParallelSocketAcceptor_INCLUDED
#include "Poco/Net/ParallelSocketReactor.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Environment.h"
#include "Poco/NObserver.h"
#include "Poco/SharedPtr.h"
#include <vector>
using Poco::Net::Socket;
using Poco::Net::SocketReactor;
using Poco::Net::ServerSocket;
using Poco::Net::StreamSocket;
using Poco::NObserver;
using Poco::AutoPtr;
namespace Poco {
namespace Net {
template <class ServiceHandler, class SR>
class ParallelSocketAcceptor
/// This class implements the Acceptor part of the Acceptor-Connector design pattern.
/// Only the difference from single-threaded version is documented here, For full
/// description see Poco::Net::SocketAcceptor documentation.
///
/// This is a multi-threaded version of SocketAcceptor, it differs from the
/// single-threaded version in number of reactors (defaulting to number of processors)
/// that can be specified at construction time and is rotated in a round-robin fashion
/// by event handler. See ParallelSocketAcceptor::onAccept and
/// ParallelSocketAcceptor::createServiceHandler documentation and implementation for
/// details.
{
public:
typedef Poco::Net::ParallelSocketReactor<SR> ParallelReactor;
explicit ParallelSocketAcceptor(ServerSocket& socket,
unsigned threads = Poco::Environment::processorCount()):
_socket(socket),
_pReactor(0),
_threads(threads),
_next(0)
/// Creates a ParallelSocketAcceptor using the given ServerSocket,
/// sets number of threads and populates the reactors vector.
{
init();
}
ParallelSocketAcceptor(ServerSocket& socket,
SocketReactor& reactor,
unsigned threads = Poco::Environment::processorCount()):
_socket(socket),
_pReactor(0),
_threads(threads),
_next(0)
/// Creates a ParallelSocketAcceptor using the given ServerSocket, sets the
/// number of threads, populates the reactors vector and registers itself
/// with the given SocketReactor.
{
init();
registerAcceptor(reactor);
}
virtual ~ParallelSocketAcceptor()
/// Destroys the ParallelSocketAcceptor.
{
unregisterAcceptor();
}
virtual void registerAcceptor(SocketReactor& reactor)
/// Registers the ParallelSocketAcceptor with a SocketReactor.
///
/// A subclass can override this and, for example, also register
/// an event handler for a timeout event.
///
/// The overriding method must call the baseclass implementation first.
{
_pReactor = &reactor;
_pReactor->addEventHandler(_socket,
Poco::Observer<ParallelSocketAcceptor,
ReadableNotification>(*this, &ParallelSocketAcceptor::onAccept));
}
virtual void unregisterAcceptor()
/// Unregisters the ParallelSocketAcceptor.
///
/// A subclass can override this and, for example, also unregister
/// its event handler for a timeout event.
///
/// The overriding method must call the baseclass implementation first.
{
_pReactor->removeEventHandler(_socket,
Poco::Observer<ParallelSocketAcceptor,
ReadableNotification>(*this, &ParallelSocketAcceptor::onAccept));
}
void onAccept(ReadableNotification* pNotification)
/// Accepts connection and creates event handler.
{
pNotification->release();
StreamSocket sock = _socket.acceptConnection();
createServiceHandler(sock);
}
protected:
virtual ServiceHandler* createServiceHandler(StreamSocket& socket)
/// Create and initialize a new ServiceHandler instance.
///
/// Subclasses can override this method.
{
std::size_t next = _next++;
if (_next == _reactors.size()) _next = 0;
return new ServiceHandler(socket, *_reactors[next]);
}
SocketReactor* reactor()
/// Returns a pointer to the SocketReactor where
/// this SocketAcceptor is registered.
///
/// The pointer may be null.
{
return _pReactor;
}
Socket& socket()
/// Returns a reference to the SocketAcceptor's socket.
{
return _socket;
}
void init()
/// Populates the reactors vector.
{
poco_assert (_threads > 0);
for (unsigned i = 0; i < _threads; ++i)
_reactors.push_back(new ParallelReactor);
}
private:
typedef std::vector<typename ParallelReactor::Ptr> ReactorVec;
ParallelSocketAcceptor();
ParallelSocketAcceptor(const ParallelSocketAcceptor&);
ParallelSocketAcceptor& operator = (const ParallelSocketAcceptor&);
ServerSocket _socket;
SocketReactor* _pReactor;
unsigned _threads;
ReactorVec _reactors;
std::size_t _next;
};
} } // namespace Poco::Net
#endif // Net_ParallelSocketAcceptor_INCLUDED