quickfix_ruby 1.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/quickfix/Acceptor.cpp +248 -0
- data/ext/quickfix/Acceptor.h +127 -0
- data/ext/quickfix/Allocator.h +9 -0
- data/ext/quickfix/Application.h +127 -0
- data/ext/quickfix/AtomicCount.h +109 -0
- data/ext/quickfix/DOMDocument.h +74 -0
- data/ext/quickfix/DataDictionary.cpp +618 -0
- data/ext/quickfix/DataDictionary.h +539 -0
- data/ext/quickfix/DataDictionaryProvider.cpp +71 -0
- data/ext/quickfix/DataDictionaryProvider.h +70 -0
- data/ext/quickfix/DatabaseConnectionID.h +105 -0
- data/ext/quickfix/DatabaseConnectionPool.h +91 -0
- data/ext/quickfix/Dictionary.cpp +162 -0
- data/ext/quickfix/Dictionary.h +94 -0
- data/ext/quickfix/Event.h +95 -0
- data/ext/quickfix/Exceptions.h +299 -0
- data/ext/quickfix/Field.h +672 -0
- data/ext/quickfix/FieldConvertors.h +863 -0
- data/ext/quickfix/FieldMap.cpp +238 -0
- data/ext/quickfix/FieldMap.h +244 -0
- data/ext/quickfix/FieldNumbers.h +46 -0
- data/ext/quickfix/FieldTypes.cpp +64 -0
- data/ext/quickfix/FieldTypes.h +698 -0
- data/ext/quickfix/Fields.h +31 -0
- data/ext/quickfix/FileLog.cpp +200 -0
- data/ext/quickfix/FileLog.h +112 -0
- data/ext/quickfix/FileStore.cpp +332 -0
- data/ext/quickfix/FileStore.h +129 -0
- data/ext/quickfix/FixFieldNumbers.h +1537 -0
- data/ext/quickfix/FixFields.h +1538 -0
- data/ext/quickfix/FixValues.h +3281 -0
- data/ext/quickfix/FlexLexer.h +188 -0
- data/ext/quickfix/Group.cpp +64 -0
- data/ext/quickfix/Group.h +73 -0
- data/ext/quickfix/HtmlBuilder.h +186 -0
- data/ext/quickfix/HttpConnection.cpp +739 -0
- data/ext/quickfix/HttpConnection.h +78 -0
- data/ext/quickfix/HttpMessage.cpp +149 -0
- data/ext/quickfix/HttpMessage.h +133 -0
- data/ext/quickfix/HttpParser.cpp +49 -0
- data/ext/quickfix/HttpParser.h +54 -0
- data/ext/quickfix/HttpServer.cpp +169 -0
- data/ext/quickfix/HttpServer.h +78 -0
- data/ext/quickfix/Initiator.cpp +289 -0
- data/ext/quickfix/Initiator.h +149 -0
- data/ext/quickfix/Log.cpp +77 -0
- data/ext/quickfix/Log.h +179 -0
- data/ext/quickfix/Message.cpp +580 -0
- data/ext/quickfix/Message.h +370 -0
- data/ext/quickfix/MessageCracker.h +188 -0
- data/ext/quickfix/MessageSorters.cpp +105 -0
- data/ext/quickfix/MessageSorters.h +156 -0
- data/ext/quickfix/MessageStore.cpp +146 -0
- data/ext/quickfix/MessageStore.h +174 -0
- data/ext/quickfix/Mutex.h +131 -0
- data/ext/quickfix/MySQLConnection.h +194 -0
- data/ext/quickfix/MySQLLog.cpp +275 -0
- data/ext/quickfix/MySQLLog.h +145 -0
- data/ext/quickfix/MySQLStore.cpp +331 -0
- data/ext/quickfix/MySQLStore.h +142 -0
- data/ext/quickfix/NullStore.cpp +54 -0
- data/ext/quickfix/NullStore.h +99 -0
- data/ext/quickfix/OdbcConnection.h +266 -0
- data/ext/quickfix/OdbcLog.cpp +252 -0
- data/ext/quickfix/OdbcLog.h +117 -0
- data/ext/quickfix/OdbcStore.cpp +338 -0
- data/ext/quickfix/OdbcStore.h +113 -0
- data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
- data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
- data/ext/quickfix/Parser.cpp +103 -0
- data/ext/quickfix/Parser.h +57 -0
- data/ext/quickfix/PostgreSQLConnection.h +176 -0
- data/ext/quickfix/PostgreSQLLog.cpp +276 -0
- data/ext/quickfix/PostgreSQLLog.h +144 -0
- data/ext/quickfix/PostgreSQLStore.cpp +334 -0
- data/ext/quickfix/PostgreSQLStore.h +141 -0
- data/ext/quickfix/Queue.h +75 -0
- data/ext/quickfix/QuickfixRuby.cpp +252066 -0
- data/ext/quickfix/QuickfixRuby.h +34 -0
- data/ext/quickfix/Responder.h +43 -0
- data/ext/quickfix/Session.cpp +1487 -0
- data/ext/quickfix/Session.h +335 -0
- data/ext/quickfix/SessionFactory.cpp +274 -0
- data/ext/quickfix/SessionFactory.h +86 -0
- data/ext/quickfix/SessionID.h +170 -0
- data/ext/quickfix/SessionSettings.cpp +189 -0
- data/ext/quickfix/SessionSettings.h +171 -0
- data/ext/quickfix/SessionState.h +231 -0
- data/ext/quickfix/Settings.cpp +100 -0
- data/ext/quickfix/Settings.h +53 -0
- data/ext/quickfix/SharedArray.h +150 -0
- data/ext/quickfix/SocketAcceptor.cpp +222 -0
- data/ext/quickfix/SocketAcceptor.h +75 -0
- data/ext/quickfix/SocketConnection.cpp +238 -0
- data/ext/quickfix/SocketConnection.h +103 -0
- data/ext/quickfix/SocketConnector.cpp +116 -0
- data/ext/quickfix/SocketConnector.h +67 -0
- data/ext/quickfix/SocketInitiator.cpp +260 -0
- data/ext/quickfix/SocketInitiator.h +81 -0
- data/ext/quickfix/SocketMonitor.cpp +335 -0
- data/ext/quickfix/SocketMonitor.h +111 -0
- data/ext/quickfix/SocketServer.cpp +177 -0
- data/ext/quickfix/SocketServer.h +100 -0
- data/ext/quickfix/ThreadedSocketAcceptor.cpp +258 -0
- data/ext/quickfix/ThreadedSocketAcceptor.h +98 -0
- data/ext/quickfix/ThreadedSocketConnection.cpp +209 -0
- data/ext/quickfix/ThreadedSocketConnection.h +82 -0
- data/ext/quickfix/ThreadedSocketInitiator.cpp +268 -0
- data/ext/quickfix/ThreadedSocketInitiator.h +84 -0
- data/ext/quickfix/TimeRange.cpp +173 -0
- data/ext/quickfix/TimeRange.h +258 -0
- data/ext/quickfix/Utility.cpp +537 -0
- data/ext/quickfix/Utility.h +219 -0
- data/ext/quickfix/Values.h +62 -0
- data/ext/quickfix/config.h +0 -0
- data/ext/quickfix/config_windows.h +0 -0
- data/ext/quickfix/extconf.rb +12 -0
- data/ext/quickfix/index.h +37 -0
- data/ext/quickfix/pugiconfig.hpp +72 -0
- data/ext/quickfix/pugixml.cpp +10765 -0
- data/ext/quickfix/pugixml.hpp +1341 -0
- data/ext/quickfix/strptime.h +7 -0
- data/lib/quickfix40.rb +274 -0
- data/lib/quickfix41.rb +351 -0
- data/lib/quickfix42.rb +1184 -0
- data/lib/quickfix43.rb +3504 -0
- data/lib/quickfix44.rb +10721 -0
- data/lib/quickfix50.rb +13426 -0
- data/lib/quickfix50sp1.rb +15629 -0
- data/lib/quickfix50sp2.rb +17068 -0
- data/lib/quickfix_fields.rb +19853 -0
- data/lib/quickfix_ruby.rb +82 -0
- data/lib/quickfixt11.rb +70 -0
- data/spec/FIX40.xml +862 -0
- data/spec/FIX41.xml +1285 -0
- data/spec/FIX42.xml +2746 -0
- data/spec/FIX43.xml +4229 -0
- data/spec/FIX44.xml +6596 -0
- data/spec/FIX50.xml +8137 -0
- data/spec/FIX50SP1.xml +9496 -0
- data/spec/FIX50SP2.xml +10011 -0
- data/spec/FIXT11.xml +313 -0
- data/test/test_DataDictionaryTestCase.rb +268 -0
- data/test/test_DictionaryTestCase.rb +112 -0
- data/test/test_FieldBaseTestCase.rb +24 -0
- data/test/test_MessageTestCase.rb +368 -0
- data/test/test_SessionSettingsTestCase.rb +41 -0
- metadata +193 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/****************************************************************************
|
|
2
|
+
** Copyright (c) 2001-2014
|
|
3
|
+
**
|
|
4
|
+
** This file is part of the QuickFIX FIX Engine
|
|
5
|
+
**
|
|
6
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
7
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
8
|
+
** LICENSE included in the packaging of this file.
|
|
9
|
+
**
|
|
10
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
11
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
12
|
+
**
|
|
13
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
14
|
+
**
|
|
15
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
16
|
+
** not clear to you.
|
|
17
|
+
**
|
|
18
|
+
****************************************************************************/
|
|
19
|
+
|
|
20
|
+
#ifdef _MSC_VER
|
|
21
|
+
#include "stdafx.h"
|
|
22
|
+
#else
|
|
23
|
+
#include "config.h"
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
#include "SocketMonitor.h"
|
|
27
|
+
#include "Utility.h"
|
|
28
|
+
#include <exception>
|
|
29
|
+
#include <set>
|
|
30
|
+
#include <algorithm>
|
|
31
|
+
#include <iostream>
|
|
32
|
+
|
|
33
|
+
namespace FIX
|
|
34
|
+
{
|
|
35
|
+
SocketMonitor::SocketMonitor( int timeout )
|
|
36
|
+
: m_timeout( timeout )
|
|
37
|
+
{
|
|
38
|
+
socket_init();
|
|
39
|
+
|
|
40
|
+
std::pair<int, int> sockets = socket_createpair();
|
|
41
|
+
m_signal = sockets.first;
|
|
42
|
+
m_interrupt = sockets.second;
|
|
43
|
+
socket_setnonblock( m_signal );
|
|
44
|
+
socket_setnonblock( m_interrupt );
|
|
45
|
+
m_readSockets.insert( m_interrupt );
|
|
46
|
+
|
|
47
|
+
m_timeval.tv_sec = 0;
|
|
48
|
+
m_timeval.tv_usec = 0;
|
|
49
|
+
#ifndef SELECT_DECREMENTS_TIME
|
|
50
|
+
m_ticks = clock();
|
|
51
|
+
#endif
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
SocketMonitor::~SocketMonitor()
|
|
55
|
+
{
|
|
56
|
+
Sockets::iterator i;
|
|
57
|
+
for ( i = m_readSockets.begin(); i != m_readSockets.end(); ++i ) {
|
|
58
|
+
socket_close( *i );
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
socket_close( m_signal );
|
|
62
|
+
socket_term();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
bool SocketMonitor::addConnect( int s )
|
|
66
|
+
{
|
|
67
|
+
socket_setnonblock( s );
|
|
68
|
+
Sockets::iterator i = m_connectSockets.find( s );
|
|
69
|
+
if( i != m_connectSockets.end() ) return false;
|
|
70
|
+
|
|
71
|
+
m_connectSockets.insert( s );
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
bool SocketMonitor::addRead( int s )
|
|
76
|
+
{
|
|
77
|
+
socket_setnonblock( s );
|
|
78
|
+
Sockets::iterator i = m_readSockets.find( s );
|
|
79
|
+
if( i != m_readSockets.end() ) return false;
|
|
80
|
+
|
|
81
|
+
m_readSockets.insert( s );
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
bool SocketMonitor::addWrite( int s )
|
|
86
|
+
{
|
|
87
|
+
if( m_readSockets.find(s) == m_readSockets.end() )
|
|
88
|
+
return false;
|
|
89
|
+
|
|
90
|
+
socket_setnonblock( s );
|
|
91
|
+
Sockets::iterator i = m_writeSockets.find( s );
|
|
92
|
+
if( i != m_writeSockets.end() ) return false;
|
|
93
|
+
|
|
94
|
+
m_writeSockets.insert( s );
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
bool SocketMonitor::drop( int s )
|
|
99
|
+
{
|
|
100
|
+
Sockets::iterator i = m_readSockets.find( s );
|
|
101
|
+
Sockets::iterator j = m_writeSockets.find( s );
|
|
102
|
+
Sockets::iterator k = m_connectSockets.find( s );
|
|
103
|
+
|
|
104
|
+
if ( i != m_readSockets.end() ||
|
|
105
|
+
j != m_writeSockets.end() ||
|
|
106
|
+
k != m_connectSockets.end() )
|
|
107
|
+
{
|
|
108
|
+
socket_close( s );
|
|
109
|
+
m_readSockets.erase( s );
|
|
110
|
+
m_writeSockets.erase( s );
|
|
111
|
+
m_connectSockets.erase( s );
|
|
112
|
+
m_dropped.push( s );
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
inline timeval* SocketMonitor::getTimeval( bool poll, double timeout )
|
|
119
|
+
{
|
|
120
|
+
if ( poll )
|
|
121
|
+
{
|
|
122
|
+
m_timeval.tv_sec = 0;
|
|
123
|
+
m_timeval.tv_usec = 0;
|
|
124
|
+
return &m_timeval;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
timeout = m_timeout;
|
|
128
|
+
|
|
129
|
+
if ( !timeout )
|
|
130
|
+
return 0;
|
|
131
|
+
#ifdef SELECT_MODIFIES_TIMEVAL
|
|
132
|
+
if ( !m_timeval.tv_sec && !m_timeval.tv_usec && timeout )
|
|
133
|
+
m_timeval.tv_sec = timeout;
|
|
134
|
+
return &m_timeval;
|
|
135
|
+
#else
|
|
136
|
+
double elapsed = ( double ) ( clock() - m_ticks ) / ( double ) CLOCKS_PER_SEC;
|
|
137
|
+
if ( elapsed >= timeout || elapsed == 0.0 )
|
|
138
|
+
{
|
|
139
|
+
m_ticks = clock();
|
|
140
|
+
m_timeval.tv_sec = 0;
|
|
141
|
+
m_timeval.tv_usec = (timeout * 1000000);
|
|
142
|
+
}
|
|
143
|
+
else
|
|
144
|
+
{
|
|
145
|
+
m_timeval.tv_sec = 0;
|
|
146
|
+
m_timeval.tv_usec = ( ( timeout - elapsed ) * 1000000 );
|
|
147
|
+
}
|
|
148
|
+
return &m_timeval;
|
|
149
|
+
#endif
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
bool SocketMonitor::sleepIfEmpty( bool poll )
|
|
153
|
+
{
|
|
154
|
+
if( poll )
|
|
155
|
+
return false;
|
|
156
|
+
|
|
157
|
+
if ( m_readSockets.empty() &&
|
|
158
|
+
m_writeSockets.empty() &&
|
|
159
|
+
m_connectSockets.empty() )
|
|
160
|
+
{
|
|
161
|
+
process_sleep( m_timeout );
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
else
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
void SocketMonitor::signal( int socket )
|
|
169
|
+
{
|
|
170
|
+
socket_send( m_signal, (char*)&socket, sizeof(socket) );
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
void SocketMonitor::unsignal( int s )
|
|
174
|
+
{
|
|
175
|
+
Sockets::iterator i = m_writeSockets.find( s );
|
|
176
|
+
if( i == m_writeSockets.end() ) return;
|
|
177
|
+
|
|
178
|
+
m_writeSockets.erase( s );
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
void SocketMonitor::block( Strategy& strategy, bool poll, double timeout )
|
|
182
|
+
{
|
|
183
|
+
while ( m_dropped.size() )
|
|
184
|
+
{
|
|
185
|
+
strategy.onError( *this, m_dropped.front() );
|
|
186
|
+
m_dropped.pop();
|
|
187
|
+
if ( m_dropped.size() == 0 )
|
|
188
|
+
return ;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
fd_set readSet;
|
|
192
|
+
FD_ZERO( &readSet );
|
|
193
|
+
buildSet( m_readSockets, readSet );
|
|
194
|
+
fd_set writeSet;
|
|
195
|
+
FD_ZERO( &writeSet );
|
|
196
|
+
buildSet( m_connectSockets, writeSet );
|
|
197
|
+
buildSet( m_writeSockets, writeSet );
|
|
198
|
+
fd_set exceptSet;
|
|
199
|
+
FD_ZERO( &exceptSet );
|
|
200
|
+
buildSet( m_connectSockets, exceptSet );
|
|
201
|
+
|
|
202
|
+
if ( sleepIfEmpty(poll) )
|
|
203
|
+
{
|
|
204
|
+
strategy.onTimeout( *this );
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
int result = select( FD_SETSIZE, &readSet, &writeSet, &exceptSet, getTimeval(poll, timeout) );
|
|
209
|
+
|
|
210
|
+
if ( result == 0 )
|
|
211
|
+
{
|
|
212
|
+
strategy.onTimeout( *this );
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
else if ( result > 0 )
|
|
216
|
+
{
|
|
217
|
+
processExceptSet( strategy, exceptSet );
|
|
218
|
+
processWriteSet( strategy, writeSet );
|
|
219
|
+
processReadSet( strategy, readSet );
|
|
220
|
+
}
|
|
221
|
+
else
|
|
222
|
+
{
|
|
223
|
+
strategy.onError( *this );
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
void SocketMonitor::processReadSet( Strategy& strategy, fd_set& readSet )
|
|
228
|
+
{
|
|
229
|
+
#ifdef _MSC_VER
|
|
230
|
+
for ( unsigned i = 0; i < readSet.fd_count; ++i )
|
|
231
|
+
{
|
|
232
|
+
int s = readSet.fd_array[ i ];
|
|
233
|
+
if( s == m_interrupt )
|
|
234
|
+
{
|
|
235
|
+
int socket = 0;
|
|
236
|
+
recv( s, (char*)&socket, sizeof(socket), 0 );
|
|
237
|
+
addWrite( socket );
|
|
238
|
+
}
|
|
239
|
+
else
|
|
240
|
+
{
|
|
241
|
+
strategy.onEvent( *this, s );
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
#else
|
|
245
|
+
Sockets::iterator i;
|
|
246
|
+
Sockets sockets = m_readSockets;
|
|
247
|
+
for ( i = sockets.begin(); i != sockets.end(); ++i )
|
|
248
|
+
{
|
|
249
|
+
int s = *i;
|
|
250
|
+
if ( !FD_ISSET( *i, &readSet ) )
|
|
251
|
+
continue;
|
|
252
|
+
if( s == m_interrupt )
|
|
253
|
+
{
|
|
254
|
+
int socket = 0;
|
|
255
|
+
recv( s, (char*)&socket, sizeof(socket), 0 );
|
|
256
|
+
addWrite( socket );
|
|
257
|
+
}
|
|
258
|
+
else
|
|
259
|
+
{
|
|
260
|
+
strategy.onEvent( *this, s );
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
#endif
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
void SocketMonitor::processWriteSet( Strategy& strategy, fd_set& writeSet )
|
|
267
|
+
{
|
|
268
|
+
#ifdef _MSC_VER
|
|
269
|
+
for ( unsigned i = 0; i < writeSet.fd_count; ++i )
|
|
270
|
+
{
|
|
271
|
+
int s = writeSet.fd_array[ i ];
|
|
272
|
+
if( m_connectSockets.find(s) != m_connectSockets.end() )
|
|
273
|
+
{
|
|
274
|
+
m_connectSockets.erase( s );
|
|
275
|
+
m_readSockets.insert( s );
|
|
276
|
+
strategy.onConnect( *this, s );
|
|
277
|
+
}
|
|
278
|
+
else
|
|
279
|
+
{
|
|
280
|
+
strategy.onWrite( *this, s );
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
#else
|
|
284
|
+
Sockets::iterator i;
|
|
285
|
+
Sockets sockets = m_connectSockets;
|
|
286
|
+
for( i = sockets.begin(); i != sockets.end(); ++i )
|
|
287
|
+
{
|
|
288
|
+
int s = *i;
|
|
289
|
+
if ( !FD_ISSET( *i, &writeSet ) )
|
|
290
|
+
continue;
|
|
291
|
+
m_connectSockets.erase( s );
|
|
292
|
+
m_readSockets.insert( s );
|
|
293
|
+
strategy.onConnect( *this, s );
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
sockets = m_writeSockets;
|
|
297
|
+
for( i = sockets.begin(); i != sockets.end(); ++i )
|
|
298
|
+
{
|
|
299
|
+
int s = *i;
|
|
300
|
+
if ( !FD_ISSET( *i, &writeSet ) )
|
|
301
|
+
continue;
|
|
302
|
+
strategy.onWrite( *this, s );
|
|
303
|
+
}
|
|
304
|
+
#endif
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
void SocketMonitor::processExceptSet( Strategy& strategy, fd_set& exceptSet )
|
|
308
|
+
{
|
|
309
|
+
#ifdef _MSC_VER
|
|
310
|
+
for ( unsigned i = 0; i < exceptSet.fd_count; ++i )
|
|
311
|
+
{
|
|
312
|
+
int s = exceptSet.fd_array[ i ];
|
|
313
|
+
strategy.onError( *this, s );
|
|
314
|
+
}
|
|
315
|
+
#else
|
|
316
|
+
Sockets::iterator i;
|
|
317
|
+
Sockets sockets = m_connectSockets;
|
|
318
|
+
for ( i = sockets.begin(); i != sockets.end(); ++i )
|
|
319
|
+
{
|
|
320
|
+
int s = *i;
|
|
321
|
+
if ( !FD_ISSET( *i, &exceptSet ) )
|
|
322
|
+
continue;
|
|
323
|
+
strategy.onError( *this, s );
|
|
324
|
+
}
|
|
325
|
+
#endif
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
void SocketMonitor::buildSet( const Sockets& sockets, fd_set& watchSet )
|
|
329
|
+
{
|
|
330
|
+
Sockets::const_iterator iter;
|
|
331
|
+
for ( iter = sockets.begin(); iter != sockets.end(); ++iter ) {
|
|
332
|
+
FD_SET( *iter, &watchSet );
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* -*- C++ -*- */
|
|
2
|
+
|
|
3
|
+
/****************************************************************************
|
|
4
|
+
** Copyright (c) 2001-2014
|
|
5
|
+
**
|
|
6
|
+
** This file is part of the QuickFIX FIX Engine
|
|
7
|
+
**
|
|
8
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
9
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
10
|
+
** LICENSE included in the packaging of this file.
|
|
11
|
+
**
|
|
12
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
13
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
**
|
|
15
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
16
|
+
**
|
|
17
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
18
|
+
** not clear to you.
|
|
19
|
+
**
|
|
20
|
+
****************************************************************************/
|
|
21
|
+
|
|
22
|
+
#ifndef FIX_SOCKETMONITOR_H
|
|
23
|
+
#define FIX_SOCKETMONITOR_H
|
|
24
|
+
|
|
25
|
+
#ifdef _MSC_VER
|
|
26
|
+
#pragma warning( disable : 4503 4355 4786 4290 )
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#ifdef _MSC_VER
|
|
30
|
+
#include <Winsock2.h>
|
|
31
|
+
typedef int socklen_t;
|
|
32
|
+
#else
|
|
33
|
+
#include <sys/types.h>
|
|
34
|
+
#include <sys/socket.h>
|
|
35
|
+
#include <sys/time.h>
|
|
36
|
+
#include <netinet/in.h>
|
|
37
|
+
#include <arpa/inet.h>
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
#include <set>
|
|
41
|
+
#include <queue>
|
|
42
|
+
#include <time.h>
|
|
43
|
+
|
|
44
|
+
namespace FIX
|
|
45
|
+
{
|
|
46
|
+
/// Monitors events on a collection of sockets.
|
|
47
|
+
class SocketMonitor
|
|
48
|
+
{
|
|
49
|
+
public:
|
|
50
|
+
class Strategy;
|
|
51
|
+
|
|
52
|
+
SocketMonitor( int timeout = 0 );
|
|
53
|
+
virtual ~SocketMonitor();
|
|
54
|
+
|
|
55
|
+
bool addConnect( int socket );
|
|
56
|
+
bool addRead( int socket );
|
|
57
|
+
bool addWrite( int socket );
|
|
58
|
+
bool drop( int socket );
|
|
59
|
+
void signal( int socket );
|
|
60
|
+
void unsignal( int socket );
|
|
61
|
+
void block( Strategy& strategy, bool poll = 0, double timeout = 0.0 );
|
|
62
|
+
|
|
63
|
+
size_t numSockets()
|
|
64
|
+
{ return m_readSockets.size() - 1; }
|
|
65
|
+
|
|
66
|
+
private:
|
|
67
|
+
typedef std::set < int > Sockets;
|
|
68
|
+
typedef std::queue < int > Queue;
|
|
69
|
+
|
|
70
|
+
void setsockopt();
|
|
71
|
+
bool bind();
|
|
72
|
+
bool listen();
|
|
73
|
+
void buildSet( const Sockets&, fd_set& );
|
|
74
|
+
inline timeval* getTimeval( bool poll, double timeout );
|
|
75
|
+
inline bool sleepIfEmpty( bool poll );
|
|
76
|
+
|
|
77
|
+
void processReadSet( Strategy&, fd_set& );
|
|
78
|
+
void processWriteSet( Strategy&, fd_set& );
|
|
79
|
+
void processExceptSet( Strategy&, fd_set& );
|
|
80
|
+
|
|
81
|
+
int m_timeout;
|
|
82
|
+
timeval m_timeval;
|
|
83
|
+
#ifndef SELECT_DECREMENTS_TIME
|
|
84
|
+
clock_t m_ticks;
|
|
85
|
+
#endif
|
|
86
|
+
|
|
87
|
+
int m_signal;
|
|
88
|
+
int m_interrupt;
|
|
89
|
+
Sockets m_connectSockets;
|
|
90
|
+
Sockets m_readSockets;
|
|
91
|
+
Sockets m_writeSockets;
|
|
92
|
+
Queue m_dropped;
|
|
93
|
+
|
|
94
|
+
public:
|
|
95
|
+
class Strategy
|
|
96
|
+
{
|
|
97
|
+
public:
|
|
98
|
+
virtual ~Strategy()
|
|
99
|
+
{}
|
|
100
|
+
virtual void onConnect( SocketMonitor&, int socket ) = 0;
|
|
101
|
+
virtual void onEvent( SocketMonitor&, int socket ) = 0;
|
|
102
|
+
virtual void onWrite( SocketMonitor&, int socket ) = 0;
|
|
103
|
+
virtual void onError( SocketMonitor&, int socket ) = 0;
|
|
104
|
+
virtual void onError( SocketMonitor& ) = 0;
|
|
105
|
+
virtual void onTimeout( SocketMonitor& )
|
|
106
|
+
{}}
|
|
107
|
+
;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#endif //FIX_SOCKETMONITOR_H
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/****************************************************************************
|
|
2
|
+
** Copyright (c) 2001-2014
|
|
3
|
+
**
|
|
4
|
+
** This file is part of the QuickFIX FIX Engine
|
|
5
|
+
**
|
|
6
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
7
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
8
|
+
** LICENSE included in the packaging of this file.
|
|
9
|
+
**
|
|
10
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
11
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
12
|
+
**
|
|
13
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
14
|
+
**
|
|
15
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
16
|
+
** not clear to you.
|
|
17
|
+
**
|
|
18
|
+
****************************************************************************/
|
|
19
|
+
|
|
20
|
+
#ifdef _MSC_VER
|
|
21
|
+
#include "stdafx.h"
|
|
22
|
+
#else
|
|
23
|
+
#include "config.h"
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
#include "SocketServer.h"
|
|
27
|
+
#include "Utility.h"
|
|
28
|
+
#include "Exceptions.h"
|
|
29
|
+
#ifndef _MSC_VER
|
|
30
|
+
#include <unistd.h>
|
|
31
|
+
#include <sys/ioctl.h>
|
|
32
|
+
#include <sys/types.h>
|
|
33
|
+
#include <sys/stat.h>
|
|
34
|
+
#endif
|
|
35
|
+
#include <exception>
|
|
36
|
+
|
|
37
|
+
namespace FIX
|
|
38
|
+
{
|
|
39
|
+
/// Handles events from SocketMonitor for server connections.
|
|
40
|
+
class ServerWrapper : public SocketMonitor::Strategy
|
|
41
|
+
{
|
|
42
|
+
public:
|
|
43
|
+
ServerWrapper( std::set<int> sockets, SocketServer& server,
|
|
44
|
+
SocketServer::Strategy& strategy )
|
|
45
|
+
: m_sockets( sockets ), m_server( server ), m_strategy( strategy ) {}
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
void onConnect( SocketMonitor&, int socket )
|
|
49
|
+
{
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void onEvent( SocketMonitor& monitor, int socket )
|
|
53
|
+
{
|
|
54
|
+
if( m_sockets.find(socket) != m_sockets.end() )
|
|
55
|
+
{
|
|
56
|
+
m_strategy.onConnect( m_server, socket, m_server.accept(socket) );
|
|
57
|
+
}
|
|
58
|
+
else
|
|
59
|
+
{
|
|
60
|
+
if( !m_strategy.onData( m_server, socket ) )
|
|
61
|
+
onError( monitor, socket );
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
void onWrite( SocketMonitor&, int socket )
|
|
66
|
+
{
|
|
67
|
+
m_strategy.onWrite( m_server, socket );
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
void onError( SocketMonitor& monitor, int socket )
|
|
71
|
+
{
|
|
72
|
+
m_strategy.onDisconnect( m_server, socket );
|
|
73
|
+
monitor.drop( socket );
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void onError( SocketMonitor& )
|
|
77
|
+
{
|
|
78
|
+
m_strategy.onError( m_server );
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
void onTimeout( SocketMonitor& )
|
|
82
|
+
{
|
|
83
|
+
m_strategy.onTimeout( m_server );
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
typedef std::set<int>
|
|
87
|
+
Sockets;
|
|
88
|
+
|
|
89
|
+
Sockets m_sockets;
|
|
90
|
+
SocketServer& m_server;
|
|
91
|
+
SocketServer::Strategy& m_strategy;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
SocketServer::SocketServer( int timeout )
|
|
95
|
+
: m_monitor( timeout ) {}
|
|
96
|
+
|
|
97
|
+
int SocketServer::add( int port, bool reuse, bool noDelay,
|
|
98
|
+
int sendBufSize, int rcvBufSize )
|
|
99
|
+
throw( SocketException& )
|
|
100
|
+
{
|
|
101
|
+
if( m_portToInfo.find(port) != m_portToInfo.end() )
|
|
102
|
+
return m_portToInfo[port].m_socket;
|
|
103
|
+
|
|
104
|
+
int socket = socket_createAcceptor( port, reuse );
|
|
105
|
+
if( socket < 0 )
|
|
106
|
+
throw SocketException();
|
|
107
|
+
if( noDelay )
|
|
108
|
+
socket_setsockopt( socket, TCP_NODELAY );
|
|
109
|
+
if( sendBufSize )
|
|
110
|
+
socket_setsockopt( socket, SO_SNDBUF, sendBufSize );
|
|
111
|
+
if( rcvBufSize )
|
|
112
|
+
socket_setsockopt( socket, SO_RCVBUF, rcvBufSize );
|
|
113
|
+
m_monitor.addRead( socket );
|
|
114
|
+
|
|
115
|
+
SocketInfo info( socket, port, noDelay, sendBufSize, rcvBufSize );
|
|
116
|
+
m_socketToInfo[socket] = info;
|
|
117
|
+
m_portToInfo[port] = info;
|
|
118
|
+
return socket;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
int SocketServer::accept( int socket )
|
|
122
|
+
{
|
|
123
|
+
SocketInfo info = m_socketToInfo[socket];
|
|
124
|
+
|
|
125
|
+
int result = socket_accept( socket );
|
|
126
|
+
if( info.m_noDelay )
|
|
127
|
+
socket_setsockopt( result, TCP_NODELAY );
|
|
128
|
+
if( info.m_sendBufSize )
|
|
129
|
+
socket_setsockopt( result, SO_SNDBUF, info.m_sendBufSize );
|
|
130
|
+
if( info.m_rcvBufSize )
|
|
131
|
+
socket_setsockopt( result, SO_RCVBUF, info.m_rcvBufSize );
|
|
132
|
+
if ( result >= 0 )
|
|
133
|
+
m_monitor.addConnect( result );
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
void SocketServer::close()
|
|
138
|
+
{
|
|
139
|
+
SocketToInfo::iterator i = m_socketToInfo.begin();
|
|
140
|
+
for( ; i != m_socketToInfo.end(); ++i )
|
|
141
|
+
{
|
|
142
|
+
int s = i->first;
|
|
143
|
+
socket_close( s );
|
|
144
|
+
socket_invalidate( s );
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
bool SocketServer::block( Strategy& strategy, bool poll, double timeout )
|
|
149
|
+
{
|
|
150
|
+
std::set<int> sockets;
|
|
151
|
+
SocketToInfo::iterator i = m_socketToInfo.begin();
|
|
152
|
+
for( ; i != m_socketToInfo.end(); ++i )
|
|
153
|
+
{
|
|
154
|
+
if( !socket_isValid(i->first) )
|
|
155
|
+
return false;
|
|
156
|
+
sockets.insert( i->first );
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
ServerWrapper wrapper( sockets, *this, strategy );
|
|
160
|
+
m_monitor.block( wrapper, poll, timeout );
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
int SocketServer::socketToPort( int socket )
|
|
165
|
+
{
|
|
166
|
+
SocketToInfo::iterator find = m_socketToInfo.find( socket );
|
|
167
|
+
if( find == m_socketToInfo.end() ) return 0;
|
|
168
|
+
return find->second.m_port;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
int SocketServer::portToSocket( int port )
|
|
172
|
+
{
|
|
173
|
+
SocketToInfo::iterator find = m_portToInfo.find( port );
|
|
174
|
+
if( find == m_portToInfo.end() ) return 0;
|
|
175
|
+
return find->second.m_socket;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* -*- C++ -*- */
|
|
2
|
+
|
|
3
|
+
/****************************************************************************
|
|
4
|
+
** Copyright (c) 2001-2014
|
|
5
|
+
**
|
|
6
|
+
** This file is part of the QuickFIX FIX Engine
|
|
7
|
+
**
|
|
8
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
9
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
10
|
+
** LICENSE included in the packaging of this file.
|
|
11
|
+
**
|
|
12
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
13
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
**
|
|
15
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
16
|
+
**
|
|
17
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
18
|
+
** not clear to you.
|
|
19
|
+
**
|
|
20
|
+
****************************************************************************/
|
|
21
|
+
|
|
22
|
+
#ifndef FIX_SOCKETSERVER_H
|
|
23
|
+
#define FIX_SOCKETSERVER_H
|
|
24
|
+
|
|
25
|
+
#ifdef _MSC_VER
|
|
26
|
+
#pragma warning( disable : 4503 4355 4786 4290 )
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#include "SocketMonitor.h"
|
|
30
|
+
#include "Exceptions.h"
|
|
31
|
+
#include <map>
|
|
32
|
+
#include <set>
|
|
33
|
+
#include <queue>
|
|
34
|
+
|
|
35
|
+
namespace FIX
|
|
36
|
+
{
|
|
37
|
+
/// Information about listening socket
|
|
38
|
+
struct SocketInfo
|
|
39
|
+
{
|
|
40
|
+
SocketInfo()
|
|
41
|
+
: m_socket( -1 ), m_port( 0 ), m_noDelay( false ),
|
|
42
|
+
m_sendBufSize( 0 ), m_rcvBufSize( 0 ) {}
|
|
43
|
+
|
|
44
|
+
SocketInfo( int socket, short port, bool noDelay, int sendBufSize, int rcvBufSize )
|
|
45
|
+
: m_socket( socket ), m_port( port ), m_noDelay( noDelay ),
|
|
46
|
+
m_sendBufSize( sendBufSize ), m_rcvBufSize( rcvBufSize ) {}
|
|
47
|
+
|
|
48
|
+
int m_socket;
|
|
49
|
+
short m_port;
|
|
50
|
+
bool m_noDelay;
|
|
51
|
+
int m_sendBufSize;
|
|
52
|
+
int m_rcvBufSize;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/// Listens for and accepts incoming socket connections on a port.
|
|
56
|
+
class SocketServer
|
|
57
|
+
{
|
|
58
|
+
public:
|
|
59
|
+
class Strategy;
|
|
60
|
+
|
|
61
|
+
SocketServer( int timeout = 0 );
|
|
62
|
+
|
|
63
|
+
int add( int port, bool reuse = false, bool noDelay = false,
|
|
64
|
+
int sendBufSize = 0, int rcvBufSize = 0 ) throw( SocketException& );
|
|
65
|
+
int accept( int socket );
|
|
66
|
+
void close();
|
|
67
|
+
bool block( Strategy& strategy, bool poll = 0, double timeout = 0.0 );
|
|
68
|
+
|
|
69
|
+
size_t numConnections() { return m_monitor.numSockets() - 1; }
|
|
70
|
+
SocketMonitor& getMonitor() { return m_monitor; }
|
|
71
|
+
|
|
72
|
+
int socketToPort( int socket );
|
|
73
|
+
int portToSocket( int port );
|
|
74
|
+
|
|
75
|
+
private:
|
|
76
|
+
typedef std::map<int, SocketInfo>
|
|
77
|
+
SocketToInfo;
|
|
78
|
+
typedef std::map<int, SocketInfo>
|
|
79
|
+
PortToInfo;
|
|
80
|
+
|
|
81
|
+
SocketToInfo m_socketToInfo;
|
|
82
|
+
PortToInfo m_portToInfo;
|
|
83
|
+
SocketMonitor m_monitor;
|
|
84
|
+
|
|
85
|
+
public:
|
|
86
|
+
class Strategy
|
|
87
|
+
{
|
|
88
|
+
public:
|
|
89
|
+
virtual ~Strategy() {}
|
|
90
|
+
virtual void onConnect( SocketServer&, int acceptSocket, int socket ) = 0;
|
|
91
|
+
virtual void onWrite( SocketServer&, int socket ) = 0;
|
|
92
|
+
virtual bool onData( SocketServer&, int socket ) = 0;
|
|
93
|
+
virtual void onDisconnect( SocketServer&, int socket ) = 0;
|
|
94
|
+
virtual void onError( SocketServer& ) = 0;
|
|
95
|
+
virtual void onTimeout( SocketServer& ) {};
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#endif //FIX_SOCKETSERVER_H
|