eventmachine 0.5.3 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/RELEASE_NOTES +14 -1
- data/TODO +10 -0
- data/ext/cmain.cpp +100 -4
- data/ext/ed.cpp +228 -44
- data/ext/ed.h +25 -2
- data/ext/em.cpp +351 -14
- data/ext/em.h +33 -8
- data/ext/emwin.h +4 -2
- data/ext/eventmachine.h +9 -1
- data/ext/files.cpp +101 -0
- data/ext/files.h +72 -0
- data/ext/project.h +3 -1
- data/ext/rubymain.cpp +113 -5
- data/lib/em/deferrable.rb +89 -0
- data/lib/em/eventable.rb +50 -0
- data/lib/eventmachine.rb +274 -9
- data/lib/eventmachine_version.rb +42 -0
- data/lib/evma/callback.rb +35 -0
- data/lib/evma/container.rb +77 -0
- data/lib/evma/factory.rb +80 -0
- data/lib/evma/protocol.rb +89 -0
- data/lib/evma/reactor.rb +50 -0
- data/lib/evma.rb +35 -0
- data/lib/pr_eventmachine.rb +714 -0
- data/lib/protocols/header_and_content.rb +134 -0
- data/lib/protocols/httpclient.rb +233 -0
- data/lib/protocols/line_and_text.rb +141 -0
- data/lib/protocols/tcptest.rb +67 -0
- data/tests/test_basic.rb +106 -0
- data/tests/test_eventables.rb +85 -0
- data/tests/test_hc.rb +207 -0
- data/tests/test_httpclient.rb +94 -0
- data/tests/test_ltp.rb +192 -0
- data/tests/test_ud.rb +52 -0
- metadata +44 -18
- data/ext/Makefile +0 -139
- data/ext/mkmf.log +0 -59
data/RELEASE_NOTES
CHANGED
@@ -1,7 +1,20 @@
|
|
1
|
-
$Id: RELEASE_NOTES
|
1
|
+
$Id: RELEASE_NOTES 223 2006-08-08 20:30:41Z blackhedd $
|
2
2
|
|
3
3
|
RUBY/EventMachine RELEASE NOTES
|
4
4
|
|
5
|
+
--------------------------------------------------
|
6
|
+
Version: 0.7.0, released xxAug06
|
7
|
+
Added a fix in em.cpp/ConnectToServer to fix a fatal exception that
|
8
|
+
occurred in FreeBSD when connecting successfully to a remote server.
|
9
|
+
|
10
|
+
--------------------------------------------------
|
11
|
+
Version: 0.6.0, released xxJul06
|
12
|
+
Added deferred operations, suggested by Don Stocks, amillionhitpoints@yahoo.com.
|
13
|
+
|
14
|
+
--------------------------------------------------
|
15
|
+
Version: 0.5.4, released xxJun06
|
16
|
+
Added get_peername support for streams and datagrams.
|
17
|
+
|
5
18
|
--------------------------------------------------
|
6
19
|
Version: 0.5.3, released 17May06
|
7
20
|
Fixed bugs in extconf.rb, thanks to Daniel Harple, dharple@generalconsumption.org.
|
data/TODO
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
$Id: TODO 231 2006-08-13 17:15:53Z blackhedd $
|
2
|
+
|
3
|
+
TODO List:
|
4
|
+
|
5
|
+
12Aug06: Noticed by Don Stocks. A TCP connect-request that results
|
6
|
+
in a failed DNS resolution fires a fatal error back to user code.
|
7
|
+
Uuuuuugly. We should probably cause an unbind event to get fired
|
8
|
+
instead, and add some parameterization so the caller can detect
|
9
|
+
the nature of the failure.
|
10
|
+
|
data/ext/cmain.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: cmain.cpp
|
3
|
+
$Id: cmain.cpp 265 2006-10-05 19:07:45Z blackhedd $
|
4
4
|
|
5
5
|
File: libmain.cpp
|
6
6
|
Date: 06Apr06
|
@@ -105,6 +105,17 @@ extern "C" const char *evma_create_tcp_server (const char *address, int port)
|
|
105
105
|
return EventMachine->CreateTcpServer (address, port);
|
106
106
|
}
|
107
107
|
|
108
|
+
/******************************
|
109
|
+
evma_create_unix_domain_server
|
110
|
+
******************************/
|
111
|
+
|
112
|
+
extern "C" const char *evma_create_unix_domain_server (const char *filename)
|
113
|
+
{
|
114
|
+
if (!EventMachine)
|
115
|
+
throw std::runtime_error ("not initialized");
|
116
|
+
return EventMachine->CreateUnixDomainServer (filename);
|
117
|
+
}
|
118
|
+
|
108
119
|
/*************************
|
109
120
|
evma_open_datagram_socket
|
110
121
|
*************************/
|
@@ -173,10 +184,95 @@ extern "C" void evma_start_tls (const char *binding)
|
|
173
184
|
{
|
174
185
|
if (!EventMachine)
|
175
186
|
throw std::runtime_error ("not initialized");
|
176
|
-
|
177
|
-
|
178
|
-
|
187
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
188
|
+
if (ed)
|
189
|
+
ed->StartTls();
|
190
|
+
}
|
191
|
+
|
192
|
+
|
193
|
+
/*****************
|
194
|
+
evma_get_peername
|
195
|
+
*****************/
|
196
|
+
|
197
|
+
extern "C" int evma_get_peername (const char *binding, struct sockaddr *sa)
|
198
|
+
{
|
199
|
+
if (!EventMachine)
|
200
|
+
throw std::runtime_error ("not initialized");
|
201
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
202
|
+
if (ed) {
|
203
|
+
return ed->GetPeername (sa) ? 1 : 0;
|
204
|
+
}
|
205
|
+
else
|
206
|
+
return 0;
|
207
|
+
}
|
208
|
+
|
209
|
+
|
210
|
+
/*********************
|
211
|
+
evma_signal_loopbreak
|
212
|
+
*********************/
|
213
|
+
|
214
|
+
extern "C" void evma_signal_loopbreak()
|
215
|
+
{
|
216
|
+
if (!EventMachine)
|
217
|
+
throw std::runtime_error ("not initialized");
|
218
|
+
EventMachine->SignalLoopBreaker();
|
219
|
+
}
|
220
|
+
|
221
|
+
|
222
|
+
|
223
|
+
/****************
|
224
|
+
evma__write_file
|
225
|
+
****************/
|
226
|
+
|
227
|
+
extern "C" const char *evma__write_file (const char *filename)
|
228
|
+
{
|
229
|
+
if (!EventMachine)
|
230
|
+
throw std::runtime_error ("not initialized");
|
231
|
+
return EventMachine->_OpenFileForWriting (filename);
|
232
|
+
}
|
233
|
+
|
234
|
+
|
235
|
+
/********************************
|
236
|
+
evma_get_comm_inactivity_timeout
|
237
|
+
********************************/
|
238
|
+
|
239
|
+
extern "C" int evma_get_comm_inactivity_timeout (const char *binding, int *value)
|
240
|
+
{
|
241
|
+
if (!EventMachine)
|
242
|
+
throw std::runtime_error ("not initialized");
|
243
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
244
|
+
if (ed) {
|
245
|
+
return ed->GetCommInactivityTimeout (value);
|
246
|
+
}
|
247
|
+
else
|
248
|
+
return 0; //Perhaps this should be an exception. Access to an unknown binding.
|
179
249
|
}
|
180
250
|
|
251
|
+
/********************************
|
252
|
+
evma_set_comm_inactivity_timeout
|
253
|
+
********************************/
|
181
254
|
|
255
|
+
extern "C" int evma_set_comm_inactivity_timeout (const char *binding, int *value)
|
256
|
+
{
|
257
|
+
if (!EventMachine)
|
258
|
+
throw std::runtime_error ("not initialized");
|
259
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
260
|
+
if (ed) {
|
261
|
+
return ed->SetCommInactivityTimeout (value);
|
262
|
+
}
|
263
|
+
else
|
264
|
+
return 0; //Perhaps this should be an exception. Access to an unknown binding.
|
265
|
+
}
|
266
|
+
|
267
|
+
|
268
|
+
/**********************
|
269
|
+
evma_set_timer_quantum
|
270
|
+
**********************/
|
271
|
+
|
272
|
+
extern "C" void evma_set_timer_quantum (int interval)
|
273
|
+
{
|
274
|
+
if (!EventMachine)
|
275
|
+
throw std::runtime_error ("not initialized");
|
276
|
+
EventMachine->SetTimerQuantum (interval);
|
277
|
+
}
|
182
278
|
|
data/ext/ed.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: ed.cpp
|
3
|
+
$Id: ed.cpp 255 2006-09-15 11:21:15Z blackhedd $
|
4
4
|
|
5
5
|
File: ed.cpp
|
6
6
|
Date: 06Apr06
|
@@ -159,13 +159,16 @@ ConnectionDescriptor::ConnectionDescriptor
|
|
159
159
|
******************************************/
|
160
160
|
|
161
161
|
ConnectionDescriptor::ConnectionDescriptor (int sd):
|
162
|
-
|
163
|
-
|
164
|
-
|
162
|
+
EventableDescriptor (sd),
|
163
|
+
bConnectPending (false),
|
164
|
+
bReadAttemptedAfterClose (false),
|
165
|
+
OutboundDataSize (0),
|
165
166
|
#ifdef WITH_SSL
|
166
167
|
SslBox (NULL),
|
167
168
|
#endif
|
168
|
-
bIsServer (false)
|
169
|
+
bIsServer (false),
|
170
|
+
LastIo (gCurrentLoopTime),
|
171
|
+
InactivityTimeout (0)
|
169
172
|
{
|
170
173
|
}
|
171
174
|
|
@@ -333,10 +336,33 @@ void ConnectionDescriptor::Read()
|
|
333
336
|
* a socket that has already been scheduled for closing or close-after-writing.
|
334
337
|
* In those cases, we'll leave it up the to protocol handler to "do the
|
335
338
|
* right thing" (which probably means to ignore the incoming data).
|
339
|
+
*
|
340
|
+
* 22Aug06: Chris Ochs reports that on FreeBSD, it's possible to come
|
341
|
+
* here with the socket already closed, after the process receives
|
342
|
+
* a ctrl-C signal (not sure if that's TERM or INT on BSD). The application
|
343
|
+
* was one in which network connections were doing a lot of interleaved reads
|
344
|
+
* and writes.
|
345
|
+
* Since we always write before reading (in order to keep the outbound queues
|
346
|
+
* as light as possible), I think what happened is that an interrupt caused
|
347
|
+
* the socket to be closed in ConnectionDescriptor::Write. We'll then
|
348
|
+
* come here in the same pass through the main event loop, and won't get
|
349
|
+
* cleaned up until immediately after.
|
350
|
+
* We originally asserted that the socket was valid when we got here.
|
351
|
+
* To deal properly with the possibility that we are closed when we get here,
|
352
|
+
* I removed the assert. HOWEVER, the potential for an infinite loop scares me,
|
353
|
+
* so even though this is really clunky, I added a flag to assert that we never
|
354
|
+
* come here more than once after being closed. (FCianfrocca)
|
336
355
|
*/
|
337
356
|
|
338
357
|
int sd = GetSocket();
|
339
|
-
assert (sd != INVALID_SOCKET);
|
358
|
+
//assert (sd != INVALID_SOCKET); (original, removed 22Aug06)
|
359
|
+
if (sd == INVALID_SOCKET) {
|
360
|
+
assert (!bReadAttemptedAfterClose);
|
361
|
+
bReadAttemptedAfterClose = true;
|
362
|
+
return;
|
363
|
+
}
|
364
|
+
|
365
|
+
LastIo = gCurrentLoopTime;
|
340
366
|
|
341
367
|
int total_bytes_read = 0;
|
342
368
|
char readbuffer [16 * 1024];
|
@@ -345,6 +371,10 @@ void ConnectionDescriptor::Read()
|
|
345
371
|
// Don't read just one buffer and then move on. This is faster
|
346
372
|
// if there is a lot of incoming.
|
347
373
|
// But don't read indefinitely. Give other sockets a chance to run.
|
374
|
+
// NOTICE, we're reading one less than the buffer size.
|
375
|
+
// That's so we can put a guard byte at the end of what we send
|
376
|
+
// to user code.
|
377
|
+
|
348
378
|
|
349
379
|
int r = recv (sd, readbuffer, sizeof(readbuffer) - 1, 0);
|
350
380
|
//cerr << "<R:" << r << ">";
|
@@ -355,17 +385,18 @@ void ConnectionDescriptor::Read()
|
|
355
385
|
|
356
386
|
// Add a null-terminator at the the end of the buffer
|
357
387
|
// that we will send to the callback.
|
358
|
-
// DO NOT CHANGE THIS. We want to explicitly allow users
|
388
|
+
// DO NOT EVER CHANGE THIS. We want to explicitly allow users
|
359
389
|
// to be able to depend on this behavior, so they will have
|
360
|
-
// the option to do some things faster.
|
390
|
+
// the option to do some things faster. Additionally it's
|
391
|
+
// a security guard against buffer overflows.
|
361
392
|
readbuffer [r] = 0;
|
362
|
-
|
393
|
+
_DispatchInboundData (readbuffer, r);
|
363
394
|
}
|
364
395
|
else if (r == 0) {
|
365
396
|
break;
|
366
397
|
}
|
367
398
|
else {
|
368
|
-
// Basically a would-block, meaning we've everything there is to read.
|
399
|
+
// Basically a would-block, meaning we've read everything there is to read.
|
369
400
|
break;
|
370
401
|
}
|
371
402
|
|
@@ -424,19 +455,19 @@ ConnectionDescriptor::Write
|
|
424
455
|
|
425
456
|
void ConnectionDescriptor::Write()
|
426
457
|
{
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
458
|
+
/* A socket which is in a pending-connect state will select
|
459
|
+
* writable when the disposition of the connect is known.
|
460
|
+
* At that point, check to be sure there are no errors,
|
461
|
+
* and if none, then promote the socket out of the pending
|
462
|
+
* state.
|
463
|
+
* TODO: I haven't figured out how Windows signals errors on
|
464
|
+
* unconnected sockets. Maybe it does the untraditional but
|
465
|
+
* logical thing and makes the socket selectable for error.
|
466
|
+
* If so, it's unsupported here for the time being, and connect
|
467
|
+
* errors will have to be caught by the timeout mechanism.
|
468
|
+
*/
|
438
469
|
|
439
|
-
|
470
|
+
if (bConnectPending) {
|
440
471
|
int error;
|
441
472
|
socklen_t len;
|
442
473
|
len = sizeof(error);
|
@@ -446,14 +477,17 @@ void ConnectionDescriptor::Write()
|
|
446
477
|
#ifdef OS_WIN32
|
447
478
|
int o = getsockopt (MySocket, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
|
448
479
|
#endif
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
480
|
+
if ((o == 0) && (error == 0)) {
|
481
|
+
if (EventCallback)
|
482
|
+
(*EventCallback)(GetBinding().c_str(), EventMachine_t::CONNECTION_COMPLETED, "", 0);
|
483
|
+
bConnectPending = false;
|
484
|
+
}
|
485
|
+
else
|
486
|
+
bCloseNow = true;
|
487
|
+
}
|
488
|
+
else {
|
489
|
+
_WriteOutboundData();
|
490
|
+
}
|
457
491
|
}
|
458
492
|
|
459
493
|
|
@@ -473,6 +507,7 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
473
507
|
int sd = GetSocket();
|
474
508
|
assert (sd != INVALID_SOCKET);
|
475
509
|
|
510
|
+
LastIo = gCurrentLoopTime;
|
476
511
|
char output_buffer [16 * 1024];
|
477
512
|
size_t nbytes = 0;
|
478
513
|
|
@@ -617,14 +652,20 @@ ConnectionDescriptor::Heartbeat
|
|
617
652
|
|
618
653
|
void ConnectionDescriptor::Heartbeat()
|
619
654
|
{
|
620
|
-
|
621
|
-
|
622
|
-
|
655
|
+
/* Only allow a certain amount of time to go by while waiting
|
656
|
+
* for a pending connect. If it expires, then kill the socket.
|
657
|
+
* For a connected socket, close it if its inactivity timer
|
658
|
+
* has expired.
|
659
|
+
*/
|
623
660
|
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
661
|
+
if (bConnectPending) {
|
662
|
+
if ((gCurrentLoopTime - CreatedAt) >= PendingConnectTimeout)
|
663
|
+
bCloseNow = true;
|
664
|
+
}
|
665
|
+
else {
|
666
|
+
if (InactivityTimeout && ((gCurrentLoopTime - LastIo) >= InactivityTimeout))
|
667
|
+
bCloseNow = true;
|
668
|
+
}
|
628
669
|
}
|
629
670
|
|
630
671
|
|
@@ -748,7 +789,9 @@ DatagramDescriptor::DatagramDescriptor
|
|
748
789
|
|
749
790
|
DatagramDescriptor::DatagramDescriptor (int sd):
|
750
791
|
EventableDescriptor (sd),
|
751
|
-
OutboundDataSize (0)
|
792
|
+
OutboundDataSize (0),
|
793
|
+
LastIo (gCurrentLoopTime),
|
794
|
+
InactivityTimeout (0)
|
752
795
|
{
|
753
796
|
memset (&ReturnAddress, 0, sizeof(ReturnAddress));
|
754
797
|
}
|
@@ -766,6 +809,19 @@ DatagramDescriptor::~DatagramDescriptor()
|
|
766
809
|
}
|
767
810
|
|
768
811
|
|
812
|
+
/*****************************
|
813
|
+
DatagramDescriptor::Heartbeat
|
814
|
+
*****************************/
|
815
|
+
|
816
|
+
void DatagramDescriptor::Heartbeat()
|
817
|
+
{
|
818
|
+
// Close it if its inactivity timer has expired.
|
819
|
+
|
820
|
+
if (InactivityTimeout && ((gCurrentLoopTime - LastIo) >= InactivityTimeout))
|
821
|
+
bCloseNow = true;
|
822
|
+
}
|
823
|
+
|
824
|
+
|
769
825
|
/************************
|
770
826
|
DatagramDescriptor::Read
|
771
827
|
************************/
|
@@ -774,6 +830,7 @@ void DatagramDescriptor::Read()
|
|
774
830
|
{
|
775
831
|
int sd = GetSocket();
|
776
832
|
assert (sd != INVALID_SOCKET);
|
833
|
+
LastIo = gCurrentLoopTime;
|
777
834
|
|
778
835
|
// This is an extremely large read buffer.
|
779
836
|
// In many cases you wouldn't expect to get any more than 4K.
|
@@ -783,6 +840,9 @@ void DatagramDescriptor::Read()
|
|
783
840
|
// Don't read just one buffer and then move on. This is faster
|
784
841
|
// if there is a lot of incoming.
|
785
842
|
// But don't read indefinitely. Give other sockets a chance to run.
|
843
|
+
// NOTICE, we're reading one less than the buffer size.
|
844
|
+
// That's so we can put a guard byte at the end of what we send
|
845
|
+
// to user code.
|
786
846
|
|
787
847
|
struct sockaddr_in sin;
|
788
848
|
socklen_t slen = sizeof (sin);
|
@@ -797,9 +857,10 @@ void DatagramDescriptor::Read()
|
|
797
857
|
|
798
858
|
// Add a null-terminator at the the end of the buffer
|
799
859
|
// that we will send to the callback.
|
800
|
-
// DO NOT CHANGE THIS. We want to explicitly allow users
|
860
|
+
// DO NOT EVER CHANGE THIS. We want to explicitly allow users
|
801
861
|
// to be able to depend on this behavior, so they will have
|
802
|
-
// the option to do some things faster.
|
862
|
+
// the option to do some things faster. Additionally it's
|
863
|
+
// a security guard against buffer overflows.
|
803
864
|
readbuffer [r] = 0;
|
804
865
|
|
805
866
|
|
@@ -819,7 +880,7 @@ void DatagramDescriptor::Read()
|
|
819
880
|
|
820
881
|
}
|
821
882
|
else {
|
822
|
-
// Basically a would-block, meaning we've everything there is to read.
|
883
|
+
// Basically a would-block, meaning we've read everything there is to read.
|
823
884
|
break;
|
824
885
|
}
|
825
886
|
|
@@ -848,6 +909,7 @@ void DatagramDescriptor::Write()
|
|
848
909
|
|
849
910
|
int sd = GetSocket();
|
850
911
|
assert (sd != INVALID_SOCKET);
|
912
|
+
LastIo = gCurrentLoopTime;
|
851
913
|
|
852
914
|
assert (OutboundPages.size() > 0);
|
853
915
|
|
@@ -923,7 +985,7 @@ int DatagramDescriptor::SendOutboundDatagram (const char *data, int length, cons
|
|
923
985
|
{
|
924
986
|
// This is an exact clone of ConnectionDescriptor::SendOutboundData.
|
925
987
|
// That means it needs to move to a common ancestor.
|
926
|
-
|
988
|
+
// TODO: Refactor this so there's no overlap with SendOutboundData.
|
927
989
|
|
928
990
|
if (bCloseNow || bCloseAfterWriting)
|
929
991
|
return 0;
|
@@ -972,7 +1034,129 @@ int DatagramDescriptor::SendDatagram (const char *binding, const char *data, int
|
|
972
1034
|
DatagramDescriptor *dd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
|
973
1035
|
if (dd)
|
974
1036
|
return dd->SendOutboundDatagram (data, length, address, port);
|
975
|
-
|
976
|
-
|
1037
|
+
else
|
1038
|
+
return -1;
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
|
1042
|
+
/*********************************
|
1043
|
+
ConnectionDescriptor::GetPeername
|
1044
|
+
*********************************/
|
1045
|
+
|
1046
|
+
bool ConnectionDescriptor::GetPeername (struct sockaddr *s)
|
1047
|
+
{
|
1048
|
+
bool ok = false;
|
1049
|
+
if (s) {
|
1050
|
+
socklen_t len = sizeof(*s);
|
1051
|
+
int gp = getpeername (GetSocket(), s, &len);
|
1052
|
+
if (gp == 0)
|
1053
|
+
ok = true;
|
1054
|
+
}
|
1055
|
+
return ok;
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
|
1059
|
+
/**********************************************
|
1060
|
+
ConnectionDescriptor::GetCommInactivityTimeout
|
1061
|
+
**********************************************/
|
1062
|
+
|
1063
|
+
int ConnectionDescriptor::GetCommInactivityTimeout (int *value)
|
1064
|
+
{
|
1065
|
+
if (value) {
|
1066
|
+
*value = InactivityTimeout;
|
1067
|
+
return 1;
|
1068
|
+
}
|
1069
|
+
else {
|
1070
|
+
// TODO, extended logging, got bad parameter.
|
1071
|
+
return 0;
|
1072
|
+
}
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
|
1076
|
+
/**********************************************
|
1077
|
+
ConnectionDescriptor::SetCommInactivityTimeout
|
1078
|
+
**********************************************/
|
1079
|
+
|
1080
|
+
int ConnectionDescriptor::SetCommInactivityTimeout (int *value)
|
1081
|
+
{
|
1082
|
+
int out = 0;
|
1083
|
+
|
1084
|
+
if (value) {
|
1085
|
+
if ((*value==0) || (*value >= 2)) {
|
1086
|
+
// Replace the value and send the old one back to the caller.
|
1087
|
+
int v = *value;
|
1088
|
+
*value = InactivityTimeout;
|
1089
|
+
InactivityTimeout = v;
|
1090
|
+
out = 1;
|
1091
|
+
}
|
1092
|
+
else {
|
1093
|
+
// TODO, extended logging, got bad value.
|
1094
|
+
}
|
1095
|
+
}
|
1096
|
+
else {
|
1097
|
+
// TODO, extended logging, got bad parameter.
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
return out;
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
/*******************************
|
1104
|
+
DatagramDescriptor::GetPeername
|
1105
|
+
*******************************/
|
1106
|
+
|
1107
|
+
bool DatagramDescriptor::GetPeername (struct sockaddr *s)
|
1108
|
+
{
|
1109
|
+
bool ok = false;
|
1110
|
+
if (s) {
|
1111
|
+
memset (s, 0, sizeof(struct sockaddr));
|
1112
|
+
memcpy (s, &ReturnAddress, sizeof(ReturnAddress));
|
1113
|
+
ok = true;
|
1114
|
+
}
|
1115
|
+
return ok;
|
1116
|
+
}
|
1117
|
+
|
1118
|
+
|
1119
|
+
|
1120
|
+
/********************************************
|
1121
|
+
DatagramDescriptor::GetCommInactivityTimeout
|
1122
|
+
********************************************/
|
1123
|
+
|
1124
|
+
int DatagramDescriptor::GetCommInactivityTimeout (int *value)
|
1125
|
+
{
|
1126
|
+
if (value) {
|
1127
|
+
*value = InactivityTimeout;
|
1128
|
+
return 1;
|
1129
|
+
}
|
1130
|
+
else {
|
1131
|
+
// TODO, extended logging, got bad parameter.
|
1132
|
+
return 0;
|
1133
|
+
}
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
/********************************************
|
1137
|
+
DatagramDescriptor::SetCommInactivityTimeout
|
1138
|
+
********************************************/
|
1139
|
+
|
1140
|
+
int DatagramDescriptor::SetCommInactivityTimeout (int *value)
|
1141
|
+
{
|
1142
|
+
int out = 0;
|
1143
|
+
|
1144
|
+
if (value) {
|
1145
|
+
if ((*value==0) || (*value >= 2)) {
|
1146
|
+
// Replace the value and send the old one back to the caller.
|
1147
|
+
int v = *value;
|
1148
|
+
*value = InactivityTimeout;
|
1149
|
+
InactivityTimeout = v;
|
1150
|
+
out = 1;
|
1151
|
+
}
|
1152
|
+
else {
|
1153
|
+
// TODO, extended logging, got bad value.
|
1154
|
+
}
|
1155
|
+
}
|
1156
|
+
else {
|
1157
|
+
// TODO, extended logging, got bad parameter.
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
return out;
|
977
1161
|
}
|
978
1162
|
|
data/ext/ed.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: ed.h
|
3
|
+
$Id: ed.h 254 2006-09-15 11:17:01Z blackhedd $
|
4
4
|
|
5
5
|
File: ed.h
|
6
6
|
Date: 06Apr06
|
@@ -67,8 +67,15 @@ class EventableDescriptor: public Bindable_t
|
|
67
67
|
|
68
68
|
void SetEventCallback (void (*cb)(const char*, int, const char*, int));
|
69
69
|
|
70
|
+
virtual bool GetPeername (struct sockaddr*) {return false;}
|
71
|
+
|
70
72
|
virtual void StartTls() {}
|
71
73
|
|
74
|
+
// Properties: return 0/1 to signify T/F, and handle the values
|
75
|
+
// through arguments.
|
76
|
+
virtual int GetCommInactivityTimeout (int *value) {return 0;}
|
77
|
+
virtual int SetCommInactivityTimeout (int *value) {return 0;}
|
78
|
+
|
72
79
|
protected:
|
73
80
|
enum {
|
74
81
|
PendingConnectTimeout = 4 // can easily be made an instance variable
|
@@ -116,6 +123,10 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
116
123
|
virtual void StartTls();
|
117
124
|
void SetServerMode() {bIsServer = true;}
|
118
125
|
|
126
|
+
virtual bool GetPeername (struct sockaddr*);
|
127
|
+
|
128
|
+
virtual int GetCommInactivityTimeout (int *value);
|
129
|
+
virtual int SetCommInactivityTimeout (int *value);
|
119
130
|
|
120
131
|
protected:
|
121
132
|
struct OutboundPage {
|
@@ -128,6 +139,7 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
128
139
|
|
129
140
|
protected:
|
130
141
|
bool bConnectPending;
|
142
|
+
bool bReadAttemptedAfterClose;
|
131
143
|
|
132
144
|
deque<OutboundPage> OutboundPages;
|
133
145
|
int OutboundDataSize;
|
@@ -137,6 +149,9 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
137
149
|
#endif
|
138
150
|
bool bIsServer;
|
139
151
|
|
152
|
+
time_t LastIo;
|
153
|
+
int InactivityTimeout;
|
154
|
+
|
140
155
|
private:
|
141
156
|
void _WriteOutboundData();
|
142
157
|
void _DispatchInboundData (const char *buffer, int size);
|
@@ -158,7 +173,7 @@ class DatagramDescriptor: public EventableDescriptor
|
|
158
173
|
|
159
174
|
virtual void Read();
|
160
175
|
virtual void Write();
|
161
|
-
virtual void Heartbeat()
|
176
|
+
virtual void Heartbeat();
|
162
177
|
|
163
178
|
virtual bool SelectForRead() {return true;}
|
164
179
|
virtual bool SelectForWrite();
|
@@ -169,6 +184,11 @@ class DatagramDescriptor: public EventableDescriptor
|
|
169
184
|
// Do we have any data to write? This is used by ShouldDelete.
|
170
185
|
virtual int GetOutboundDataSize() {return OutboundDataSize;}
|
171
186
|
|
187
|
+
virtual bool GetPeername (struct sockaddr*);
|
188
|
+
|
189
|
+
virtual int GetCommInactivityTimeout (int *value);
|
190
|
+
virtual int SetCommInactivityTimeout (int *value);
|
191
|
+
|
172
192
|
static int SendDatagram (const char*, const char*, int, const char*, int);
|
173
193
|
|
174
194
|
|
@@ -186,6 +206,9 @@ class DatagramDescriptor: public EventableDescriptor
|
|
186
206
|
int OutboundDataSize;
|
187
207
|
|
188
208
|
struct sockaddr_in ReturnAddress;
|
209
|
+
|
210
|
+
time_t LastIo;
|
211
|
+
int InactivityTimeout;
|
189
212
|
};
|
190
213
|
|
191
214
|
|