eventmachine 1.0.7-java → 1.0.8-java

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/ext/ed.cpp CHANGED
@@ -31,7 +31,7 @@ bool SetSocketNonblocking (SOCKET sd)
31
31
  int val = fcntl (sd, F_GETFL, 0);
32
32
  return (fcntl (sd, F_SETFL, val | O_NONBLOCK) != SOCKET_ERROR) ? true : false;
33
33
  #endif
34
-
34
+
35
35
  #ifdef OS_WIN32
36
36
  #ifdef BUILD_FOR_RUBY
37
37
  // 14Jun09 Ruby provides its own wrappers for ioctlsocket. On 1.8 this is a simple wrapper,
@@ -45,6 +45,22 @@ bool SetSocketNonblocking (SOCKET sd)
45
45
  #endif
46
46
  }
47
47
 
48
+ /************
49
+ SetFdCloexec
50
+ ************/
51
+
52
+ bool SetFdCloexec (int fd)
53
+ {
54
+ #ifdef OS_UNIX
55
+ int flags = fcntl(fd, F_GETFD, 0);
56
+ assert (flags >= 0);
57
+ flags |= FD_CLOEXEC;
58
+ return (fcntl(fd, F_SETFD, FD_CLOEXEC) == 0) ? true : false;
59
+ #else
60
+ // TODO: Windows?
61
+ return true;
62
+ #endif
63
+ }
48
64
 
49
65
  /****************************************
50
66
  EventableDescriptor::EventableDescriptor
@@ -243,7 +259,7 @@ bool EventableDescriptor::IsCloseScheduled()
243
259
  EventableDescriptor::StartProxy
244
260
  *******************************/
245
261
 
246
- void EventableDescriptor::StartProxy(const unsigned long to, const unsigned long bufsize, const unsigned long length)
262
+ void EventableDescriptor::StartProxy(const uintptr_t to, const unsigned long bufsize, const unsigned long length)
247
263
  {
248
264
  EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (to));
