eventmachine 0.12.10 → 1.0.0.beta.1
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.
- data/.gitignore +2 -0
- data/Gemfile +1 -0
- data/README +1 -2
- data/Rakefile +4 -76
- data/docs/DEFERRABLES +183 -70
- data/docs/KEYBOARD +15 -11
- data/docs/LIGHTWEIGHT_CONCURRENCY +84 -24
- data/docs/SMTP +3 -1
- data/docs/SPAWNED_PROCESSES +84 -25
- data/eventmachine.gemspec +19 -26
- data/examples/ex_tick_loop_array.rb +15 -0
- data/examples/ex_tick_loop_counter.rb +32 -0
- data/ext/binder.cpp +0 -1
- data/ext/cmain.cpp +36 -11
- data/ext/cplusplus.cpp +1 -1
- data/ext/ed.cpp +104 -113
- data/ext/ed.h +24 -30
- data/ext/em.cpp +347 -248
- data/ext/em.h +23 -16
- data/ext/eventmachine.h +5 -3
- data/ext/extconf.rb +5 -3
- data/ext/fastfilereader/extconf.rb +5 -3
- data/ext/fastfilereader/mapper.cpp +1 -1
- data/ext/kb.cpp +1 -3
- data/ext/pipe.cpp +9 -11
- data/ext/project.h +12 -4
- data/ext/rubymain.cpp +138 -89
- data/java/src/com/rubyeventmachine/EmReactor.java +1 -0
- data/lib/em/channel.rb +1 -1
- data/lib/em/connection.rb +6 -1
- data/lib/em/deferrable.rb +16 -2
- data/lib/em/iterator.rb +270 -0
- data/lib/em/protocols.rb +1 -1
- data/lib/em/protocols/httpclient.rb +5 -0
- data/lib/em/protocols/line_protocol.rb +28 -0
- data/lib/em/protocols/smtpserver.rb +101 -8
- data/lib/em/protocols/stomp.rb +1 -1
- data/lib/{pr_eventmachine.rb → em/pure_ruby.rb} +1 -11
- data/lib/em/queue.rb +1 -0
- data/lib/em/streamer.rb +1 -1
- data/lib/em/tick_loop.rb +85 -0
- data/lib/em/timers.rb +2 -1
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +38 -84
- data/lib/jeventmachine.rb +1 -0
- data/tests/test_attach.rb +13 -3
- data/tests/test_basic.rb +60 -95
- data/tests/test_channel.rb +3 -2
- data/tests/test_defer.rb +14 -12
- data/tests/test_deferrable.rb +35 -0
- data/tests/test_file_watch.rb +1 -1
- data/tests/test_futures.rb +1 -1
- data/tests/test_hc.rb +40 -68
- data/tests/test_httpclient.rb +15 -6
- data/tests/test_httpclient2.rb +3 -2
- data/tests/test_inactivity_timeout.rb +3 -3
- data/tests/test_ltp.rb +13 -5
- data/tests/test_next_tick.rb +1 -1
- data/tests/test_pending_connect_timeout.rb +2 -2
- data/tests/test_process_watch.rb +36 -34
- data/tests/test_proxy_connection.rb +52 -0
- data/tests/test_pure.rb +10 -1
- data/tests/test_sasl.rb +1 -1
- data/tests/test_send_file.rb +16 -7
- data/tests/test_servers.rb +1 -1
- data/tests/test_tick_loop.rb +59 -0
- data/tests/test_timers.rb +13 -15
- metadata +45 -17
- data/web/whatis +0 -7
data/ext/binder.cpp
CHANGED
data/ext/cmain.cpp
CHANGED
@@ -25,6 +25,7 @@ See the file COPYING for complete licensing information.
|
|
25
25
|
*/
|
26
26
|
#if defined(BUILD_FOR_RUBY) && defined(OS_WIN32)
|
27
27
|
#undef stat
|
28
|
+
#undef fstat
|
28
29
|
#endif
|
29
30
|
|
30
31
|
static EventMachine_t *EventMachine;
|
@@ -49,7 +50,7 @@ extern "C" void ensure_eventmachine (const char *caller = "unknown caller")
|
|
49
50
|
evma_initialize_library
|
50
51
|
***********************/
|
51
52
|
|
52
|
-
extern "C" void evma_initialize_library (
|
53
|
+
extern "C" void evma_initialize_library (EMCallback cb)
|
53
54
|
{
|
54
55
|
// Probably a bad idea to mess with the signal mask of a process
|
55
56
|
// we're just being linked into.
|
@@ -148,6 +149,7 @@ extern "C" int evma_detach_fd (const unsigned long binding)
|
|
148
149
|
#else
|
149
150
|
throw std::runtime_error ("invalid binding to detach");
|
150
151
|
#endif
|
152
|
+
return -1;
|
151
153
|
}
|
152
154
|
|
153
155
|
/************************
|
@@ -166,6 +168,7 @@ extern "C" int evma_get_file_descriptor (const unsigned long binding)
|
|
166
168
|
#else
|
167
169
|
throw std::runtime_error ("invalid binding to get_fd");
|
168
170
|
#endif
|
171
|
+
return -1;
|
169
172
|
}
|
170
173
|
|
171
174
|
/***********************
|
@@ -340,7 +343,10 @@ evma_send_data_to_connection
|
|
340
343
|
extern "C" int evma_send_data_to_connection (const unsigned long binding, const char *data, int data_length)
|
341
344
|
{
|
342
345
|
ensure_eventmachine("evma_send_data_to_connection");
|
343
|
-
|
346
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
347
|
+
if (ed)
|
348
|
+
return ed->SendOutboundData(data, data_length);
|
349
|
+
return -1;
|
344
350
|
}
|
345
351
|
|
346
352
|
/******************
|
@@ -350,7 +356,10 @@ evma_send_datagram
|
|
350
356
|
extern "C" int evma_send_datagram (const unsigned long binding, const char *data, int data_length, const char *address, int port)
|
351
357
|
{
|
352
358
|
ensure_eventmachine("evma_send_datagram");
|
353
|
-
|
359
|
+
DatagramDescriptor *dd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
|
360
|
+
if (dd)
|
361
|
+
return dd->SendOutboundDatagram(data, data_length, address, port);
|
362
|
+
return -1;
|
354
363
|
}
|
355
364
|
|
356
365
|
|
@@ -361,7 +370,9 @@ evma_close_connection
|
|
361
370
|
extern "C" void evma_close_connection (const unsigned long binding, int after_writing)
|
362
371
|
{
|
363
372
|
ensure_eventmachine("evma_close_connection");
|
364
|
-
|
373
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
374
|
+
if (ed)
|
375
|
+
ed->ScheduleClose (after_writing ? true : false);
|
365
376
|
}
|
366
377
|
|
367
378
|
/***********************************
|
@@ -371,7 +382,10 @@ evma_report_connection_error_status
|
|
371
382
|
extern "C" int evma_report_connection_error_status (const unsigned long binding)
|
372
383
|
{
|
373
384
|
ensure_eventmachine("evma_report_connection_error_status");
|
374
|
-
|
385
|
+
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
386
|
+
if (ed)
|
387
|
+
return ed->ReportErrorStatus();
|
388
|
+
return -1;
|
375
389
|
}
|
376
390
|
|
377
391
|
/********************
|
@@ -559,7 +573,7 @@ extern "C" float evma_get_comm_inactivity_timeout (const unsigned long binding)
|
|
559
573
|
ensure_eventmachine("evma_get_comm_inactivity_timeout");
|
560
574
|
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
561
575
|
if (ed) {
|
562
|
-
return ed->GetCommInactivityTimeout();
|
576
|
+
return ((float)ed->GetCommInactivityTimeout() / 1000);
|
563
577
|
}
|
564
578
|
else
|
565
579
|
return 0.0; //Perhaps this should be an exception. Access to an unknown binding.
|
@@ -574,7 +588,7 @@ extern "C" int evma_set_comm_inactivity_timeout (const unsigned long binding, fl
|
|
574
588
|
ensure_eventmachine("evma_set_comm_inactivity_timeout");
|
575
589
|
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
576
590
|
if (ed) {
|
577
|
-
return ed->SetCommInactivityTimeout (value);
|
591
|
+
return ed->SetCommInactivityTimeout ((uint64_t)(value * 1000));
|
578
592
|
}
|
579
593
|
else
|
580
594
|
return 0; //Perhaps this should be an exception. Access to an unknown binding.
|
@@ -590,7 +604,7 @@ extern "C" float evma_get_pending_connect_timeout (const unsigned long binding)
|
|
590
604
|
ensure_eventmachine("evma_get_pending_connect_timeout");
|
591
605
|
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
592
606
|
if (ed) {
|
593
|
-
return ed->GetPendingConnectTimeout();
|
607
|
+
return ((float)ed->GetPendingConnectTimeout() / 1000);
|
594
608
|
}
|
595
609
|
else
|
596
610
|
return 0.0;
|
@@ -606,7 +620,7 @@ extern "C" int evma_set_pending_connect_timeout (const unsigned long binding, fl
|
|
606
620
|
ensure_eventmachine("evma_set_pending_connect_timeout");
|
607
621
|
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
608
622
|
if (ed) {
|
609
|
-
return ed->SetPendingConnectTimeout (value);
|
623
|
+
return ed->SetPendingConnectTimeout ((uint64_t)(value * 1000));
|
610
624
|
}
|
611
625
|
else
|
612
626
|
return 0;
|
@@ -783,12 +797,12 @@ extern "C" int evma_send_file_data_to_connection (const unsigned long binding, c
|
|
783
797
|
evma_start_proxy
|
784
798
|
*****************/
|
785
799
|
|
786
|
-
extern "C" void evma_start_proxy (const unsigned long from, const unsigned long to, const unsigned long bufsize)
|
800
|
+
extern "C" void evma_start_proxy (const unsigned long from, const unsigned long to, const unsigned long bufsize, const unsigned long length)
|
787
801
|
{
|
788
802
|
ensure_eventmachine("evma_start_proxy");
|
789
803
|
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
|
790
804
|
if (ed)
|
791
|
-
ed->StartProxy(to, bufsize);
|
805
|
+
ed->StartProxy(to, bufsize, length);
|
792
806
|
}
|
793
807
|
|
794
808
|
|
@@ -825,3 +839,14 @@ extern "C" int evma_set_heartbeat_interval(float interval)
|
|
825
839
|
ensure_eventmachine("evma_set_heartbeat_interval");
|
826
840
|
return EventMachine->SetHeartbeatInterval(interval);
|
827
841
|
}
|
842
|
+
|
843
|
+
|
844
|
+
/**************************
|
845
|
+
evma_get_current_loop_time
|
846
|
+
***************************/
|
847
|
+
|
848
|
+
extern "C" uint64_t evma_get_current_loop_time()
|
849
|
+
{
|
850
|
+
ensure_eventmachine("evma_get_current_loop_time");
|
851
|
+
return EventMachine->GetCurrentLoopTime();
|
852
|
+
}
|
data/ext/cplusplus.cpp
CHANGED
data/ext/ed.cpp
CHANGED
@@ -61,7 +61,8 @@ EventableDescriptor::EventableDescriptor (int sd, EventMachine_t *em):
|
|
61
61
|
ProxiedFrom(NULL),
|
62
62
|
MaxOutboundBufSize(0),
|
63
63
|
MyEventMachine (em),
|
64
|
-
PendingConnectTimeout(20000000)
|
64
|
+
PendingConnectTimeout(20000000),
|
65
|
+
InactivityTimeout (0)
|
65
66
|
{
|
66
67
|
/* There are three ways to close a socket, all of which should
|
67
68
|
* automatically signal to the event machine that this object
|
@@ -88,12 +89,13 @@ EventableDescriptor::EventableDescriptor (int sd, EventMachine_t *em):
|
|
88
89
|
throw std::runtime_error ("bad eventable descriptor");
|
89
90
|
if (MyEventMachine == NULL)
|
90
91
|
throw std::runtime_error ("bad em in eventable descriptor");
|
91
|
-
CreatedAt =
|
92
|
+
CreatedAt = MyEventMachine->GetCurrentLoopTime();
|
92
93
|
|
93
94
|
#ifdef HAVE_EPOLL
|
94
95
|
EpollEvent.events = 0;
|
95
96
|
EpollEvent.data.ptr = this;
|
96
97
|
#endif
|
98
|
+
LastActivity = MyEventMachine->GetCurrentLoopTime();
|
97
99
|
}
|
98
100
|
|
99
101
|
|
@@ -103,6 +105,8 @@ EventableDescriptor::~EventableDescriptor
|
|
103
105
|
|
104
106
|
EventableDescriptor::~EventableDescriptor()
|
105
107
|
{
|
108
|
+
if (NextHeartbeat)
|
109
|
+
MyEventMachine->ClearHeartbeat(NextHeartbeat);
|
106
110
|
if (EventCallback && bCallbackUnbind)
|
107
111
|
(*EventCallback)(GetBinding(), EM_CONNECTION_UNBOUND, NULL, UnbindReasonCode);
|
108
112
|
if (ProxiedFrom) {
|
@@ -118,7 +122,7 @@ EventableDescriptor::~EventableDescriptor()
|
|
118
122
|
EventableDescriptor::SetEventCallback
|
119
123
|
*************************************/
|
120
124
|
|
121
|
-
void EventableDescriptor::SetEventCallback (
|
125
|
+
void EventableDescriptor::SetEventCallback (EMCallback cb)
|
122
126
|
{
|
123
127
|
EventCallback = cb;
|
124
128
|
}
|
@@ -133,7 +137,7 @@ void EventableDescriptor::Close()
|
|
133
137
|
// Close the socket right now. Intended for emergencies.
|
134
138
|
if (MySocket != INVALID_SOCKET) {
|
135
139
|
shutdown (MySocket, 1);
|
136
|
-
|
140
|
+
close (MySocket);
|
137
141
|
MySocket = INVALID_SOCKET;
|
138
142
|
}
|
139
143
|
}
|
@@ -187,12 +191,13 @@ bool EventableDescriptor::IsCloseScheduled()
|
|
187
191
|
EventableDescriptor::StartProxy
|
188
192
|
*******************************/
|
189
193
|
|
190
|
-
void EventableDescriptor::StartProxy(const unsigned long to, const unsigned long bufsize)
|
194
|
+
void EventableDescriptor::StartProxy(const unsigned long to, const unsigned long bufsize, const unsigned long length)
|
191
195
|
{
|
192
196
|
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (to));
|
193
197
|
if (ed) {
|
194
198
|
StopProxy();
|
195
199
|
ProxyTarget = ed;
|
200
|
+
BytesToProxy = length;
|
196
201
|
ed->SetProxiedFrom(this, bufsize);
|
197
202
|
return;
|
198
203
|
}
|
@@ -219,6 +224,9 @@ EventableDescriptor::SetProxiedFrom
|
|
219
224
|
|
220
225
|
void EventableDescriptor::SetProxiedFrom(EventableDescriptor *from, const unsigned long bufsize)
|
221
226
|
{
|
227
|
+
if (from != NULL && ProxiedFrom != NULL)
|
228
|
+
throw std::runtime_error ("Tried to proxy to a busy target");
|
229
|
+
|
222
230
|
ProxiedFrom = from;
|
223
231
|
MaxOutboundBufSize = bufsize;
|
224
232
|
}
|
@@ -232,10 +240,24 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
|
|
232
240
|
{
|
233
241
|
assert(EventCallback);
|
234
242
|
|
235
|
-
if (ProxyTarget)
|
236
|
-
|
237
|
-
|
243
|
+
if (ProxyTarget) {
|
244
|
+
if (BytesToProxy > 0) {
|
245
|
+
unsigned long proxied = min(BytesToProxy, (unsigned long) size);
|
246
|
+
ProxyTarget->SendOutboundData(buf, proxied);
|
247
|
+
BytesToProxy -= proxied;
|
248
|
+
if (BytesToProxy == 0) {
|
249
|
+
StopProxy();
|
250
|
+
(*EventCallback)(GetBinding(), EM_PROXY_COMPLETED, NULL, 0);
|
251
|
+
if (proxied < size) {
|
252
|
+
(*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf + proxied, size - proxied);
|
253
|
+
}
|
254
|
+
}
|
255
|
+
} else {
|
256
|
+
ProxyTarget->SendOutboundData(buf, size);
|
257
|
+
}
|
258
|
+
} else {
|
238
259
|
(*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf, size);
|
260
|
+
}
|
239
261
|
}
|
240
262
|
|
241
263
|
|
@@ -243,9 +265,9 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
|
|
243
265
|
EventableDescriptor::GetPendingConnectTimeout
|
244
266
|
*********************************************/
|
245
267
|
|
246
|
-
|
268
|
+
uint64_t EventableDescriptor::GetPendingConnectTimeout()
|
247
269
|
{
|
248
|
-
return
|
270
|
+
return PendingConnectTimeout / 1000;
|
249
271
|
}
|
250
272
|
|
251
273
|
|
@@ -253,16 +275,43 @@ float EventableDescriptor::GetPendingConnectTimeout()
|
|
253
275
|
EventableDescriptor::SetPendingConnectTimeout
|
254
276
|
*********************************************/
|
255
277
|
|
256
|
-
int EventableDescriptor::SetPendingConnectTimeout (
|
278
|
+
int EventableDescriptor::SetPendingConnectTimeout (uint64_t value)
|
257
279
|
{
|
258
280
|
if (value > 0) {
|
259
|
-
PendingConnectTimeout =
|
281
|
+
PendingConnectTimeout = value * 1000;
|
282
|
+
MyEventMachine->QueueHeartbeat(this);
|
260
283
|
return 1;
|
261
284
|
}
|
262
285
|
return 0;
|
263
286
|
}
|
264
287
|
|
265
288
|
|
289
|
+
/*************************************
|
290
|
+
EventableDescriptor::GetNextHeartbeat
|
291
|
+
*************************************/
|
292
|
+
|
293
|
+
uint64_t EventableDescriptor::GetNextHeartbeat()
|
294
|
+
{
|
295
|
+
if (NextHeartbeat)
|
296
|
+
MyEventMachine->ClearHeartbeat(NextHeartbeat);
|
297
|
+
|
298
|
+
NextHeartbeat = 0;
|
299
|
+
|
300
|
+
if (!ShouldDelete()) {
|
301
|
+
uint64_t time_til_next = GetCommInactivityTimeout() * 1000;
|
302
|
+
if (IsConnectPending()) {
|
303
|
+
if (time_til_next == 0 || PendingConnectTimeout < time_til_next)
|
304
|
+
time_til_next = PendingConnectTimeout;
|
305
|
+
}
|
306
|
+
if (time_til_next == 0)
|
307
|
+
return 0;
|
308
|
+
NextHeartbeat = time_til_next + MyEventMachine->GetRealTime();
|
309
|
+
}
|
310
|
+
|
311
|
+
return NextHeartbeat;
|
312
|
+
}
|
313
|
+
|
314
|
+
|
266
315
|
/******************************************
|
267
316
|
ConnectionDescriptor::ConnectionDescriptor
|
268
317
|
******************************************/
|
@@ -286,9 +335,7 @@ ConnectionDescriptor::ConnectionDescriptor (int sd, EventMachine_t *em):
|
|
286
335
|
#ifdef HAVE_KQUEUE
|
287
336
|
bGotExtraKqueueEvent(false),
|
288
337
|
#endif
|
289
|
-
bIsServer (false)
|
290
|
-
LastIo (gCurrentLoopTime),
|
291
|
-
InactivityTimeout (0)
|
338
|
+
bIsServer (false)
|
292
339
|
{
|
293
340
|
// 22Jan09: Moved ArmKqueueWriter into SetConnectPending() to fix assertion failure in _WriteOutboundData()
|
294
341
|
// 5May09: Moved EPOLLOUT into SetConnectPending() so it doesn't happen for attached read pipes
|
@@ -312,57 +359,6 @@ ConnectionDescriptor::~ConnectionDescriptor()
|
|
312
359
|
}
|
313
360
|
|
314
361
|
|
315
|
-
/**************************************************
|
316
|
-
STATIC: ConnectionDescriptor::SendDataToConnection
|
317
|
-
**************************************************/
|
318
|
-
|
319
|
-
int ConnectionDescriptor::SendDataToConnection (const unsigned long binding, const char *data, int data_length)
|
320
|
-
{
|
321
|
-
// TODO: This is something of a hack, or at least it's a static method of the wrong class.
|
322
|
-
// TODO: Poor polymorphism here. We should be calling one virtual method
|
323
|
-
// instead of hacking out the runtime information of the target object.
|
324
|
-
ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
|
325
|
-
if (cd)
|
326
|
-
return cd->SendOutboundData (data, data_length);
|
327
|
-
DatagramDescriptor *ds = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
|
328
|
-
if (ds)
|
329
|
-
return ds->SendOutboundData (data, data_length);
|
330
|
-
#ifdef OS_UNIX
|
331
|
-
PipeDescriptor *ps = dynamic_cast <PipeDescriptor*> (Bindable_t::GetObject (binding));
|
332
|
-
if (ps)
|
333
|
-
return ps->SendOutboundData (data, data_length);
|
334
|
-
#endif
|
335
|
-
return -1;
|
336
|
-
}
|
337
|
-
|
338
|
-
|
339
|
-
/*********************************************
|
340
|
-
STATIC: ConnectionDescriptor::CloseConnection
|
341
|
-
*********************************************/
|
342
|
-
|
343
|
-
void ConnectionDescriptor::CloseConnection (const unsigned long binding, bool after_writing)
|
344
|
-
{
|
345
|
-
// TODO: This is something of a hack, or at least it's a static method of the wrong class.
|
346
|
-
EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
|
347
|
-
if (ed)
|
348
|
-
ed->ScheduleClose (after_writing);
|
349
|
-
}
|
350
|
-
|
351
|
-
/***********************************************
|
352
|
-
STATIC: ConnectionDescriptor::ReportErrorStatus
|
353
|
-
***********************************************/
|
354
|
-
|
355
|
-
int ConnectionDescriptor::ReportErrorStatus (const unsigned long binding)
|
356
|
-
{
|
357
|
-
// TODO: This is something of a hack, or at least it's a static method of the wrong class.
|
358
|
-
// TODO: Poor polymorphism here. We should be calling one virtual method
|
359
|
-
// instead of hacking out the runtime information of the target object.
|
360
|
-
ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
|
361
|
-
if (cd)
|
362
|
-
return cd->_ReportErrorStatus();
|
363
|
-
return -1;
|
364
|
-
}
|
365
|
-
|
366
362
|
/***********************************
|
367
363
|
ConnectionDescriptor::_UpdateEvents
|
368
364
|
************************************/
|
@@ -500,7 +496,7 @@ int ConnectionDescriptor::SendOutboundData (const char *data, int length)
|
|
500
496
|
if (bWatchOnly)
|
501
497
|
throw std::runtime_error ("cannot send data on a 'watch only' connection");
|
502
498
|
|
503
|
-
if (ProxiedFrom && MaxOutboundBufSize && GetOutboundDataSize() + length > MaxOutboundBufSize)
|
499
|
+
if (ProxiedFrom && MaxOutboundBufSize && (unsigned int)(GetOutboundDataSize() + length) > MaxOutboundBufSize)
|
504
500
|
ProxiedFrom->Pause();
|
505
501
|
|
506
502
|
#ifdef WITH_SSL
|
@@ -541,7 +537,11 @@ int ConnectionDescriptor::_SendRawOutboundData (const char *data, int length)
|
|
541
537
|
// (Well, not so bad, small pages are coalesced in ::Write)
|
542
538
|
|
543
539
|
if (IsCloseScheduled())
|
544
|
-
|
540
|
+
return 0;
|
541
|
+
|
542
|
+
// 25Mar10: Ignore 0 length packets as they are not meaningful in TCP (as opposed to UDP)
|
543
|
+
// and can cause the assert(nbytes>0) to fail when OutboundPages has a bunch of 0 length pages.
|
544
|
+
if (length == 0)
|
545
545
|
return 0;
|
546
546
|
|
547
547
|
if (!data && (length > 0))
|
@@ -688,7 +688,7 @@ void ConnectionDescriptor::Read()
|
|
688
688
|
return;
|
689
689
|
}
|
690
690
|
|
691
|
-
|
691
|
+
LastActivity = MyEventMachine->GetCurrentLoopTime();
|
692
692
|
|
693
693
|
int total_bytes_read = 0;
|
694
694
|
char readbuffer [16 * 1024 + 1];
|
@@ -894,7 +894,7 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
894
894
|
return;
|
895
895
|
}
|
896
896
|
|
897
|
-
|
897
|
+
LastActivity = MyEventMachine->GetCurrentLoopTime();
|
898
898
|
size_t nbytes = 0;
|
899
899
|
|
900
900
|
#ifdef HAVE_WRITEV
|
@@ -902,11 +902,19 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
902
902
|
// Max of 16 outbound pages at a time
|
903
903
|
if (iovcnt > 16) iovcnt = 16;
|
904
904
|
|
905
|
+
#ifdef CC_SUNWspro
|
906
|
+
struct iovec iov[16];
|
907
|
+
#else
|
905
908
|
struct iovec iov[ iovcnt ];
|
909
|
+
#endif
|
906
910
|
|
907
911
|
for(int i = 0; i < iovcnt; i++){
|
908
912
|
OutboundPage *op = &(OutboundPages[i]);
|
913
|
+
#ifdef CC_SUNWspro
|
914
|
+
iov[i].iov_base = (char *)(op->Buffer + op->Offset);
|
915
|
+
#else
|
909
916
|
iov[i].iov_base = (void *)(op->Buffer + op->Offset);
|
917
|
+
#endif
|
910
918
|
iov[i].iov_len = op->Length - op->Offset;
|
911
919
|
|
912
920
|
nbytes += iov[i].iov_len;
|
@@ -953,7 +961,7 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
953
961
|
assert (bytes_written >= 0);
|
954
962
|
OutboundDataSize -= bytes_written;
|
955
963
|
|
956
|
-
if (ProxiedFrom && MaxOutboundBufSize && GetOutboundDataSize() < MaxOutboundBufSize && ProxiedFrom->IsPaused())
|
964
|
+
if (ProxiedFrom && MaxOutboundBufSize && (unsigned int)GetOutboundDataSize() < MaxOutboundBufSize && ProxiedFrom->IsPaused())
|
957
965
|
ProxiedFrom->Resume();
|
958
966
|
|
959
967
|
#ifdef HAVE_WRITEV
|
@@ -1005,11 +1013,11 @@ void ConnectionDescriptor::_WriteOutboundData()
|
|
1005
1013
|
}
|
1006
1014
|
|
1007
1015
|
|
1008
|
-
|
1009
|
-
ConnectionDescriptor::
|
1010
|
-
|
1016
|
+
/***************************************
|
1017
|
+
ConnectionDescriptor::ReportErrorStatus
|
1018
|
+
***************************************/
|
1011
1019
|
|
1012
|
-
int ConnectionDescriptor::
|
1020
|
+
int ConnectionDescriptor::ReportErrorStatus()
|
1013
1021
|
{
|
1014
1022
|
int error;
|
1015
1023
|
socklen_t len;
|
@@ -1190,12 +1198,12 @@ void ConnectionDescriptor::Heartbeat()
|
|
1190
1198
|
*/
|
1191
1199
|
|
1192
1200
|
if (bConnectPending) {
|
1193
|
-
if ((
|
1201
|
+
if ((MyEventMachine->GetCurrentLoopTime() - CreatedAt) >= PendingConnectTimeout)
|
1194
1202
|
ScheduleClose (false);
|
1195
1203
|
//bCloseNow = true;
|
1196
1204
|
}
|
1197
1205
|
else {
|
1198
|
-
if (InactivityTimeout && ((
|
1206
|
+
if (InactivityTimeout && ((MyEventMachine->GetCurrentLoopTime() - LastActivity) >= InactivityTimeout))
|
1199
1207
|
ScheduleClose (false);
|
1200
1208
|
//bCloseNow = true;
|
1201
1209
|
}
|
@@ -1328,7 +1336,7 @@ void AcceptorDescriptor::Read()
|
|
1328
1336
|
//int val = fcntl (sd, F_GETFL, 0);
|
1329
1337
|
//if (fcntl (sd, F_SETFL, val | O_NONBLOCK) == -1) {
|
1330
1338
|
shutdown (sd, 1);
|
1331
|
-
|
1339
|
+
close (sd);
|
1332
1340
|
continue;
|
1333
1341
|
}
|
1334
1342
|
|
@@ -1405,9 +1413,7 @@ DatagramDescriptor::DatagramDescriptor
|
|
1405
1413
|
|
1406
1414
|
DatagramDescriptor::DatagramDescriptor (int sd, EventMachine_t *parent_em):
|
1407
1415
|
EventableDescriptor (sd, parent_em),
|
1408
|
-
OutboundDataSize (0)
|
1409
|
-
LastIo (gCurrentLoopTime),
|
1410
|
-
InactivityTimeout (0)
|
1416
|
+
OutboundDataSize (0)
|
1411
1417
|
{
|
1412
1418
|
memset (&ReturnAddress, 0, sizeof(ReturnAddress));
|
1413
1419
|
|
@@ -1461,7 +1467,7 @@ void DatagramDescriptor::Heartbeat()
|
|
1461
1467
|
{
|
1462
1468
|
// Close it if its inactivity timer has expired.
|
1463
1469
|
|
1464
|
-
if (InactivityTimeout && ((
|
1470
|
+
if (InactivityTimeout && ((MyEventMachine->GetCurrentLoopTime() - LastActivity) >= InactivityTimeout))
|
1465
1471
|
ScheduleClose (false);
|
1466
1472
|
//bCloseNow = true;
|
1467
1473
|
}
|
@@ -1475,7 +1481,7 @@ void DatagramDescriptor::Read()
|
|
1475
1481
|
{
|
1476
1482
|
int sd = GetSocket();
|
1477
1483
|
assert (sd != INVALID_SOCKET);
|
1478
|
-
|
1484
|
+
LastActivity = MyEventMachine->GetCurrentLoopTime();
|
1479
1485
|
|
1480
1486
|
// This is an extremely large read buffer.
|
1481
1487
|
// In many cases you wouldn't expect to get any more than 4K.
|
@@ -1552,7 +1558,7 @@ void DatagramDescriptor::Write()
|
|
1552
1558
|
|
1553
1559
|
int sd = GetSocket();
|
1554
1560
|
assert (sd != INVALID_SOCKET);
|
1555
|
-
|
1561
|
+
LastActivity = MyEventMachine->GetCurrentLoopTime();
|
1556
1562
|
|
1557
1563
|
assert (OutboundPages.size() > 0);
|
1558
1564
|
|
@@ -1618,11 +1624,11 @@ DatagramDescriptor::SendOutboundData
|
|
1618
1624
|
|
1619
1625
|
int DatagramDescriptor::SendOutboundData (const char *data, int length)
|
1620
1626
|
{
|
1621
|
-
// This is an exact clone of ConnectionDescriptor::
|
1622
|
-
// That means it
|
1627
|
+
// This is almost an exact clone of ConnectionDescriptor::_SendRawOutboundData.
|
1628
|
+
// That means most of it could be factored to a common ancestor. Note that
|
1629
|
+
// empty datagrams are meaningful, which isn't the case for TCP streams.
|
1623
1630
|
|
1624
1631
|
if (IsCloseScheduled())
|
1625
|
-
//if (bCloseNow || bCloseAfterWriting)
|
1626
1632
|
return 0;
|
1627
1633
|
|
1628
1634
|
if (!data && (length > 0))
|
@@ -1706,20 +1712,6 @@ int DatagramDescriptor::SendOutboundDatagram (const char *data, int length, cons
|
|
1706
1712
|
}
|
1707
1713
|
|
1708
1714
|
|
1709
|
-
/****************************************
|
1710
|
-
STATIC: DatagramDescriptor::SendDatagram
|
1711
|
-
****************************************/
|
1712
|
-
|
1713
|
-
int DatagramDescriptor::SendDatagram (const unsigned long binding, const char *data, int length, const char *address, int port)
|
1714
|
-
{
|
1715
|
-
DatagramDescriptor *dd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
|
1716
|
-
if (dd)
|
1717
|
-
return dd->SendOutboundDatagram (data, length, address, port);
|
1718
|
-
else
|
1719
|
-
return -1;
|
1720
|
-
}
|
1721
|
-
|
1722
|
-
|
1723
1715
|
/*********************************
|
1724
1716
|
ConnectionDescriptor::GetPeername
|
1725
1717
|
*********************************/
|
@@ -1757,9 +1749,9 @@ bool ConnectionDescriptor::GetSockname (struct sockaddr *s)
|
|
1757
1749
|
ConnectionDescriptor::GetCommInactivityTimeout
|
1758
1750
|
**********************************************/
|
1759
1751
|
|
1760
|
-
|
1752
|
+
uint64_t ConnectionDescriptor::GetCommInactivityTimeout()
|
1761
1753
|
{
|
1762
|
-
return
|
1754
|
+
return InactivityTimeout / 1000;
|
1763
1755
|
}
|
1764
1756
|
|
1765
1757
|
|
@@ -1767,13 +1759,11 @@ float ConnectionDescriptor::GetCommInactivityTimeout()
|
|
1767
1759
|
ConnectionDescriptor::SetCommInactivityTimeout
|
1768
1760
|
**********************************************/
|
1769
1761
|
|
1770
|
-
int ConnectionDescriptor::SetCommInactivityTimeout (
|
1762
|
+
int ConnectionDescriptor::SetCommInactivityTimeout (uint64_t value)
|
1771
1763
|
{
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
}
|
1776
|
-
return 0;
|
1764
|
+
InactivityTimeout = value * 1000;
|
1765
|
+
MyEventMachine->QueueHeartbeat(this);
|
1766
|
+
return 1;
|
1777
1767
|
}
|
1778
1768
|
|
1779
1769
|
/*******************************
|
@@ -1813,19 +1803,20 @@ bool DatagramDescriptor::GetSockname (struct sockaddr *s)
|
|
1813
1803
|
DatagramDescriptor::GetCommInactivityTimeout
|
1814
1804
|
********************************************/
|
1815
1805
|
|
1816
|
-
|
1806
|
+
uint64_t DatagramDescriptor::GetCommInactivityTimeout()
|
1817
1807
|
{
|
1818
|
-
return
|
1808
|
+
return InactivityTimeout / 1000;
|
1819
1809
|
}
|
1820
1810
|
|
1821
1811
|
/********************************************
|
1822
1812
|
DatagramDescriptor::SetCommInactivityTimeout
|
1823
1813
|
********************************************/
|
1824
1814
|
|
1825
|
-
int DatagramDescriptor::SetCommInactivityTimeout (
|
1815
|
+
int DatagramDescriptor::SetCommInactivityTimeout (uint64_t value)
|
1826
1816
|
{
|
1827
1817
|
if (value > 0) {
|
1828
|
-
InactivityTimeout =
|
1818
|
+
InactivityTimeout = value * 1000;
|
1819
|
+
MyEventMachine->QueueHeartbeat(this);
|
1829
1820
|
return 1;
|
1830
1821
|
}
|
1831
1822
|
return 0;
|