smparkes-eventmachine 0.12.10.2 → 0.12.10.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -13,4 +13,5 @@ Makefile
13
13
  *.pdb
14
14
  *.dSYM
15
15
  java/src/.project
16
- /*eventmachine*.gem
16
+ /*eventmachine*.gem
17
+ *.rbc
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{smparkes-eventmachine}
5
- s.version = "0.12.10.2"
5
+ s.version = "0.12.10.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Francis Cianfrocca"]
@@ -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;
@@ -148,6 +148,7 @@ extern "C" int evma_detach_fd (const unsigned long binding)
148
148
  #else
149
149
  throw std::runtime_error ("invalid binding to detach");
150
150
  #endif
151
+ return -1;
151
152
  }
152
153
 
153
154
  /************************
@@ -166,6 +167,7 @@ extern "C" int evma_get_file_descriptor (const unsigned long binding)
166
167
  #else
167
168
  throw std::runtime_error ("invalid binding to get_fd");
168
169
  #endif
170
+ return -1;
169
171
  }
170
172
 
171
173
  /***********************
@@ -340,7 +342,10 @@ evma_send_data_to_connection
340
342
  extern "C" int evma_send_data_to_connection (const unsigned long binding, const char *data, int data_length)
341
343
  {
342
344
  ensure_eventmachine("evma_send_data_to_connection");
343
- return ConnectionDescriptor::SendDataToConnection (binding, data, data_length);
345
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
346
+ if (ed)
347
+ return ed->SendOutboundData(data, data_length);
348
+ return -1;
344
349
  }
345
350
 
346
351
  /******************
@@ -350,7 +355,10 @@ evma_send_datagram
350
355
  extern "C" int evma_send_datagram (const unsigned long binding, const char *data, int data_length, const char *address, int port)
351
356
  {
352
357
  ensure_eventmachine("evma_send_datagram");
353
- return DatagramDescriptor::SendDatagram (binding, data, data_length, address, port);
358
+ DatagramDescriptor *dd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
359
+ if (dd)
360
+ return dd->SendOutboundDatagram(data, data_length, address, port);
361
+ return -1;
354
362
  }
355
363
 
356
364
 
@@ -361,7 +369,9 @@ evma_close_connection
361
369
  extern "C" void evma_close_connection (const unsigned long binding, int after_writing)
362
370
  {
363
371
  ensure_eventmachine("evma_close_connection");
364
- ConnectionDescriptor::CloseConnection (binding, (after_writing ? true : false));
372
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
373
+ if (ed)
374
+ ed->ScheduleClose (after_writing ? true : false);
365
375
  }
366
376
 
367
377
  /***********************************
@@ -371,7 +381,10 @@ evma_report_connection_error_status
371
381
  extern "C" int evma_report_connection_error_status (const unsigned long binding)
372
382
  {
373
383
  ensure_eventmachine("evma_report_connection_error_status");
374
- return ConnectionDescriptor::ReportErrorStatus (binding);
384
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
385
+ if (ed)
386
+ return ed->ReportErrorStatus();
387
+ return -1;
375
388
  }
376
389
 
377
390
  /********************
@@ -559,7 +572,7 @@ extern "C" float evma_get_comm_inactivity_timeout (const unsigned long binding)
559
572
  ensure_eventmachine("evma_get_comm_inactivity_timeout");
560
573
  EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
561
574
  if (ed) {
562
- return ed->GetCommInactivityTimeout();
575
+ return ((float)ed->GetCommInactivityTimeout() / 1000);
563
576
  }
564
577
  else
565
578
  return 0.0; //Perhaps this should be an exception. Access to an unknown binding.
@@ -574,7 +587,7 @@ extern "C" int evma_set_comm_inactivity_timeout (const unsigned long binding, fl
574
587
  ensure_eventmachine("evma_set_comm_inactivity_timeout");
575
588
  EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
576
589
  if (ed) {
577
- return ed->SetCommInactivityTimeout (value);
590
+ return ed->SetCommInactivityTimeout ((uint64_t)(value * 1000));
578
591
  }
579
592
  else
580
593
  return 0; //Perhaps this should be an exception. Access to an unknown binding.
@@ -590,7 +603,7 @@ extern "C" float evma_get_pending_connect_timeout (const unsigned long binding)
590
603
  ensure_eventmachine("evma_get_pending_connect_timeout");
591
604
  EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
592
605
  if (ed) {
593
- return ed->GetPendingConnectTimeout();
606
+ return ((float)ed->GetPendingConnectTimeout() / 1000);
594
607
  }
595
608
  else
596
609
  return 0.0;
@@ -606,7 +619,7 @@ extern "C" int evma_set_pending_connect_timeout (const unsigned long binding, fl
606
619
  ensure_eventmachine("evma_set_pending_connect_timeout");
607
620
  EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
608
621
  if (ed) {
609
- return ed->SetPendingConnectTimeout (value);
622
+ return ed->SetPendingConnectTimeout ((uint64_t)(value * 1000));
610
623
  }
611
624
  else
612
625
  return 0;
@@ -825,3 +838,14 @@ extern "C" int evma_set_heartbeat_interval(float interval)
825
838
  ensure_eventmachine("evma_set_heartbeat_interval");
826
839
  return EventMachine->SetHeartbeatInterval(interval);
827
840
  }
841
+
842
+
843
+ /**************************
844
+ evma_get_current_loop_time
845
+ ***************************/
846
+
847
+ extern "C" uint64_t evma_get_current_loop_time()
848
+ {
849
+ ensure_eventmachine("evma_get_current_loop_time");
850
+ return EventMachine->GetCurrentTime();
851
+ }
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->GetCurrentTime();
92
93
 
