eventmachine 1.0.0.beta.4-java → 1.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,10 +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
- GEMSPEC = eval(File.read(File.expand_path('../eventmachine.gemspec', __FILE__)))
6
-
7
- require 'yard'
8
4
  require 'rake/clean'
9
5
  task :clobber => :clean
10
6
 
@@ -12,8 +8,13 @@ desc "Build eventmachine, then run tests."
12
8
  task :default => [:compile, :test]
13
9
 
14
10
  desc 'Generate documentation'
15
- YARD::Rake::YardocTask.new do |t|
16
- t.files = ['lib/**/*.rb', '-', 'docs/*.md']
17
- t.options = ['--main', 'README.md', '--no-private']
18
- 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
19
20
  end
@@ -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.9'
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
 
@@ -253,6 +253,15 @@ extern "C" int evma_is_paused (const unsigned long binding)
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,12 +54,14 @@ 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),
@@ -115,6 +117,7 @@ EventableDescriptor::~EventableDescriptor()
115
117
  (*EventCallback)(ProxiedFrom->GetBinding(), EM_PROXY_TARGET_UNBOUND, NULL, 0);
116
118
  ProxiedFrom->StopProxy();
117
119
  }
120
+ MyEventMachine->NumCloseScheduled--;
118
121
  StopProxy();
119
122
  Close();
120
123
  }
@@ -179,7 +182,7 @@ void EventableDescriptor::Close()
179
182
  MyEventMachine->Deregister (this);
180
183
 
181
184
  // Do not close STDIN, STDOUT, STDERR
182
- if (MySocket > 2 && !bWatchOnly) {
185
+ if (MySocket > 2 && !bAttached) {
183
186
  shutdown (MySocket, 1);
184
187
  close (MySocket);
185
188
  }
@@ -214,6 +217,7 @@ EventableDescriptor::ScheduleClose
214
217
 
215
218
  void EventableDescriptor::ScheduleClose (bool after_writing)
216
219
  {
220
+ MyEventMachine->NumCloseScheduled++;
217
221
  // KEEP THIS SYNCHRONIZED WITH ::IsCloseScheduled.
218
222
  if (after_writing)
219
223
  bCloseAfterWriting = true;
@@ -244,6 +248,7 @@ void EventableDescriptor::StartProxy(const unsigned long to, const unsigned long
244
248
  StopProxy();
245
249
  ProxyTarget = ed;
246
250
  BytesToProxy = length;
251
+ ProxiedBytes = 0;
247
252
  ed->SetProxiedFrom(this, bufsize);
248
253
  return;
249
254
  }
@@ -290,6 +295,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
290
295
  if (BytesToProxy > 0) {
291
296
  unsigned long proxied = min(BytesToProxy, (unsigned long) size);
292
297
  ProxyTarget->SendOutboundData(buf, proxied);
298
+ ProxiedBytes += (unsigned long) proxied;
293
299
  BytesToProxy -= proxied;
294
300
  if (BytesToProxy == 0) {
295
301
  StopProxy();
@@ -300,6 +306,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size)
300
306
  }
301
307
  } else {
302
308
  ProxyTarget->SendOutboundData(buf, size);
309
+ ProxiedBytes += (unsigned long) size;
303
310
  }
304
311
  } else {
305
312
  (*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf, size);
@@ -457,6 +464,16 @@ void ConnectionDescriptor::SetConnectPending(bool f)
457
464
  }
458
465
 
459
466
 
467
+ /**********************************
468
+ ConnectionDescriptor::SetAttached
469
+ ***********************************/
470
+
471
+ void ConnectionDescriptor::SetAttached(bool state)
472
+ {
473
+ bAttached = state;
474
+ }
475
+
476
+
460
477
  /**********************************
461
478
  ConnectionDescriptor::SetWatchOnly
462
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,6 +87,7 @@ 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
93
  virtual bool IsPaused(){ return bPaused; }
@@ -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
 
@@ -169,6 +173,7 @@ class ConnectionDescriptor: public EventableDescriptor
169
173
 
170
174
  void SetNotifyReadable (bool);
171
175
  void SetNotifyWritable (bool);
176
+ void SetAttached (bool);
172
177
  void SetWatchOnly (bool);
173
178
 
174
179
  bool Pause();
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;
@@ -520,8 +520,7 @@ bool EventMachine_t::_RunEpollOnce()
520
520
  assert (epfd != -1);
521
521
  int s;
522
522
 
523
- timeval tv;
524
- _TimeTilNextEvent(&tv);
523
+ timeval tv = _TimeTilNextEvent();
525
524
 
526
525
  #ifdef BUILD_FOR_RUBY
527
526
  int ret = 0;
@@ -591,8 +590,7 @@ bool EventMachine_t::_RunKqueueOnce()
591
590
  assert (kqfd != -1);
592
591
  int k;
593
592
 
594
- timeval tv;
595
- _TimeTilNextEvent(&tv);
593
+ timeval tv = _TimeTilNextEvent();
596
594
 
597
595
  struct timespec ts;
598
596
  ts.tv_sec = tv.tv_sec;
@@ -673,9 +671,15 @@ bool EventMachine_t::_RunKqueueOnce()
673
671
  EventMachine_t::_TimeTilNextEvent
674
672
  *********************************/
