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.
Files changed (69) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +1 -0
  3. data/README +1 -2
  4. data/Rakefile +4 -76
  5. data/docs/DEFERRABLES +183 -70
  6. data/docs/KEYBOARD +15 -11
  7. data/docs/LIGHTWEIGHT_CONCURRENCY +84 -24
  8. data/docs/SMTP +3 -1
  9. data/docs/SPAWNED_PROCESSES +84 -25
  10. data/eventmachine.gemspec +19 -26
  11. data/examples/ex_tick_loop_array.rb +15 -0
  12. data/examples/ex_tick_loop_counter.rb +32 -0
  13. data/ext/binder.cpp +0 -1
  14. data/ext/cmain.cpp +36 -11
  15. data/ext/cplusplus.cpp +1 -1
  16. data/ext/ed.cpp +104 -113
  17. data/ext/ed.h +24 -30
  18. data/ext/em.cpp +347 -248
  19. data/ext/em.h +23 -16
  20. data/ext/eventmachine.h +5 -3
  21. data/ext/extconf.rb +5 -3
  22. data/ext/fastfilereader/extconf.rb +5 -3
  23. data/ext/fastfilereader/mapper.cpp +1 -1
  24. data/ext/kb.cpp +1 -3
  25. data/ext/pipe.cpp +9 -11
  26. data/ext/project.h +12 -4
  27. data/ext/rubymain.cpp +138 -89
  28. data/java/src/com/rubyeventmachine/EmReactor.java +1 -0
  29. data/lib/em/channel.rb +1 -1
  30. data/lib/em/connection.rb +6 -1
  31. data/lib/em/deferrable.rb +16 -2
  32. data/lib/em/iterator.rb +270 -0
  33. data/lib/em/protocols.rb +1 -1
  34. data/lib/em/protocols/httpclient.rb +5 -0
  35. data/lib/em/protocols/line_protocol.rb +28 -0
  36. data/lib/em/protocols/smtpserver.rb +101 -8
  37. data/lib/em/protocols/stomp.rb +1 -1
  38. data/lib/{pr_eventmachine.rb → em/pure_ruby.rb} +1 -11
  39. data/lib/em/queue.rb +1 -0
  40. data/lib/em/streamer.rb +1 -1
  41. data/lib/em/tick_loop.rb +85 -0
  42. data/lib/em/timers.rb +2 -1
  43. data/lib/em/version.rb +1 -1
  44. data/lib/eventmachine.rb +38 -84
  45. data/lib/jeventmachine.rb +1 -0
  46. data/tests/test_attach.rb +13 -3
  47. data/tests/test_basic.rb +60 -95
  48. data/tests/test_channel.rb +3 -2
  49. data/tests/test_defer.rb +14 -12
  50. data/tests/test_deferrable.rb +35 -0
  51. data/tests/test_file_watch.rb +1 -1
  52. data/tests/test_futures.rb +1 -1
  53. data/tests/test_hc.rb +40 -68
  54. data/tests/test_httpclient.rb +15 -6
  55. data/tests/test_httpclient2.rb +3 -2
  56. data/tests/test_inactivity_timeout.rb +3 -3
  57. data/tests/test_ltp.rb +13 -5
  58. data/tests/test_next_tick.rb +1 -1
  59. data/tests/test_pending_connect_timeout.rb +2 -2
  60. data/tests/test_process_watch.rb +36 -34
  61. data/tests/test_proxy_connection.rb +52 -0
  62. data/tests/test_pure.rb +10 -1
  63. data/tests/test_sasl.rb +1 -1
  64. data/tests/test_send_file.rb +16 -7
  65. data/tests/test_servers.rb +1 -1
  66. data/tests/test_tick_loop.rb +59 -0
  67. data/tests/test_timers.rb +13 -15
  68. metadata +45 -17
  69. data/web/whatis +0 -7
@@ -31,7 +31,6 @@ STATIC Bindable_t::CreateBinding
31
31
 
32
32
  unsigned long Bindable_t::CreateBinding()
