eventmachine-maglev- 1.0.0.beta.4 → 1.0.0.rc.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -18,7 +18,7 @@ This unique combination makes EventMachine a premier choice for designers of cri
18
18
  applications, including Web servers and proxies, email and IM production systems, authentication/authorization
19
19
  processors, and many more.
20
20
 
21
- EventMachine has been around since yearly 2000s and is a mature and battle tested library.
21
+ EventMachine has been around since the early 2000s and is a mature and battle tested library.
22
22
 
23
23
 
24
24
  ## What EventMachine is good for? ##
data/Rakefile CHANGED
@@ -1,11 +1,6 @@
1
- require 'rubygems' unless defined?(Gem)
2
- require 'rake' unless defined?(Rake)
3
- import *Dir['tasks/*.rake']
1
+ require 'rubygems'
2
+ GEMSPEC = Gem::Specification.load('eventmachine.gemspec')
4
3
 
5
- require File.expand_path('../lib/em/version', __FILE__)
6
- GEMSPEC = eval(File.read(File.expand_path('../eventmachine.gemspec', __FILE__)))
7
-
8
- require 'yard'
9
4
  require 'rake/clean'
10
5
  task :clobber => :clean
11
6
 
@@ -13,8 +8,13 @@ desc "Build eventmachine, then run tests."
13
8
  task :default => [:compile, :test]
14
9
 
15
10
  desc 'Generate documentation'
16
- YARD::Rake::YardocTask.new do |t|
17
- t.files = ['lib/**/*.rb', '-', 'docs/*.md']
18
- t.options = ['--main', 'README.md', '--no-private']
19
- t.options = ['--exclude', 'lib/jeventmachine', '--exclude', 'lib/pr_eventmachine']
11
+ begin
12
+ require 'yard'
13
+ YARD::Rake::YardocTask.new do |t|
14
+ t.files = ['lib/**/*.rb', '-', 'docs/*.md']
15
+ t.options = ['--main', 'README.md', '--no-private']
16
+ t.options = ['--exclude', 'lib/jeventmachine', '--exclude', 'lib/pr_eventmachine']
17
+ end
18
+ rescue LoadError
19
+ task :yard do puts "Please install yard first!"; end
20
20
  end
data/eventmachine.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.files = `git ls-files`.split("\n")
14
14
  s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
15
15
 
16
- s.add_development_dependency 'rake-compiler', '0.7.6'
16
+ s.add_development_dependency 'rake-compiler', '~> 0.8.1'
17
17
  s.add_development_dependency 'yard', ">= 0.7.2"
18
18
  s.add_development_dependency 'bluecloth'
19
19
 
data/ext/cmain.cpp CHANGED
@@ -220,7 +220,7 @@ evma_pause
220
220
 
221
221
  extern "C" int evma_pause (const unsigned long binding)
222
222
  {
223
- ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
223
+ EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
224
224
  if (cd)
225
225
  return cd->Pause() ? 1 : 0;
226
226
 
@@ -233,7 +233,7 @@ evma_resume
233
233
 
234
234
  extern "C" int evma_resume (const unsigned long binding)
235
235
  {
236
- ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
236
+ EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
237
237
  if (cd)
238
238
  return cd->Resume() ? 1 : 0;
239
239
 
@@ -246,13 +246,22 @@ evma_is_paused
246
246
 
247
247
  extern "C" int evma_is_paused (const unsigned long binding)
248
248
  {
249
- ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject (binding));
249
+ EventableDescriptor *cd = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
250
250
  if (cd)
251
251
  return cd->IsPaused() ? 1 : 0;
252
252
 
253
253
  return 0;
254
254
  }
255
255
 
256
+ /************************
257
+ evma_num_close_scheduled
258
+ ************************/
259
+
260
+ extern "C" int evma_num_close_scheduled ()
261
+ {
262
+ return EventMachine->NumCloseScheduled;
263
+ }
264
+
256
265
  /**********************
257
266
  evma_create_tcp_server
258
267
  **********************/
@@ -804,6 +813,35 @@ extern "C" void evma_stop_proxy (const unsigned long from)
804
813
  ed->StopProxy();
805
814
  }
806
815
 