675
673
 
676
- timeval *EventMachine_t::_TimeTilNextEvent(timeval *tv)
674
+ timeval EventMachine_t::_TimeTilNextEvent()
677
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.
678
681
  uint64_t next_event = 0;
682
+ uint64_t current_time = GetRealTime();
679
683
 
680
684
  if (!Heartbeats.empty()) {
681
685
  multimap<uint64_t,EventableDescriptor*>::iterator heartbeats = Heartbeats.begin();
@@ -689,20 +693,20 @@ timeval *EventMachine_t::_TimeTilNextEvent(timeval *tv)
689
693
  }
690
694
 
691
695
  if (!NewDescriptors.empty() || !ModifiedDescriptors.empty()) {
692
- next_event = MyCurrentLoopTime;
696
+ next_event = current_time;
693
697
  }
698
+
699
+ timeval tv;
694
700
 
695
- if (next_event == 0) {
696
- // tv->tv_sec = Quantum->tv_sec;
697
- // tv->tv_usec = Quantum->tv_usec;
698
- return NULL;
701
+ if (next_event == 0 || NumCloseScheduled > 0) {
702
+ tv = Quantum;
699
703
  } else {
700
- if (next_event > MyCurrentLoopTime) {
701
- uint64_t duration = next_event - MyCurrentLoopTime;
702
- tv->tv_sec = duration / 1000000;
703
- tv->tv_usec = duration % 1000000;
704
+ if (next_event > current_time) {
705
+ uint64_t duration = next_event - current_time;
706
+ tv.tv_sec = duration / 1000000;
707
+ tv.tv_usec = duration % 1000000;
704
708
  } else {
705
- tv->tv_sec = tv->tv_usec = 0;
709
+ tv.tv_sec = tv.tv_usec = 0;
706
710
  }
707
711
  }
708
712
 
@@ -908,7 +912,7 @@ bool EventMachine_t::_RunSelectOnce()
908
912
  { // read and write the sockets
909
913
  //timeval tv = {1, 0}; // Solaris fails if the microseconds member is >= 1000000.
910
914
  //timeval tv = Quantum;
911
- _TimeTilNextEvent(&SelectData.tv);
915
+ SelectData.tv = _TimeTilNextEvent();
912
916
  int s = SelectData._Select();
913
917
  //rb_thread_blocking_region(xxx,(void*)&SelectData,RUBY_UBF_IO,0);
914
918
  //int s = EmSelect (SelectData.maxsocket+1, &(SelectData.fdreads), &(SelectData.fdwrites), NULL, &(SelectData.tv));
@@ -1259,7 +1263,7 @@ const unsigned long EventMachine_t::ConnectToUnixServer (const char *server)
1259
1263
 
1260
1264
  #ifdef OS_WIN32
1261
1265
  throw std::runtime_error ("unix-domain connection unavailable on this platform");
1262
- return NULL;
1266
+ return 0;
1263
1267
  #endif
1264
1268
 
1265
1269
  // The whole rest of this function is only compiled on Unix systems.
@@ -1358,6 +1362,7 @@ const unsigned long EventMachine_t::AttachFD (int fd, bool watch_mode)
1358
1362
  if (!cd)
1359
1363
  throw std::runtime_error ("no connection allocated");
1360
1364
 
1365
+ cd->SetAttached(true);
1361
1366
  cd->SetWatchOnly(watch_mode);
1362
1367
  cd->SetConnectPending (false);
1363
1368
 
@@ -1397,7 +1402,11 @@ int EventMachine_t::DetachFD (EventableDescriptor *ed)
1397
1402
  if (bKqueue) {
1398
1403
  // remove any read/write events for this fd
1399
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
1400
1408
  EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, ed);
1409
+ #endif
1401
1410
  int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
1402
1411
  if (t < 0 && (errno != ENOENT) && (errno != EBADF)) {
1403
1412
  char buf [200];
@@ -1653,7 +1662,11 @@ void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed)
1653
1662
  if (!ed)
1654
1663
  throw std::runtime_error ("added bad descriptor");
1655
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
1656
1668
  EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, ed);
1669
+ #endif
1657
1670
  int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
1658
1671
  if (t < 0) {
1659
1672
  char buf [200];
@@ -1675,7 +1688,11 @@ void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed)
1675
1688
  if (!ed)
1676
1689
  throw std::runtime_error ("added bad descriptor");
1677
1690
  struct kevent k;
1691
+ #ifdef __NetBSD__
1692
+ EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed);
1693
+ #else
1678
1694
  EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed);