33
33
  {
34
- // XXX use atomic_t to prevent thread-safety issues
35
34
  static unsigned long num = 0;
36
35
  while(BindingBag[++num]);
37
36
  return num;
@@ -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 (void(*cb)(const unsigned long, int, const char*, const unsigned long))
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
- return ConnectionDescriptor::SendDataToConnection (binding, data, data_length);
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
- return DatagramDescriptor::SendDatagram (binding, data, data_length, address, port);
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
- ConnectionDescriptor::CloseConnection (binding, (after_writing ? true : false));
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
- return ConnectionDescriptor::ReportErrorStatus (binding);
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
+ }
@@ -34,7 +34,7 @@ EM::Run
34
34
  void EM::Run (void (*start_func)())
35
35
  {
36
36
  evma_set_epoll (1);
37
- evma_initialize_library (EM::Callback);
37
+ evma_initialize_library ((EMCallback)EM::Callback);
38
38
  if (start_func)
39
39
  AddTimer (0, start_func);
40
40
  evma_run_machine();
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 = gCurrentLoopTime;
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 (void(*cb)(const unsigned long, int, const char*, const unsigned long))
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
- closesocket (MySocket);
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
- ProxyTarget->SendOutboundData(buf, size);
237
- else
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
- float EventableDescriptor::GetPendingConnectTimeout()
268
+ uint64_t EventableDescriptor::GetPendingConnectTimeout()
247
269
  {
248
- return ((float)PendingConnectTimeout / 1000000);
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 (float value)
278
+ int EventableDescriptor::SetPendingConnectTimeout (uint64_t value)
257
279
  {
258
280
  if (value > 0) {
259
- PendingConnectTimeout = (Int64)(value * 1000000);
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
- //if (bCloseNow || bCloseAfterWriting)
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
- LastIo = gCurrentLoopTime;
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
- LastIo = gCurrentLoopTime;
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::_ReportErrorStatus
1010
- ****************************************/
1016
+ /***************************************
1017
+ ConnectionDescriptor::ReportErrorStatus
1018
+ ***************************************/
1011
1019
 
1012
- int ConnectionDescriptor::_ReportErrorStatus()
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 ((gCurrentLoopTime - CreatedAt) >= PendingConnectTimeout)
1201
+ if ((MyEventMachine->GetCurrentLoopTime() - CreatedAt) >= PendingConnectTimeout)
1194
1202
  ScheduleClose (false);
1195
1203
  //bCloseNow = true;
1196
1204
  }
1197
1205
  else {
1198
- if (InactivityTimeout && ((gCurrentLoopTime - LastIo) >= 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
- closesocket (sd);
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 && ((gCurrentLoopTime - LastIo) >= 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
- LastIo = gCurrentLoopTime;
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
- LastIo = gCurrentLoopTime;
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::SendOutboundData.
1622
- // That means it needs to move to a common ancestor.
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
- float ConnectionDescriptor::GetCommInactivityTimeout()
1752
+ uint64_t ConnectionDescriptor::GetCommInactivityTimeout()
1761
1753
  {
1762
- return ((float)InactivityTimeout / 1000000);
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 (float value)
1762
+ int ConnectionDescriptor::SetCommInactivityTimeout (uint64_t value)
1771
1763
  {
1772
- if (value > 0) {
1773
- InactivityTimeout = (Int64)(value * 1000000);
1774
- return 1;
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
- float DatagramDescriptor::GetCommInactivityTimeout()
1806
+ uint64_t DatagramDescriptor::GetCommInactivityTimeout()
1817
1807
  {
1818
- return ((float)InactivityTimeout / 1000000);
1808
+ return InactivityTimeout / 1000;
1819
1809
  }
1820
1810
 
1821
1811
  /********************************************
1822
1812
  DatagramDescriptor::SetCommInactivityTimeout
1823
1813
  ********************************************/
1824
1814
 
1825
- int DatagramDescriptor::SetCommInactivityTimeout (float value)
1815
+ int DatagramDescriptor::SetCommInactivityTimeout (uint64_t value)
1826
1816
  {
1827
1817
  if (value > 0) {
1828
- InactivityTimeout = (Int64)(value * 1000000);
1818
+ InactivityTimeout = value * 1000;
1819
+ MyEventMachine->QueueHeartbeat(this);
1829
1820
  return 1;
1830
1821
  }
1831
1822
  return 0;