eventmachine 1.0.7-java → 1.0.8-java

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