1695
+ #endif
1679
1696
  int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
1680
1697
  if (t < 0) {
1681
1698
  char buf [200];
@@ -1726,7 +1743,11 @@ void EventMachine_t::_AddNewDescriptors()
1726
1743
  // INCOMPLETE. Some descriptors don't want to be readable.
1727
1744
  assert (kqfd != -1);
1728
1745
  struct kevent k;
1746
+ #ifdef __NetBSD__
1747
+ EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed);
1748
+ #else
1729
1749
  EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed);
1750
+ #endif
1730
1751
  int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
1731
1752
  assert (t == 0);
1732
1753
  }
data/ext/em.h CHANGED
@@ -44,10 +44,10 @@ See the file COPYING for complete licensing information.
44
44
  #define RUBY_UBF_IO RB_UBF_DFL
45
45
  #endif
46
46
  #ifndef RSTRING_PTR
47
- #define RSTRING_PTR(str) RString(str)->ptr
47
+ #define RSTRING_PTR(str) RSTRING(str)->ptr
48
48
  #endif
49
49
  #ifndef RSTRING_LEN
50
- #define RSTRING_LEN(str) RString(str)->len
50
+ #define RSTRING_LEN(str) RSTRING(str)->len
51
51
  #endif
52
52
  #ifndef RSTRING_LENINT
53
53
  #define RSTRING_LENINT(str) RSTRING_LEN(str)
@@ -161,6 +161,7 @@ class EventMachine_t
161
161
  public:
162
162
  void _ReadLoopBreaker();
163
163
  void _ReadInotifyEvents();
164
+ int NumCloseScheduled;
164
165
 
165
166
  private:
166
167
  enum {
@@ -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
 
@@ -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"
@@ -87,12 +88,21 @@ else
87
88
  add_define "HAVE_KQUEUE" if have_header("sys/event.h") and have_header("sys/queue.h")
88
89
  end
89
90
 
91
+ # Adjust number of file descriptors (FD) on Windows
92
+
93
+ if RbConfig::CONFIG["host_os"] =~ /mingw/
94
+ found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
95
+ any? { |v| v.include?("FD_SETSIZE") }
96
+
97
+ add_define "FD_SETSIZE=32767" unless found
98
+ end
99
+
90
100
  # Main platform invariances:
91
101
 
92
102
  case RUBY_PLATFORM
93
103
  when /mswin32/, /mingw32/, /bccwin32/
94
104
  check_heads(%w[windows.h winsock.h], true)
95
- check_libs(%w[kernel32 rpcrt4 gdi32], true) unless ENV['CROSS_COMPILING']
105
+ check_libs(%w[kernel32 rpcrt4 gdi32], true)
96
106
 
97
107
  if GNU_CHAIN
98
108
  CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++"
@@ -139,6 +149,15 @@ when /linux/
139
149
  when /aix/
140
150
  CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G -Wl,-brtl"
141
151
 
152
+ when /cygwin/
153
+ # For rubies built with Cygwin, CXX may be set to CC, which is just
154
+ # a wrapper for gcc.
155
+ # This will compile, but it will not link to the C++ std library.
156
+ # Explicitly set CXX to use g++.
157
+ CONFIG['CXX'] = "g++"
158
+ # on Unix we need a g++ link, not gcc.
159
+ CONFIG['LDSHARED'] = "$(CXX) -shared"
160
+
142
161
  else
143
162
  # on Unix we need a g++ link, not gcc.
144
163
  CONFIG['LDSHARED'] = "$(CXX) -shared"