eventmachine 0.12.10 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
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;