93
94
  #ifdef HAVE_EPOLL
94
95
  EpollEvent.events = 0;
95
96
  EpollEvent.data.ptr = this;
96
97
  #endif
98
+ LastActivity = MyEventMachine->GetCurrentTime();
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) {
@@ -243,9 +247,9 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
243
247
  EventableDescriptor::GetPendingConnectTimeout
244
248
  *********************************************/
245
249
 
246
- float EventableDescriptor::GetPendingConnectTimeout()
250
+ uint64_t EventableDescriptor::GetPendingConnectTimeout()
247
251
  {
248
- return ((float)PendingConnectTimeout / 1000000);
252
+ return PendingConnectTimeout / 1000;
249
253
  }
250
254
 
251
255
 
@@ -253,16 +257,43 @@ float EventableDescriptor::GetPendingConnectTimeout()
253
257
  EventableDescriptor::SetPendingConnectTimeout
254
258
  *********************************************/
255
259
 
256
- int EventableDescriptor::SetPendingConnectTimeout (float value)
260
+ int EventableDescriptor::SetPendingConnectTimeout (uint64_t value)
257
261
  {
258
262
  if (value > 0) {
259
- PendingConnectTimeout = (Int64)(value * 1000000);
263
+ PendingConnectTimeout = value * 1000;
264
+ MyEventMachine->QueueHeartbeat(this);
260
265
  return 1;
261
266
  }
262
267
  return 0;
263
268
  }
264
269
 
265
270
 
271
+ /*************************************
272
+ EventableDescriptor::GetNextHeartbeat
273
+ *************************************/
274
+
275
+ uint64_t EventableDescriptor::GetNextHeartbeat()
276
+ {
277
+ if (NextHeartbeat)
278
+ MyEventMachine->ClearHeartbeat(NextHeartbeat);
279
+
280
+ NextHeartbeat = 0;
281
+
282
+ if (!ShouldDelete()) {
283
+ uint64_t time_til_next = GetCommInactivityTimeout() * 1000;
284
+ if (IsConnectPending()) {
285
+ if (time_til_next == 0 || PendingConnectTimeout < time_til_next)
286
+ time_til_next = PendingConnectTimeout;
287
+ }
288
+ if (time_til_next == 0)
289
+ return 0;
290
+ NextHeartbeat = time_til_next + MyEventMachine->GetRealTime();
291
+ }
292
+
293
+ return NextHeartbeat;
294
+ }
295
+
296
+
266
297
  /******************************************
267
298
  ConnectionDescriptor::ConnectionDescriptor
268
299
  ******************************************/
@@ -286,9 +317,7 @@ ConnectionDescriptor::ConnectionDescriptor (int sd, EventMachine_t *em):
286
317
  #ifdef HAVE_KQUEUE
287
318
  bGotExtraKqueueEvent(false),
288
319
  #endif
289
- bIsServer (false),
290
- LastIo (gCurrentLoopTime),
291
- InactivityTimeout (0)
320
+ bIsServer (false)
292
321
  {
293
322
  // 22Jan09: Moved ArmKqueueWriter into SetConnectPending() to fix assertion failure in _WriteOutboundData()
294
323
  // 5May09: Moved EPOLLOUT into SetConnectPending() so it doesn't happen for attached read pipes
@@ -312,57 +341,6 @@ ConnectionDescriptor::~ConnectionDescriptor()
312
341
  }
313
342
 
314
343
 
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
344
  /***********************************
367
345
  ConnectionDescriptor::_UpdateEvents
368
346
  ************************************/
@@ -500,7 +478,7 @@ int ConnectionDescriptor::SendOutboundData (const char *data, int length)
500
478
  if (bWatchOnly)
501
479
  throw std::runtime_error ("cannot send data on a 'watch only' connection");
502
480
 
503
- if (ProxiedFrom && MaxOutboundBufSize && GetOutboundDataSize() + length > MaxOutboundBufSize)
481
+ if (ProxiedFrom && MaxOutboundBufSize && (unsigned int)(GetOutboundDataSize() + length) > MaxOutboundBufSize)
504
482
  ProxiedFrom->Pause();
505
483
 
506
484
  #ifdef WITH_SSL
@@ -688,7 +666,7 @@ void ConnectionDescriptor::Read()
688
666
  return;
689
667
  }