816
+ /******************
817
+ evma_proxied_bytes
818
+ *******************/
819
+
820
+ extern "C" unsigned long evma_proxied_bytes (const unsigned long from)
821
+ {
822
+ ensure_eventmachine("evma_proxied_bytes");
823
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
824
+ if (ed)
825
+ return ed->GetProxiedBytes();
826
+ else
827
+ return 0;
828
+ }
829
+
830
+
831
+ /***************************
832
+ evma_get_last_activity_time
833
+ ****************************/
834
+
835
+ extern "C" uint64_t evma_get_last_activity_time(const unsigned long from)
836
+ {
837
+ ensure_eventmachine("evma_get_last_activity_time");
838
+ EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
839
+ if (ed)
840
+ return ed->GetLastActivity();
841
+ else
842
+ return 0;
843
+ }
844
+
807
845
 
808
846
  /***************************
809
847
  evma_get_heartbeat_interval
data/ext/ed.cpp CHANGED
@@ -54,16 +54,19 @@ EventableDescriptor::EventableDescriptor (int sd, EventMachine_t *em):
54
54
  bCloseNow (false),
55
55
  bCloseAfterWriting (false),
56
56
  MySocket (sd),
57
+ bAttached (false),
57
58
  bWatchOnly (false),
58
59
  EventCallback (NULL),
59
60
  bCallbackUnbind (true),
60
61
  UnbindReasonCode (0),
61
62
  ProxyTarget(NULL),
62
63
  ProxiedFrom(NULL),
64
+ ProxiedBytes(0),
63
65
  MaxOutboundBufSize(0),
64
66
  MyEventMachine (em),
65
67
  PendingConnectTimeout(20000000),
66
- InactivityTimeout (0)
68
+ InactivityTimeout (0),
69
+ bPaused (false)
67
70
  {
68
71
  /* There are three ways to close a socket, all of which should
69
72
  * automatically signal to the event machine that this object
@@ -114,6 +117,7 @@ EventableDescriptor::~EventableDescriptor()
114
117
  (*EventCallback)(ProxiedFrom->GetBinding(), EM_PROXY_TARGET_UNBOUND, NULL, 0);
115
118
  ProxiedFrom->StopProxy();
116
119
  }
120
+ MyEventMachine->NumCloseScheduled--;
117
121
  StopProxy();
118
122
  Close();
119
123
  }
@@ -168,13 +172,21 @@ void EventableDescriptor::Close()
168
172
  * Therefore, it is necessary to notify EventMachine that
169
173
  * the fd associated with this EventableDescriptor is
170
174
  * closing.
175
+ *
176
+ * EventMachine also never closes fds for STDIN, STDOUT and
177
+ * STDERR (0, 1 & 2)
171
178
  */
172
179
 
173
180
  // Close the socket right now. Intended for emergencies.
174
- if (MySocket != INVALID_SOCKET && !bWatchOnly) {
175
- MyEventMachine->Closing (this);
176
- shutdown (MySocket, 1);
177
- close (MySocket);
181
+ if (MySocket != INVALID_SOCKET) {
182
+ MyEventMachine->Deregister (this);
183
+
184
+ // Do not close STDIN, STDOUT, STDERR
185
+ if (MySocket > 2 && !bAttached) {
186
+ shutdown (MySocket, 1);
187
+ close (MySocket);
188
+ }
189
+
178
190
  MySocket = INVALID_SOCKET;
179
191
  }
180
192
  }
@@ -205,6 +217,7 @@ EventableDescriptor::ScheduleClose
205
217
 
206
218
  void EventableDescriptor::ScheduleClose (bool after_writing)