249
265
  if (ed) {
@@ -289,13 +305,13 @@ void EventableDescriptor::SetProxiedFrom(EventableDescriptor *from, const unsign
289
305
  EventableDescriptor::_GenericInboundDispatch
290
306
  ********************************************/
291
307
 
292
- void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
308
+ void EventableDescriptor::_GenericInboundDispatch(const char *buf, unsigned long size)
293
309
  {
294
310
  assert(EventCallback);
295
311
 
296
312
  if (ProxyTarget) {
297
313
  if (BytesToProxy > 0) {
298
- unsigned long proxied = min(BytesToProxy, (unsigned long) size);
314
+ unsigned long proxied = min(BytesToProxy, size);
299
315
  ProxyTarget->SendOutboundData(buf, proxied);
300
316
  ProxiedBytes += (unsigned long) proxied;
301
317
  BytesToProxy -= proxied;
@@ -308,7 +324,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
308
324
  }
309
325
  } else {
310
326
  ProxyTarget->SendOutboundData(buf, size);
311
- ProxiedBytes += (unsigned long) size;
327
+ ProxiedBytes += size;
312
328
  }
313
329
  } else {
314
330
  (*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf, size);
@@ -450,8 +466,9 @@ void ConnectionDescriptor::_UpdateEvents(bool read, bool write)
450
466
  #ifdef HAVE_KQUEUE
451
467
  if (read && SelectForRead())
452
468
  MyEventMachine->ArmKqueueReader (this);
453
- if (write && SelectForWrite())
454
- MyEventMachine->ArmKqueueWriter (this);
469
+ bKqueueArmWrite = SelectForWrite();
470
+ if (write && bKqueueArmWrite)
471
+ MyEventMachine->Modify (this);
455
472
  #endif
456
473
  }
457
474
 
@@ -473,7 +490,7 @@ ConnectionDescriptor::SetAttached
473
490
 
474
491
  void ConnectionDescriptor::SetAttached(bool state)
475
492
  {
476
- bAttached = state;
493
+ bAttached = state;
477
494
  }
478
495
 
479
496
 
@@ -555,7 +572,7 @@ void ConnectionDescriptor::SetNotifyWritable(bool writable)
555
572
  ConnectionDescriptor::SendOutboundData
556
573
  **************************************/
557
574
 
558
- int ConnectionDescriptor::SendOutboundData (const char *data, int length)
575
+ int ConnectionDescriptor::SendOutboundData (const char *data, unsigned long length)
559
576
  {
560
577
  if (bWatchOnly)
561
578
  throw std::runtime_error ("cannot send data on a 'watch only' connection");
@@ -566,7 +583,7 @@ int ConnectionDescriptor::SendOutboundData (const char *data, int length)
566
583
  #ifdef WITH_SSL
567
584
  if (SslBox) {
568
585
  if (length > 0) {
569
- int writed = 0;
586
+ unsigned long writed = 0;
570
587
  char *p = (char*)data;
571
588
 
572
589
  while (writed < length) {
@@ -600,7 +617,7 @@ int ConnectionDescriptor::SendOutboundData (const char *data, int length)
600
617
  ConnectionDescriptor::_SendRawOutboundData
601
618
  ******************************************/
602
619
 
603
- int ConnectionDescriptor::_SendRawOutboundData (const char *data, int length)
620
+ int ConnectionDescriptor::_SendRawOutboundData (const char *data, unsigned long length)
604
621
  {
605
622
  /* This internal method is called to schedule bytes that
606
623
  * will be sent out to the remote peer.
@@ -645,28 +662,28 @@ ConnectionDescriptor::SelectForRead
645
662
 
646
663
  bool ConnectionDescriptor::SelectForRead()
647
664
  {
648
- /* A connection descriptor is always scheduled for read,
649
- * UNLESS it's in a pending-connect state.
650
- * On Linux, unlike Unix, a nonblocking socket on which
651
- * connect has been called, does NOT necessarily select
652
- * both readable and writable in case of error.
653
- * The socket will select writable when the disposition
654
- * of the connect is known. On the other hand, a socket
655
- * which successfully connects and selects writable may
656
- * indeed have some data available on it, so it will
657
- * select readable in that case, violating expectations!
658
- * So we will not poll for readability until the socket
659
- * is known to be in a connected state.
660
- */
661
-
662
- if (bPaused)
663
- return false;
664
- else if (bConnectPending)
665
- return false;
666
- else if (bWatchOnly)
667
- return bNotifyReadable ? true : false;
668
- else
669
- return true;
665
+ /* A connection descriptor is always scheduled for read,
666
+ * UNLESS it's in a pending-connect state.
667
+ * On Linux, unlike Unix, a nonblocking socket on which
668
+ * connect has been called, does NOT necessarily select
669
+ * both readable and writable in case of error.
670
+ * The socket will select writable when the disposition
671
+ * of the connect is known. On the other hand, a socket
672
+ * which successfully connects and selects writable may
673
+ * indeed have some data available on it, so it will
674
+ * select readable in that case, violating expectations!
675
+ * So we will not poll for readability until the socket
676
+ * is known to be in a connected state.
677
+ */
678
+
679
+ if (bPaused)
680
+ return false;
681
+ else if (bConnectPending)
682
+ return false;
683
+ else if (bWatchOnly)
684
+ return bNotifyReadable ? true : false;
685
+ else
686
+ return true;
670
687
  }
671
688
 
672
689
 
@@ -676,20 +693,20 @@ ConnectionDescriptor::SelectForWrite
676
693
 
677
694
  bool ConnectionDescriptor::SelectForWrite()
678
695
  {
679
- /* Cf the notes under SelectForRead.
680
- * In a pending-connect state, we ALWAYS select for writable.
681
- * In a normal state, we only select for writable when we
682
- * have outgoing data to send.
683
- */
696
+ /* Cf the notes under SelectForRead.
697
+ * In a pending-connect state, we ALWAYS select for writable.
698
+ * In a normal state, we only select for writable when we
699
+ * have outgoing data to send.
700
+ */
684
701
 
685
- if (bPaused)
686
- return false;
687
- else if (bConnectPending)
688
- return true;
689
- else if (bWatchOnly)
690
- return bNotifyWritable ? true : false;
691
- else
692
- return (GetOutboundDataSize() > 0);
702
+ if (bPaused)
703
+ return false;
704
+ else if (bConnectPending)
705
+ return true;
706
+ else if (bWatchOnly)
707
+ return bNotifyWritable ? true : false;
708
+ else
709
+ return (GetOutboundDataSize() > 0);
693
710
  }
694
711
 
695
712
  /***************************
@@ -840,7 +857,7 @@ void ConnectionDescriptor::Read()
840
857
  ConnectionDescriptor::_DispatchInboundData
841
858
  ******************************************/
842
859
 
843
- void ConnectionDescriptor::_DispatchInboundData (const char *buffer, int size)
860
+ void ConnectionDescriptor::_DispatchInboundData (const char *buffer, unsigned long size)
844
861
  {
845
862
  #ifdef WITH_SSL
846
863
  if (SslBox) {
@@ -953,7 +970,7 @@ void ConnectionDescriptor::Write()
953
970
  ::Write to be called in a busy-loop.
954
971
  */
955
972
  #ifdef HAVE_KQUEUE
956
- if (MyEventMachine->UsingKqueue()) {
973
+ if (MyEventMachine->GetPoller() == Poller_Kqueue) {
957
974
  if (OutboundDataSize == 0 && !bGotExtraKqueueEvent) {
958
975
  bGotExtraKqueueEvent = true;
959
976
  return;
@@ -1311,14 +1328,14 @@ void ConnectionDescriptor::Heartbeat()
1311
1328
  UnbindReasonCode = ETIMEDOUT;
1312
1329
  ScheduleClose (false);
1313
1330
  //bCloseNow = true;
1314
- }
1331
+ }
1315
1332
  }
1316
1333
  else {
1317
1334
  if (InactivityTimeout && ((MyEventMachine->GetCurrentLoopTime() - LastActivity) >= InactivityTimeout)) {
1318
1335
  UnbindReasonCode = ETIMEDOUT;
1319
1336
  ScheduleClose (false);
1320
1337
  //bCloseNow = true;
1321
- }
1338
+ }
1322
1339
  }
1323
1340
  }
1324
1341
 
@@ -1366,8 +1383,8 @@ LoopbreakDescriptor::Write
1366
1383
 
1367
1384
  void LoopbreakDescriptor::Write()
1368
1385
  {
1369
- // Why are we here?
1370
- throw std::runtime_error ("bad code path in loopbreak");
1386
+ // Why are we here?
1387
+ throw std::runtime_error ("bad code path in loopbreak");
1371
1388
  }
1372
1389
 
1373
1390
  /**************************************
@@ -1398,7 +1415,7 @@ AcceptorDescriptor::~AcceptorDescriptor()
1398
1415
  STATIC: AcceptorDescriptor::StopAcceptor
1399
1416
  ****************************************/
1400
1417
 
1401
- void AcceptorDescriptor::StopAcceptor (const unsigned long binding)
1418
+ void AcceptorDescriptor::StopAcceptor (const uintptr_t binding)
1402
1419
  {
1403
1420
  // TODO: This is something of a hack, or at least it's a static method of the wrong class.
1404
1421
  AcceptorDescriptor *ad = dynamic_cast <AcceptorDescriptor*> (Bindable_t::GetObject (binding));
@@ -1434,7 +1451,16 @@ void AcceptorDescriptor::Read()
1434
1451
  int accept_count = EventMachine_t::GetSimultaneousAcceptCount();
1435
1452
 
1436
1453
  for (int i=0; i < accept_count; i++) {
1454
+ #if defined(HAVE_SOCK_CLOEXEC) && defined(HAVE_ACCEPT4)
1455
+ int sd = accept4 (GetSocket(), (struct sockaddr*)&pin, &addrlen, SOCK_CLOEXEC);
1456
+ if (sd == INVALID_SOCKET) {
1457
+ // We may be running in a kernel where
1458
+ // SOCK_CLOEXEC is not supported - fall back:
1459
+ sd = accept (GetSocket(), (struct sockaddr*)&pin, &addrlen);
1460
+ }
1461
+ #else
1437
1462
  int sd = accept (GetSocket(), (struct sockaddr*)&pin, &addrlen);
1463
+ #endif
1438
1464
  if (sd == INVALID_SOCKET) {
1439
1465
  // This breaks the loop when we've accepted everything on the kernel queue,
1440
1466
  // up to 10 new connections. But what if the *first* accept fails?
@@ -1443,10 +1469,10 @@ void AcceptorDescriptor::Read()
1443
1469
  break;
1444
1470
  }
1445
1471
 
1446
- // Set the newly-accepted socket non-blocking.
1472
+ // Set the newly-accepted socket non-blocking and to close on exec.
1447
1473
  // On Windows, this may fail because, weirdly, Windows inherits the non-blocking
1448
1474
  // attribute that we applied to the acceptor socket into the accepted one.
1449
- if (!SetSocketNonblocking (sd)) {
1475
+ if (!SetFdCloexec(sd) || !SetSocketNonblocking (sd)) {
1450
1476
  //int val = fcntl (sd, F_GETFL, 0);
1451
1477
  //if (fcntl (sd, F_SETFL, val | O_NONBLOCK) == -1) {
1452
1478
  shutdown (sd, 1);
@@ -1454,7 +1480,6 @@ void AcceptorDescriptor::Read()
1454
1480
  continue;
1455
1481
  }
1456
1482
 
1457
-
1458
1483
  // Disable slow-start (Nagle algorithm). Eventually make this configurable.
1459
1484
  int one = 1;
1460
1485
  setsockopt (sd, IPPROTO_TCP, TCP_NODELAY, (char*) &one, sizeof(one));
@@ -1468,14 +1493,18 @@ void AcceptorDescriptor::Read()
1468
1493
  (*EventCallback) (GetBinding(), EM_CONNECTION_ACCEPTED, NULL, cd->GetBinding());
1469
1494
  }
1470
1495
  #ifdef HAVE_EPOLL
1471
- cd->GetEpollEvent()->events =
1472
- (cd->SelectForRead() ? EPOLLIN : 0) | (cd->SelectForWrite() ? EPOLLOUT : 0);
1496
+ cd->GetEpollEvent()->events = 0;
1497
+ if (cd->SelectForRead())
1498
+ cd->GetEpollEvent()->events |= EPOLLIN;
1499
+ if (cd->SelectForWrite())
1500
+ cd->GetEpollEvent()->events |= EPOLLOUT;
1473
1501
  #endif
1474
1502
  assert (MyEventMachine);
1475
1503
  MyEventMachine->Add (cd);
1476
1504
  #ifdef HAVE_KQUEUE
1477
- if (cd->SelectForWrite())
1478
- MyEventMachine->ArmKqueueWriter (cd);
1505
+ bKqueueArmWrite = cd->SelectForWrite();
1506
+ if (bKqueueArmWrite)
1507
+ MyEventMachine->Modify (cd);
1479
1508
  if (cd->SelectForRead())
1480
1509
  MyEventMachine->ArmKqueueReader (cd);
1481
1510
  #endif
@@ -1490,8 +1519,8 @@ AcceptorDescriptor::Write
1490
1519
 
1491
1520
  void AcceptorDescriptor::Write()
1492
1521
  {
1493
- // Why are we here?
1494
- throw std::runtime_error ("bad code path in acceptor");
1522
+ // Why are we here?
1523
+ throw std::runtime_error ("bad code path in acceptor");
1495
1524
  }
1496
1525
 
1497
1526
 
@@ -1501,7 +1530,7 @@ AcceptorDescriptor::Heartbeat
1501
1530
 
1502
1531
  void AcceptorDescriptor::Heartbeat()
1503
1532
  {
1504
- // No-op
1533
+ // No-op
1505
1534
  }
1506
1535
 
1507
1536
 
@@ -1710,13 +1739,16 @@ void DatagramDescriptor::Write()
1710
1739
  }
1711
1740
 
1712
1741
  #ifdef HAVE_EPOLL
1713
- EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0));
1742
+ EpollEvent.events = EPOLLIN;
1743
+ if (SelectForWrite())
1744
+ EpollEvent.events |= EPOLLOUT;
1714
1745
  assert (MyEventMachine);
1715
1746
  MyEventMachine->Modify (this);
1716
1747
  #endif
1717
1748
  #ifdef HAVE_KQUEUE
1718
- if (SelectForWrite())
1719
- MyEventMachine->ArmKqueueWriter (this);
1749
+ bKqueueArmWrite = SelectForWrite();
1750
+ assert (MyEventMachine);
1751
+ MyEventMachine->Modify (this);
1720
1752
  #endif
1721
1753
  }
1722
1754
 
@@ -1742,7 +1774,7 @@ bool DatagramDescriptor::SelectForWrite()
1742
1774
  DatagramDescriptor::SendOutboundData
1743
1775
  ************************************/
1744
1776
 
1745
- int DatagramDescriptor::SendOutboundData (const char *data, int length)
1777
+ int DatagramDescriptor::SendOutboundData (const char *data, unsigned long length)
1746
1778
  {
1747
1779
  // This is almost an exact clone of ConnectionDescriptor::_SendRawOutboundData.
1748
1780
  // That means most of it could be factored to a common ancestor. Note that
@@ -1767,7 +1799,9 @@ int DatagramDescriptor::SendOutboundData (const char *data, int length)
1767
1799
  MyEventMachine->Modify (this);
1768
1800
  #endif
1769
1801
  #ifdef HAVE_KQUEUE
1770
- MyEventMachine->ArmKqueueWriter (this);
1802
+ bKqueueArmWrite = true;
1803
+ assert (MyEventMachine);
1804
+ MyEventMachine->Modify (this);
1771
1805
  #endif
1772
1806
 
1773
1807
  return length;
@@ -1778,7 +1812,7 @@ int DatagramDescriptor::SendOutboundData (const char *data, int length)
1778
1812
  DatagramDescriptor::SendOutboundDatagram
1779
1813
  ****************************************/
1780
1814
 
1781
- int DatagramDescriptor::SendOutboundDatagram (const char *data, int length, const char *address, int port)
1815
+ int DatagramDescriptor::SendOutboundDatagram (const char *data, unsigned long length, const char *address, int port)
1782
1816
  {
1783
1817
  // This is an exact clone of ConnectionDescriptor::SendOutboundData.
1784
1818
  // That means it needs to move to a common ancestor.
@@ -1825,7 +1859,9 @@ int DatagramDescriptor::SendOutboundDatagram (const char *data, int length, cons
1825
1859
  MyEventMachine->Modify (this);
1826
1860
  #endif
1827
1861
  #ifdef HAVE_KQUEUE
1828
- MyEventMachine->ArmKqueueWriter (this);
1862
+ bKqueueArmWrite = true;
1863
+ assert (MyEventMachine);
1864
+ MyEventMachine->Modify (this);
1829
1865
  #endif
1830
1866
 
1831
1867
  return length;
data/ext/ed.h CHANGED
@@ -27,7 +27,7 @@ class SslBox_t; // forward reference
27
27
  #endif
28
28
 
29
29
  bool SetSocketNonblocking (SOCKET);
30
-
30
+ bool SetFdCloexec (int);
31
31
 
32
32
  /*************************
33
33
  class EventableDescriptor
@@ -85,11 +85,15 @@ class EventableDescriptor: public Bindable_t
85
85
  struct epoll_event *GetEpollEvent() { return &EpollEvent; }
86
86
  #endif
87
87
 
88
- virtual void StartProxy(const unsigned long, const unsigned long, const unsigned long);
88
+ #ifdef HAVE_KQUEUE
89
+ bool GetKqueueArmWrite() { return bKqueueArmWrite; }
90
+ #endif
91
+
92
+ virtual void StartProxy(const uintptr_t, const unsigned long, const unsigned long);
89
93
  virtual void StopProxy();
90
94
  virtual unsigned long GetProxiedBytes(){ return ProxiedBytes; };
91
95
  virtual void SetProxiedFrom(EventableDescriptor*, const unsigned long);
92
- virtual int SendOutboundData(const char*,int){ return -1; }
96
+ virtual int SendOutboundData(const char*,unsigned long){ return -1; }
93
97
  virtual bool IsPaused(){ return bPaused; }
94
98
  virtual bool Pause(){ bPaused = true; return bPaused; }
95
99
  virtual bool Resume(){ bPaused = false; return bPaused; }
@@ -109,7 +113,7 @@ class EventableDescriptor: public Bindable_t
109
113
  bool bWatchOnly;
110
114
 
111
115
  EMCallback EventCallback;
112
- void _GenericInboundDispatch(const char*, int);
116
+ void _GenericInboundDispatch(const char *buffer, unsigned long size);
113
117
 
114
118
  uint64_t CreatedAt;
115
119
  bool bCallbackUnbind;
@@ -126,6 +130,10 @@ class EventableDescriptor: public Bindable_t
126
130
  struct epoll_event EpollEvent;
127
131
  #endif
128
132
 
133
+ #ifdef HAVE_KQUEUE
134
+ bool bKqueueArmWrite;
135
+ #endif
136
+
129
137
  EventMachine_t *MyEventMachine;
130
138
  uint64_t PendingConnectTimeout;
131
139
  uint64_t InactivityTimeout;
@@ -165,7 +173,7 @@ class ConnectionDescriptor: public EventableDescriptor
165
173
  ConnectionDescriptor (int, EventMachine_t*);
166
174
  virtual ~ConnectionDescriptor();
167
175
 
168
- int SendOutboundData (const char*, int);
176
+ int SendOutboundData (const char*, unsigned long);
169
177
 
170
178
  void SetConnectPending (bool f);
171
179
  virtual void ScheduleClose (bool after_writing);
@@ -252,9 +260,9 @@ class ConnectionDescriptor: public EventableDescriptor
252
260
  void _UpdateEvents();
253
261
  void _UpdateEvents(bool, bool);
254
262
  void _WriteOutboundData();
255
- void _DispatchInboundData (const char *buffer, int size);
263
+ void _DispatchInboundData (const char *buffer, unsigned long size);
256
264
  void _DispatchCiphertext();
257
- int _SendRawOutboundData (const char*, int);
265
+ int _SendRawOutboundData (const char *buffer, unsigned long size);
258
266
  void _CheckHandshakeStatus();
259
267
 
260
268
  };
@@ -277,8 +285,8 @@ class DatagramDescriptor: public EventableDescriptor
277
285
  virtual bool SelectForRead() {return true;}
278
286
  virtual bool SelectForWrite();
279
287
 
280
- int SendOutboundData (const char*, int);
281
- int SendOutboundDatagram (const char*, int, const char*, int);
288
+ int SendOutboundData (const char*, unsigned long);
289
+ int SendOutboundDatagram (const char*, unsigned long, const char*, int);
282
290
 
283
291
  // Do we have any data to write? This is used by ShouldDelete.
284
292
  virtual int GetOutboundDataSize() {return OutboundDataSize;}
@@ -325,7 +333,7 @@ class AcceptorDescriptor: public EventableDescriptor
325
333
 
326
334
  virtual bool GetSockname (struct sockaddr*, socklen_t*);
327
335
 
328
- static void StopAcceptor (const unsigned long binding);
336
+ static void StopAcceptor (const uintptr_t binding);
329
337
  };
330
338
 
331
339
  /********************
@@ -346,7 +354,7 @@ class PipeDescriptor: public EventableDescriptor
346
354
  virtual bool SelectForRead();
347
355
  virtual bool SelectForWrite();
348
356
 
349
- int SendOutboundData (const char*, int);
357
+ int SendOutboundData (const char*, unsigned long);
350
358
  virtual int GetOutboundDataSize() {return OutboundDataSize;}
351
359
 
352
360
  virtual bool GetSubprocessPid (pid_t*);
@@ -418,5 +426,3 @@ class InotifyDescriptor: public EventableDescriptor
418
426
  };
419
427
 
420
428
  #endif // __EventableDescriptor__H_
421
-
422
-