690
668
 
691
- LastIo = gCurrentLoopTime;
669
+ LastActivity = MyEventMachine->GetCurrentTime();
692
670
 
693
671
  int total_bytes_read = 0;
694
672
  char readbuffer [16 * 1024 + 1];
@@ -894,7 +872,7 @@ void ConnectionDescriptor::_WriteOutboundData()
894
872
  return;
895
873
  }
896
874
 
897
- LastIo = gCurrentLoopTime;
875
+ LastActivity = MyEventMachine->GetCurrentTime();
898
876
  size_t nbytes = 0;
899
877
 
900
878
  #ifdef HAVE_WRITEV
@@ -961,7 +939,7 @@ void ConnectionDescriptor::_WriteOutboundData()
961
939
  assert (bytes_written >= 0);
962
940
  OutboundDataSize -= bytes_written;
963
941
 
964
- if (ProxiedFrom && MaxOutboundBufSize && GetOutboundDataSize() < MaxOutboundBufSize && ProxiedFrom->IsPaused())
942
+ if (ProxiedFrom && MaxOutboundBufSize && (unsigned int)GetOutboundDataSize() < MaxOutboundBufSize && ProxiedFrom->IsPaused())
965
943
  ProxiedFrom->Resume();
966
944
 
967
945
  #ifdef HAVE_WRITEV
@@ -1013,11 +991,11 @@ void ConnectionDescriptor::_WriteOutboundData()
1013
991
  }
1014
992
 
1015
993
 
1016
- /****************************************
1017
- ConnectionDescriptor::_ReportErrorStatus
1018
- ****************************************/
994
+ /***************************************
995
+ ConnectionDescriptor::ReportErrorStatus
996
+ ***************************************/
1019
997
 