207
219
  {
220
+ MyEventMachine->NumCloseScheduled++;
208
221
  // KEEP THIS SYNCHRONIZED WITH ::IsCloseScheduled.
209
222
  if (after_writing)
210
223
  bCloseAfterWriting = true;
@@ -235,6 +248,7 @@ void EventableDescriptor::StartProxy(const unsigned long to, const unsigned long
235
248
  StopProxy();
236
249
  ProxyTarget = ed;
237
250
  BytesToProxy = length;
251
+ ProxiedBytes = 0;
238
252
  ed->SetProxiedFrom(this, bufsize);
239
253
  return;
240
254
  }
@@ -281,6 +295,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
281
295
  if (BytesToProxy > 0) {
282
296
  unsigned long proxied = min(BytesToProxy, (unsigned long) size);
283
297
  ProxyTarget->SendOutboundData(buf, proxied);
298
+ ProxiedBytes += (unsigned long) proxied;
284
299
  BytesToProxy -= proxied;
285
300
  if (BytesToProxy == 0) {
286
301
  StopProxy();
@@ -291,6 +306,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
291
306
  }
292
307
  } else {
293
308
  ProxyTarget->SendOutboundData(buf, size);
309
+ ProxiedBytes += (unsigned long) size;
294
310
  }
295
311
  } else {
296
312
  (*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf, size);
@@ -355,7 +371,6 @@ ConnectionDescriptor::ConnectionDescriptor
355
371
 
356
372
  ConnectionDescriptor::ConnectionDescriptor (int sd, EventMachine_t *em):
357
373
  EventableDescriptor (sd, em),
358
- bPaused (false),
359
374
  bConnectPending (false),
360
375
  bNotifyReadable (false),
361
376
  bNotifyWritable (false),
@@ -449,6 +464,16 @@ void ConnectionDescriptor::SetConnectPending(bool f)
449
464
  }
450
465
 
451
466
 
467
+ /**********************************
468
+ ConnectionDescriptor::SetAttached
469
+ ***********************************/
470
+
471
+ void ConnectionDescriptor::SetAttached(bool state)
472
+ {
473
+ bAttached = state;
474
+ }
475
+
476
+
452
477
  /**********************************
453
478
  ConnectionDescriptor::SetWatchOnly
454
479
  ***********************************/
data/ext/ed.h CHANGED
@@ -79,6 +79,7 @@ class EventableDescriptor: public Bindable_t
79
79
  virtual int SetCommInactivityTimeout (uint64_t value) {return 0;}
80
80
  uint64_t GetPendingConnectTimeout();
81
81
  int SetPendingConnectTimeout (uint64_t value);
82
+ uint64_t GetLastActivity() { return LastActivity; }
82
83
 
83
84
  #ifdef HAVE_EPOLL
84
85
  struct epoll_event *GetEpollEvent() { return &EpollEvent; }
@@ -86,11 +87,12 @@ class EventableDescriptor: public Bindable_t
86
87
 
87
88
  virtual void StartProxy(const unsigned long, const unsigned long, const unsigned long);
88
89
  virtual void StopProxy();
90
+ virtual unsigned long GetProxiedBytes(){ return ProxiedBytes; };
89
91
  virtual void SetProxiedFrom(EventableDescriptor*, const unsigned long);
90
92
  virtual int SendOutboundData(const char*,int){ return -1; }
91
- virtual bool IsPaused(){ return false; }
92
- virtual bool Pause(){ return false; }
93
- virtual bool Resume(){ return false; }
93
+ virtual bool IsPaused(){ return bPaused; }
94
+ virtual bool Pause(){ bPaused = true; return bPaused; }
95
+ virtual bool Resume(){ bPaused = false; return bPaused; }
94
96
 
95
97
  void SetUnbindReasonCode(int code){ UnbindReasonCode = code; }
96
98
  virtual int ReportErrorStatus(){ return 0; }
@@ -103,6 +105,7 @@ class EventableDescriptor: public Bindable_t
103
105
 
104
106
  protected:
105
107
  int MySocket;
108
+ bool bAttached;
106
109
  bool bWatchOnly;
107
110
 
108
111
  EMCallback EventCallback;
@@ -115,6 +118,7 @@ class EventableDescriptor: public Bindable_t
115
118
  unsigned long BytesToProxy;
116
119
  EventableDescriptor *ProxyTarget;
117
120
  EventableDescriptor *ProxiedFrom;
121
+ unsigned long ProxiedBytes;
118
122
 
119
123
  unsigned long MaxOutboundBufSize;
120
124
 
@@ -127,6 +131,7 @@ class EventableDescriptor: public Bindable_t
127
131
  uint64_t InactivityTimeout;
128
132
  uint64_t LastActivity;
129
133
  uint64_t NextHeartbeat;
134
+ bool bPaused;
130
135
  };
131
136
 
132
137
 
@@ -168,9 +173,9 @@ class ConnectionDescriptor: public EventableDescriptor
168
173
 
169
174
  void SetNotifyReadable (bool);
170
175
  void SetNotifyWritable (bool);
176
+ void SetAttached (bool);
171
177
  void SetWatchOnly (bool);
172
178
 
173
- bool IsPaused(){ return bPaused; }
174
179
  bool Pause();
175
180
  bool Resume();
176
181
 
@@ -217,7 +222,6 @@ class ConnectionDescriptor: public EventableDescriptor
217
222
  };
218
223
 
219
224
  protected:
220
- bool bPaused;
221
225
  bool bConnectPending;
222
226
 
223
227
  bool bNotifyReadable;
data/ext/em.cpp CHANGED
@@ -73,6 +73,7 @@ EventMachine_t::EventMachine_t (EMCallback event_callback):
73
73
  NextHeartbeatTime (0),
74
74
  LoopBreakerReader (-1),
75
75
  LoopBreakerWriter (-1),
76
+ NumCloseScheduled (0),
76
77
  bTerminateSignalReceived (false),
77
78
  bEpoll (false),
78
79
  epfd (-1),
@@ -197,10 +198,9 @@ EventMachine_t::SetTimerQuantum
197
198
  void EventMachine_t::SetTimerQuantum (int interval)
198
199
  {
199
200
  /* We get a timer-quantum expressed in milliseconds.
200
- * Don't set a quantum smaller than 5 or larger than 2500.
201
201
  */
202
202
 
203
- if ((interval < 5) || (interval > 2500))
203
+ if ((interval < 5) || (interval > 5*60*1000))
204
204
  throw std::runtime_error ("invalid timer-quantum");
205
205
 
206
206
  Quantum.tv_sec = interval / 1000;
@@ -673,7 +673,13 @@ EventMachine_t::_TimeTilNextEvent
673
673
 
674
674
  timeval EventMachine_t::_TimeTilNextEvent()
675
675
  {
676
+ // 29jul11: Changed calculation base from MyCurrentLoopTime to the
677
+ // real time. As MyCurrentLoopTime is set at the beginning of an
678
+ // iteration and this calculation is done at the end, evenmachine
679
+ // will potentially oversleep by the amount of time the iteration
680
+ // took to execute.
676
681
  uint64_t next_event = 0;
682
+ uint64_t current_time = GetRealTime();
677
683
 
678
684
  if (!Heartbeats.empty()) {
679
685
  multimap<uint64_t,EventableDescriptor*>::iterator heartbeats = Heartbeats.begin();
@@ -687,16 +693,16 @@ timeval EventMachine_t::_TimeTilNextEvent()
687
693
  }
688
694
 
689
695
  if (!NewDescriptors.empty() || !ModifiedDescriptors.empty()) {
690
- next_event = MyCurrentLoopTime;
696
+ next_event = current_time;
691
697
  }
692
-
698
+
693
699
  timeval tv;
694
700
 
695
- if (next_event == 0) {
701
+ if (next_event == 0 || NumCloseScheduled > 0) {
696
702
  tv = Quantum;
697
703
  } else {
698
- if (next_event > MyCurrentLoopTime) {
699
- uint64_t duration = next_event - MyCurrentLoopTime;
704
+ if (next_event > current_time) {
705
+ uint64_t duration = next_event - current_time;
700
706
  tv.tv_sec = duration / 1000000;
701
707
  tv.tv_usec = duration % 1000000;
702
708
  } else {
@@ -1257,7 +1263,7 @@ const unsigned long EventMachine_t::ConnectToUnixServer (const char *server)
1257
1263
 
1258
1264
  #ifdef OS_WIN32
1259
1265
  throw std::runtime_error ("unix-domain connection unavailable on this platform");
1260
- return NULL;
1266
+ return 0;
1261
1267
  #endif
1262
1268
 
1263
1269
  // The whole rest of this function is only compiled on Unix systems.
@@ -1356,6 +1362,7 @@ const unsigned long EventMachine_t::AttachFD (int fd, bool watch_mode)
1356
1362
  if (!cd)
1357
1363
  throw std::runtime_error ("no connection allocated");
1358
1364
 
1365
+ cd->SetAttached(true);
1359
1366
  cd->SetWatchOnly(watch_mode);
1360
1367
  cd->SetConnectPending (false);
1361
1368
 
@@ -1395,7 +1402,11 @@ int EventMachine_t::DetachFD (EventableDescriptor *ed)
1395
1402
  if (bKqueue) {
1396
1403
  // remove any read/write events for this fd
1397
1404
  struct kevent k;
1405
+ #ifdef __NetBSD__
1406
+ EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, (intptr_t)ed);
1407
+ #else
1398
1408
  EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, ed);
1409
+ #endif
1399
1410
  int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
1400
1411
  if (t < 0 && (errno != ENOENT) && (errno != EBADF)) {
1401
1412
  char buf [200];
@@ -1651,7 +1662,11 @@ void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed)
1651
1662
  if (!ed)
1652
1663
  throw std::runtime_error ("added bad descriptor");
1653
1664
  struct kevent k;
1665
+ #ifdef __NetBSD__
1666
+ EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, (intptr_t)ed);
1667
+ #else
1654
1668
  EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, ed);
1669
+ #endif
1655
1670
  int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
1656
1671
  if (t < 0) {
1657
1672
  char buf [200];
@@ -1673,7 +1688,11 @@ void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed)
1673
1688
  if (!ed)
1674
1689
  throw std::runtime_error ("added bad descriptor");
1675
1690
  struct kevent k;
1691
+ #ifdef __NetBSD__
1692
+ EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed);
1693
+ #else
1676
1694
  EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed);
1695
+ #endif
1677
1696
  int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
1678
1697
  if (t < 0) {
1679
1698
  char buf [200];
@@ -1724,7 +1743,11 @@ void EventMachine_t::_AddNewDescriptors()
1724
1743
  // INCOMPLETE. Some descriptors don't want to be readable.
1725
1744
  assert (kqfd != -1);
1726
1745
  struct kevent k;
1746
+ #ifdef __NetBSD__
1747
+ EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed);
1748
+ #else
1727
1749
  EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed);