1020
- int ConnectionDescriptor::_ReportErrorStatus()
998
+ int ConnectionDescriptor::ReportErrorStatus()
1021
999
  {
1022
1000
  int error;
1023
1001
  socklen_t len;
@@ -1198,12 +1176,12 @@ void ConnectionDescriptor::Heartbeat()
1198
1176
  */
1199
1177
 
1200
1178
  if (bConnectPending) {
1201
- if ((gCurrentLoopTime - CreatedAt) >= PendingConnectTimeout)
1179
+ if ((MyEventMachine->GetCurrentTime() - CreatedAt) >= PendingConnectTimeout)
1202
1180
  ScheduleClose (false);
1203
1181
  //bCloseNow = true;
1204
1182
  }
1205
1183
  else {
1206
- if (InactivityTimeout && ((gCurrentLoopTime - LastIo) >= InactivityTimeout))
1184
+ if (InactivityTimeout && ((MyEventMachine->GetCurrentTime() - LastActivity) >= InactivityTimeout))
1207
1185
  ScheduleClose (false);
1208
1186
  //bCloseNow = true;
1209
1187
  }
@@ -1413,9 +1391,7 @@ DatagramDescriptor::DatagramDescriptor
1413
1391
 
1414
1392
  DatagramDescriptor::DatagramDescriptor (int sd, EventMachine_t *parent_em):
1415
1393
  EventableDescriptor (sd, parent_em),
1416
- OutboundDataSize (0),
1417
- LastIo (gCurrentLoopTime),
1418
- InactivityTimeout (0)
1394
+ OutboundDataSize (0)
1419
1395
  {
1420
1396
  memset (&ReturnAddress, 0, sizeof(ReturnAddress));
1421
1397
 
@@ -1469,7 +1445,7 @@ void DatagramDescriptor::Heartbeat()
1469
1445
  {
1470
1446
  // Close it if its inactivity timer has expired.
1471
1447
 
1472
- if (InactivityTimeout && ((gCurrentLoopTime - LastIo) >= InactivityTimeout))
1448
+ if (InactivityTimeout && ((MyEventMachine->GetCurrentTime() - LastActivity) >= InactivityTimeout))
1473
1449
  ScheduleClose (false);
1474
1450
  //bCloseNow = true;
1475
1451
  }
@@ -1483,7 +1459,7 @@ void DatagramDescriptor::Read()
1483
1459
  {
1484
1460
  int sd = GetSocket();
1485
1461
  assert (sd != INVALID_SOCKET);
1486
- LastIo = gCurrentLoopTime;
1462
+ LastActivity = MyEventMachine->GetCurrentTime();
1487
1463
 
1488
1464
  // This is an extremely large read buffer.
1489
1465
  // In many cases you wouldn't expect to get any more than 4K.
@@ -1560,7 +1536,7 @@ void DatagramDescriptor::Write()
1560
1536
 
1561
1537
  int sd = GetSocket();
1562
1538
  assert (sd != INVALID_SOCKET);
1563
- LastIo = gCurrentLoopTime;
1539
+ LastActivity = MyEventMachine->GetCurrentTime();
1564
1540
 
1565
1541
  assert (OutboundPages.size() > 0);
1566
1542
 
@@ -1714,20 +1690,6 @@ int DatagramDescriptor::SendOutboundDatagram (const char *data, int length, cons
1714
1690
  }
1715
1691
 
1716
1692
 
1717
- /****************************************
1718
- STATIC: DatagramDescriptor::SendDatagram
1719
- ****************************************/
1720
-
1721
- int DatagramDescriptor::SendDatagram (const unsigned long binding, const char *data, int length, const char *address, int port)
1722
- {
1723
- DatagramDescriptor *dd = dynamic_cast <DatagramDescriptor*> (Bindable_t::GetObject (binding));
1724
- if (dd)
1725
- return dd->SendOutboundDatagram (data, length, address, port);
1726
- else
1727
- return -1;
1728
- }
1729
-
1730
-
1731
1693
  /*********************************
1732
1694
  ConnectionDescriptor::GetPeername
1733
1695
  *********************************/
@@ -1765,9 +1727,9 @@ bool ConnectionDescriptor::GetSockname (struct sockaddr *s)
1765
1727
  ConnectionDescriptor::GetCommInactivityTimeout
1766
1728
  **********************************************/
1767
1729
 
1768
- float ConnectionDescriptor::GetCommInactivityTimeout()
1730
+ uint64_t ConnectionDescriptor::GetCommInactivityTimeout()
1769
1731
  {
1770
- return ((float)InactivityTimeout / 1000000);
1732
+ return InactivityTimeout / 1000;
1771
1733
  }
1772
1734
 
1773
1735
 
@@ -1775,10 +1737,11 @@ float ConnectionDescriptor::GetCommInactivityTimeout()
1775
1737
  ConnectionDescriptor::SetCommInactivityTimeout
1776
1738
  **********************************************/
1777
1739
 
1778
- int ConnectionDescriptor::SetCommInactivityTimeout (float value)
1740
+ int ConnectionDescriptor::SetCommInactivityTimeout (uint64_t value)
1779
1741
  {
1780
1742
  if (value > 0) {
1781
- InactivityTimeout = (Int64)(value * 1000000);
1743
+ InactivityTimeout = value * 1000;
1744
+ MyEventMachine->QueueHeartbeat(this);
1782
1745
  return 1;
1783
1746
  }
1784
1747
  return 0;
@@ -1821,19 +1784,20 @@ bool DatagramDescriptor::GetSockname (struct sockaddr *s)
1821
1784
  DatagramDescriptor::GetCommInactivityTimeout
1822
1785
  ********************************************/
1823
1786
 
1824
- float DatagramDescriptor::GetCommInactivityTimeout()
1787
+ uint64_t DatagramDescriptor::GetCommInactivityTimeout()
1825
1788
  {
1826
- return ((float)InactivityTimeout / 1000000);
1789
+ return InactivityTimeout / 1000;
1827
1790
  }
1828
1791
 
1829
1792
  /********************************************
1830
1793
  DatagramDescriptor::SetCommInactivityTimeout
1831
1794
  ********************************************/
1832
1795
 
1833
- int DatagramDescriptor::SetCommInactivityTimeout (float value)
1796
+ int DatagramDescriptor::SetCommInactivityTimeout (uint64_t value)
1834
1797
  {
1835
1798
  if (value > 0) {
1836
- InactivityTimeout = (Int64)(value * 1000000);
1799
+ InactivityTimeout = value * 1000;
1800
+ MyEventMachine->QueueHeartbeat(this);
1837
1801
  return 1;
1838
1802
  }
1839
1803
  return 0;