1750
+ #endif
1728
1751
  int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
1729
1752
  assert (t == 0);
1730
1753
  }
@@ -1789,10 +1812,10 @@ void EventMachine_t::Modify (EventableDescriptor *ed)
1789
1812
 
1790
1813
 
1791
1814
  /***********************
1792
- EventMachine_t::Closing
1815
+ EventMachine_t::Deregister
1793
1816
  ***********************/
1794
1817
 
1795
- void EventMachine_t::Closing (EventableDescriptor *ed)
1818
+ void EventMachine_t::Deregister (EventableDescriptor *ed)
1796
1819
  {
1797
1820
  if (!ed)
1798
1821
  throw std::runtime_error ("modified bad descriptor");
data/ext/em.h CHANGED
@@ -46,6 +46,15 @@ See the file COPYING for complete licensing information.
46
46
  #ifndef RUBY_UBF_IO
47
47
  #define RUBY_UBF_IO RB_UBF_DFL
48
48
  #endif
49
+ #ifndef RSTRING_PTR
50
+ #define RSTRING_PTR(str) RSTRING(str)->ptr
51
+ #endif
52
+ #ifndef RSTRING_LEN
53
+ #define RSTRING_LEN(str) RSTRING(str)->len
54
+ #endif
55
+ #ifndef RSTRING_LENINT
56
+ #define RSTRING_LENINT(str) RSTRING_LEN(str)
57
+ #endif
49
58
  #else
50
59
  #define EmSelect select
51
60
  #endif
@@ -84,7 +93,7 @@ class EventMachine_t
84
93
 
85
94
  void Add (EventableDescriptor*);
86
95
  void Modify (EventableDescriptor*);
87
- void Closing (EventableDescriptor*);
96
+ void Deregister (EventableDescriptor*);
88
97
 
89
98
  const unsigned long AttachFD (int, bool);
90
99
  int DetachFD (EventableDescriptor*);
@@ -155,6 +164,7 @@ class EventMachine_t
155
164
  public:
156
165
  void _ReadLoopBreaker();
157
166
  void _ReadInotifyEvents();
167
+ int NumCloseScheduled;
158
168
 
159
169
  private:
160
170
  enum {
data/ext/eventmachine.h CHANGED
@@ -59,6 +59,8 @@ extern "C" {
59
59
  int evma_is_paused(const unsigned long binding);
60
60
  int evma_resume(const unsigned long binding);
61
61
 
62
+ int evma_num_close_scheduled();
63
+
62
64
  void evma_stop_tcp_server (const unsigned long signature);
63
65
  const unsigned long evma_create_tcp_server (const char *address, int port);
64
66
  const unsigned long evma_create_unix_domain_server (const char *filename);
@@ -84,6 +86,7 @@ extern "C" {
84
86
  float evma_get_pending_connect_timeout (const unsigned long binding);
85
87
  int evma_set_pending_connect_timeout (const unsigned long binding, float value);
86
88
  int evma_get_outbound_data_size (const unsigned long binding);
89
+ uint64_t evma_get_last_activity_time (const unsigned long);
87
90
  int evma_send_file_data_to_connection (const unsigned long binding, const char *filename);
88
91
 
89
92
  void evma_close_connection (const unsigned long binding, int after_writing);
@@ -107,6 +110,7 @@ extern "C" {
107
110
 
108
111
  void evma_start_proxy(const unsigned long, const unsigned long, const unsigned long, const unsigned long);
109
112
  void evma_stop_proxy(const unsigned long);
113
+ unsigned long evma_proxied_bytes(const unsigned long);
110
114
 
111
115
  int evma_set_rlimit_nofile (int n_files);
112
116
 
data/ext/extconf.rb CHANGED
@@ -25,7 +25,7 @@ end
25
25
  def manual_ssl_config
26
26
  ssl_libs_heads_args = {
27
27
  :unix => [%w[ssl crypto], %w[openssl/ssl.h openssl/err.h]],
28
- :mswin => [%w[ssleay32 libeay32], %w[openssl/ssl.h openssl/err.h]],
28
+ :mswin => [%w[ssleay32 eay32], %w[openssl/ssl.h openssl/err.h]],
29
29
  }
30
30
 
31
31
  dc_flags = ['ssl']
@@ -40,7 +40,8 @@ def manual_ssl_config
40
40
  end
41
41
 
42
42
  if ENV['CROSS_COMPILING']
43
- openssl_dir = File.expand_path("~/.rake-compiler/builds/openssl-1.0.0a/")
43
+ openssl_version = ENV.fetch("OPENSSL_VERSION", "1.0.0j")
44
+ openssl_dir = File.expand_path("~/.rake-compiler/builds/openssl-#{openssl_version}/")
44
45
  if File.exists?(openssl_dir)
45
46
  FileUtils.mkdir_p Dir.pwd+"/openssl/"
46
47
  FileUtils.cp Dir[openssl_dir+"/include/openssl/*.h"], Dir.pwd+"/openssl/", :verbose => true
@@ -57,7 +58,7 @@ if ENV['CROSS_COMPILING']
57
58
  end
58
59
 
59
60
  # Try to use pkg_config first, fixes #73
60
- if pkg_config('openssl') || manual_ssl_config
61
+ if (!ENV['CROSS_COMPILING'] and pkg_config('openssl')) || manual_ssl_config
61
62
  add_define "WITH_SSL"
62
63
  else
63
64
  add_define "WITHOUT_SSL"
@@ -80,7 +81,7 @@ if defined? RUBY_ENGINE and RUBY_ENGINE =~ /maglev/
80
81
  end
81
82
 
82
83
  if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
83
- GNU_CHAIN = $1 == 'mingw'
84
+ GNU_CHAIN = ENV['CROSS_COMPILING'] or $1 == 'mingw'
84
85
  OS_WIN32 = true
85
86
  add_define "OS_WIN32"
86
87
  else
@@ -91,6 +92,15 @@ else
91
92
  add_define "HAVE_KQUEUE" if have_header("sys/event.h") and have_header("sys/queue.h")
92
93
  end
93
94
 
95
+ # Adjust number of file descriptors (FD) on Windows
96
+
97
+ if RbConfig::CONFIG["host_os"] =~ /mingw/
98
+ found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
99
+ any? { |v| v.include?("FD_SETSIZE") }
100
+
101
+ add_define "FD_SETSIZE=32767" unless found
102
+ end
103
+
94
104
  # Main platform invariances:
95
105
 
96
106
  case RUBY_PLATFORM
@@ -143,6 +153,15 @@ when /linux/
143
153
  when /aix/
144
154
  CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G -Wl,-brtl"
145
155
 
156
+ when /cygwin/
157
+ # For rubies built with Cygwin, CXX may be set to CC, which is just
158
+ # a wrapper for gcc.
159
+ # This will compile, but it will not link to the C++ std library.
160
+ # Explicitly set CXX to use g++.
161
+ CONFIG['CXX'] = "g++"
162
+ # on Unix we need a g++ link, not gcc.
163
+ CONFIG['LDSHARED'] = "$(CXX) -shared"
164
+
146
165
  else
147
166
  # on Unix we need a g++ link, not gcc.
148
167
  CONFIG['LDSHARED'] = "$(CXX) -shared"
@@ -158,4 +177,4 @@ add_define 'HAVE_MAKE_PAIR' if try_link(<<SRC, '-lstdc++')
158
177
  SRC
159
178
  TRY_LINK.sub!('$(CXX)', '$(CC)')
160
179
 
161
- create_makefile "rubyeventmachine"
180
+ create_makefile "rubyeventmachine"
@@ -17,7 +17,7 @@ add_define 'BUILD_FOR_RUBY'
17
17
  # Minor platform details between *nix and Windows:
18
18
 
19
19
  if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
20
- GNU_CHAIN = $1 == 'mingw'
20
+ GNU_CHAIN = ENV['CROSS_COMPILING'] or $1 == 'mingw'
21
21
  OS_WIN32 = true
22
22
  add_define "OS_WIN32"
23
23
  else
@@ -26,6 +26,15 @@ else
26
26
  add_define 'OS_UNIX'
27
27
  end
28
28
 
29
+ # Adjust number of file descriptors (FD) on Windows
30
+
31
+ if RbConfig::CONFIG["host_os"] =~ /mingw/
32
+ found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
33
+ any? { |v| v.include?("FD_SETSIZE") }
34
+
35
+ add_define "FD_SETSIZE=32767" unless found
36
+ end
37
+
29
38
  # Main platform invariances:
30
39
 
31
40
  case RUBY_PLATFORM
@@ -77,9 +86,18 @@ when /aix/
77
86
  # on Unix we need a g++ link, not gcc.
78
87
  CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G"
79
88
 
89
+ when /cygwin/
90
+ # For rubies built with Cygwin, CXX may be set to CC, which is just
91
+ # a wrapper for gcc.
92
+ # This will compile, but it will not link to the C++ std library.
93
+ # Explicitly set CXX to use g++.
94
+ CONFIG['CXX'] = "g++"
95
+ # on Unix we need a g++ link, not gcc.
96
+ CONFIG['LDSHARED'] = "$(CXX) -shared"
97
+
80
98
  else
81
99
  # on Unix we need a g++ link, not gcc.
82
100
  CONFIG['LDSHARED'] = "$(CXX) -shared"
83
101
  end
84
102
 
85
- create_makefile "fastfilereaderext"
103
+ create_makefile "fastfilereaderext"
data/ext/pipe.cpp CHANGED
@@ -282,7 +282,7 @@ bool PipeDescriptor::SelectForRead()
282
282
  * a pending state, so this is simpler than for the
283
283
  * ConnectionDescriptor object.
284
284
  */
285
- return true;
285
+ return bPaused ? false : true;
286
286
  }
287
287
 
288
288
  /******************************
@@ -295,7 +295,7 @@ bool PipeDescriptor::SelectForWrite()
295
295
  * a pending state, so this is simpler than for the
296
296
  * ConnectionDescriptor object.
297
297
  */
298
- return (GetOutboundDataSize() > 0);
298
+ return (GetOutboundDataSize() > 0) && !bPaused ? true : false;
299
299
  }
300
300
 
301
301
 
data/ext/project.h CHANGED
@@ -82,7 +82,8 @@ typedef int SOCKET;
82
82
 
83
83
  #ifdef OS_WIN32
84
84
  // 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
85
- #define FD_SETSIZE 1024
85
+ // 18Jun12: fd_setsize must be changed in the ruby binary (not in this extension). redefining it also causes segvs, see eventmachine/eventmachine#333
86
+ //#define FD_SETSIZE 1024
86
87
 
87
88
  #define WIN32_LEAN_AND_MEAN
88
89
  #include <windows.h>
@@ -96,7 +97,7 @@ typedef int socklen_t;
96
97
  typedef int pid_t;
97
98
  #endif
98
99
 
99
- #if !defined(_MSC_VER) || _MSC_VER > 1400
100
+ #if !defined(_MSC_VER) || _MSC_VER > 1500
100
101
  #include <stdint.h>
101
102
  #endif
102
103