eventmachine 1.0.3-x86-mingw32 → 1.2.0.dev.2-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +84 -1
  3. data/README.md +6 -7
  4. data/ext/binder.cpp +10 -10
  5. data/ext/binder.h +5 -5
  6. data/ext/cmain.cpp +173 -61
  7. data/ext/ed.cpp +262 -127
  8. data/ext/ed.h +50 -30
  9. data/ext/em.cpp +491 -445
  10. data/ext/em.h +101 -36
  11. data/ext/eventmachine.h +67 -51
  12. data/ext/extconf.rb +124 -31
  13. data/ext/fastfilereader/extconf.rb +9 -2
  14. data/ext/fastfilereader/mapper.cpp +3 -1
  15. data/ext/fastfilereader/rubymain.cpp +7 -7
  16. data/ext/kb.cpp +1 -1
  17. data/ext/pipe.cpp +11 -4
  18. data/ext/project.h +26 -6
  19. data/ext/rubymain.cpp +408 -201
  20. data/ext/ssl.cpp +167 -20
  21. data/ext/ssl.h +11 -2
  22. data/java/src/com/rubyeventmachine/EmReactor.java +16 -0
  23. data/java/src/com/rubyeventmachine/EventableChannel.java +2 -0
  24. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +6 -0
  25. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +55 -10
  26. data/lib/1.9/fastfilereaderext.so +0 -0
  27. data/lib/1.9/rubyeventmachine.so +0 -0
  28. data/lib/2.0/fastfilereaderext.so +0 -0
  29. data/lib/2.0/rubyeventmachine.so +0 -0
  30. data/lib/2.1/fastfilereaderext.so +0 -0
  31. data/lib/2.1/rubyeventmachine.so +0 -0
  32. data/lib/2.2/fastfilereaderext.so +0 -0
  33. data/lib/2.2/rubyeventmachine.so +0 -0
  34. data/lib/2.3/fastfilereaderext.so +0 -0
  35. data/lib/2.3/rubyeventmachine.so +0 -0
  36. data/lib/em/buftok.rb +34 -85
  37. data/lib/em/channel.rb +5 -0
  38. data/lib/em/completion.rb +2 -2
  39. data/lib/em/connection.rb +62 -4
  40. data/lib/em/iterator.rb +30 -48
  41. data/lib/em/pool.rb +1 -1
  42. data/lib/em/protocols/httpclient.rb +31 -11
  43. data/lib/em/protocols/line_and_text.rb +4 -4
  44. data/lib/em/protocols/linetext2.rb +44 -39
  45. data/lib/em/protocols/smtpclient.rb +60 -31
  46. data/lib/em/protocols/smtpserver.rb +32 -9
  47. data/lib/em/pure_ruby.rb +8 -3
  48. data/lib/em/queue.rb +16 -7
  49. data/lib/em/resolver.rb +64 -24
  50. data/lib/em/threaded_resource.rb +2 -2
  51. data/lib/em/tick_loop.rb +19 -19
  52. data/lib/em/version.rb +1 -1
  53. data/lib/eventmachine.rb +96 -49
  54. data/lib/jeventmachine.rb +17 -0
  55. data/rakelib/package.rake +31 -4
  56. data/tests/dhparam.pem +13 -0
  57. data/tests/em_test_helper.rb +87 -0
  58. data/tests/test_attach.rb +25 -0
  59. data/tests/test_basic.rb +27 -38
  60. data/tests/test_channel.rb +14 -1
  61. data/tests/test_completion.rb +1 -0
  62. data/tests/test_connection_count.rb +22 -1
  63. data/tests/test_connection_write.rb +35 -0
  64. data/tests/test_defer.rb +17 -0
  65. data/tests/test_epoll.rb +26 -14
  66. data/tests/test_file_watch.rb +1 -0
  67. data/tests/test_fork.rb +75 -0
  68. data/tests/test_httpclient.rb +43 -0
  69. data/tests/test_idle_connection.rb +6 -4
  70. data/tests/test_ipv4.rb +125 -0
  71. data/tests/test_ipv6.rb +131 -0
  72. data/tests/test_iterator.rb +115 -0
  73. data/tests/test_kb.rb +19 -25
  74. data/tests/test_ltp2.rb +20 -0
  75. data/tests/test_many_fds.rb +22 -0
  76. data/tests/test_pause.rb +29 -0
  77. data/tests/test_pool.rb +2 -0
  78. data/tests/test_process_watch.rb +2 -0
  79. data/tests/test_processes.rb +7 -7
  80. data/tests/test_queue.rb +14 -0
  81. data/tests/test_resolver.rb +56 -7
  82. data/tests/test_set_sock_opt.rb +2 -0
  83. data/tests/test_smtpclient.rb +20 -0
  84. data/tests/test_ssl_args.rb +2 -2
  85. data/tests/test_ssl_dhparam.rb +83 -0
  86. data/tests/test_ssl_ecdh_curve.rb +79 -0
  87. data/tests/test_ssl_extensions.rb +49 -0
  88. data/tests/test_ssl_methods.rb +22 -5
  89. data/tests/test_ssl_protocols.rb +246 -0
  90. data/tests/test_ssl_verify.rb +103 -59
  91. data/tests/test_system.rb +4 -0
  92. data/tests/test_threaded_resource.rb +8 -0
  93. data/tests/test_unbind_reason.rb +5 -1
  94. metadata +173 -107
  95. data/.gitignore +0 -21
  96. data/.travis.yml +0 -12
  97. data/.yardopts +0 -7
  98. data/Gemfile +0 -2
  99. data/Rakefile +0 -20
  100. data/eventmachine.gemspec +0 -36
  101. data/rakelib/cpp.rake_example +0 -77
@@ -268,6 +268,20 @@ module EventMachine
268
268
  @em.getConnectionCount
269
269
  end
270
270
 
271
+ def self.pause_connection(sig)
272
+ @em.pauseConnection(sig)
273
+ end
274
+ def self.resume_connection(sig)
275
+ @em.resumeConnection(sig)
276
+ end
277
+ def self.connection_paused?(sig)
278
+ @em.isConnectionPaused(sig)
279
+ end
280
+ def self._get_outbound_data_size(sig)
281
+ @em.getOutboundDataSize(sig)
282
+ end
283
+
284
+
271
285
  def self.set_tls_parms(sig, params)
272
286
  end
273
287
  def self.start_tls(sig)
@@ -279,6 +293,9 @@ module EventMachine
279
293
  def associate_callback_target sig
280
294
  # No-op for the time being
281
295
  end
296
+ def get_outbound_data_size
297
+ EM._get_outbound_data_size @signature
298
+ end
282
299
  end
283
300
  end
284
301
 
@@ -25,14 +25,19 @@ else
25
25
  def setup_cross_compilation(ext)
26
26
  unless RUBY_PLATFORM =~ /mswin|mingw/
27
27
  ext.cross_compile = true
28
- ext.cross_platform = ['x86-mingw32', 'x86-mswin32-60']
28
+ ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
29
29
  end
30
30
  end
31
31
  def hack_cross_compilation(ext)
32
32
  # inject 1.8/1.9 pure-ruby entry point
33
33
  # HACK: add these dependencies to the task instead of using cross_compiling
34
- ext.cross_platform.each do |platform|
35
- Rake::Task["native:#{GEMSPEC.name}:#{platform}"].prerequisites.unshift "lib/#{ext.name}.rb"
34
+ if ext.cross_platform.is_a?(Array)
35
+ ext.cross_platform.each do |platform|
36
+ task = "native:#{GEMSPEC.name}:#{platform}"
37
+ if Rake::Task.task_defined?(task)
38
+ Rake::Task[task].prerequisites.unshift "lib/#{ext.name}.rb"
39
+ end
40
+ end
36
41
  end
37
42
  end
38
43
 
@@ -60,7 +65,7 @@ end
60
65
  require "\#{$1}/#{File.basename(t.name, '.rb')}"
61
66
  eoruby
62
67
  end
63
- at_exit{ FileUtils.rm t.name if File.exists?(t.name) }
68
+ at_exit{ FileUtils.rm t.name if File.exist?(t.name) }
64
69
  end
65
70
  end
66
71
 
@@ -91,3 +96,25 @@ def gem_cmd(action, name, *args)
91
96
  end
92
97
 
93
98
  Rake::Task[:clean].enhance [:clobber_package]
99
+
100
+ # DevKit task following the example of Luis Lavena's test-ruby-c-extension
101
+ task :devkit do
102
+ begin
103
+ require "devkit"
104
+ rescue LoadError => e
105
+ abort "Failed to activate RubyInstaller's DevKit required for compilation."
106
+ end
107
+ end
108
+
109
+ if RUBY_PLATFORM =~ /mingw|mswin/
110
+ Rake::Task['compile'].prerequisites.unshift 'devkit'
111
+ end
112
+
113
+ desc "Build binary gems for Windows with rake-compiler-dock"
114
+ task 'gem:windows' do
115
+ require 'rake_compiler_dock'
116
+ RakeCompilerDock.sh <<-EOT
117
+ RUBY_CC_VERSION="${RUBY_CC_VERSION//1.8.7/}"
118
+ bundle && rake cross native gem
119
+ EOT
120
+ end
@@ -0,0 +1,13 @@
1
+ -----BEGIN DH PARAMETERS-----
2
+ MIICCAKCAgEAikiatXa5aAteOtd6hOO33npjCvJByD3dwuM8rWzz0DFZdUH9nFJi
3
+ b0VvTVweVECb6XZBsrDNLqGQykCrm43swSk5D9XQCGJLxFERD6yk3b90xaeCm3/a
4
+ b0Ek5ZVvV73Cc/YbVmpBiOHoTFpUFJLZ7pLMQUSn8y3qUlNcY9/88HuwFi1s1lRM
5
+ ovihSRyZMYAuYWOD4yuOuIcroKVjD6gWFrsW9XrALWny6vUXQrhk8Q3rj+wM6ZtE
6
+ 5afcB0b6ZJtphrDfk3dFjOVG/zVT37VWgrY8GABrpo2ey0W0WIQJ7rDKLaPaI4kc
7
+ voOgC2K8Z3kSARZK+jULnwmBeYECz4EH/FF6FEp3GOKtkL4mqEkvh1n5EAesDOGl
8
+ iiX+RZXcUrZliSeifSXBTMJWWFVC0fkGIMb9PTZfZHyAC54lpuxzVki0HIyQG9Fs
9
+ 41zBJ5e8eEoXXlfUYtduUC35YGy2IxSzYLAJE76rctAZSWghha9xLOCDFoLjMr8h
10
+ FosKeHKJcBQ0bc8ymOpRIfrYLWhc0Pz2zkpJ/4eYw9t7NYg7S+jP19IE0gUnuM9v
11
+ SpoYMtS28tP9nEdokdwuBKD0D3bJEBBefDlHgfXoMgvy9Hivc9PBGGNTNpyFPpwF
12
+ sWVAkfhoNMJMC5V7LZsze+lftiDtzVoLSPDa9bO4BK7b/MgwCxfOhGsCAQI=
13
+ -----END DH PARAMETERS-----
@@ -31,6 +31,61 @@ class Test::Unit::TestCase
31
31
  @@port
32
32
  end
33
33
 
34
+ # Returns true if the host have a localhost 127.0.0.1 IPv4.
35
+ def self.local_ipv4?
36
+ return @@has_local_ipv4 if defined?(@@has_local_ipv4)
37
+ begin
38
+ get_my_ipv4_address "127.0.0.1"
39
+ @@has_local_ipv4 = true
40
+ rescue
41
+ @@has_local_ipv4 = false
42
+ end
43
+ end
44
+
45
+ # Returns true if the host have a public IPv4 and stores it in
46
+ # @@public_ipv4.
47
+ def self.public_ipv4?
48
+ return @@has_public_ipv4 if defined?(@@has_public_ipv4)
49
+ begin
50
+ @@public_ipv4 = get_my_ipv4_address "1.2.3.4"
51
+ @@has_public_ipv4 = true
52
+ rescue
53
+ @@has_public_ipv4 = false
54
+ end
55
+ end
56
+
57
+ # Returns true if the host have a localhost ::1 IPv6.
58
+ def self.local_ipv6?
59
+ return @@has_local_ipv6 if defined?(@@has_local_ipv6)
60
+ begin
61
+ get_my_ipv6_address "::1"
62
+ @@has_local_ipv6 = true
63
+ rescue
64
+ @@has_local_ipv6 = false
65
+ end
66
+ end
67
+
68
+ # Returns true if the host have a public IPv6 and stores it in
69
+ # @@public_ipv6.
70
+ def self.public_ipv6?
71
+ return @@has_public_ipv6 if defined?(@@has_public_ipv6)
72
+ begin
73
+ @@public_ipv6 = get_my_ipv6_address "2001::1"
74
+ @@has_public_ipv6 = true
75
+ rescue
76
+ @@has_public_ipv6 = false
77
+ end
78
+ end
79
+
80
+ # Returns an array with the localhost addresses (IPv4 and/or IPv6).
81
+ def local_ips
82
+ return @@local_ips if defined?(@@local_ips)
83
+ @@local_ips = []
84
+ @@local_ips << "127.0.0.1" if self.class.local_ipv4?
85
+ @@local_ips << "::1" if self.class.local_ipv6?
86
+ @@local_ips
87
+ end
88
+
34
89
  def exception_class
35
90
  jruby? ? NativeException : RuntimeError
36
91
  end
@@ -41,10 +96,18 @@ class Test::Unit::TestCase
41
96
  RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
42
97
  end
43
98
 
99
+ def solaris?
100
+ RUBY_PLATFORM =~ /solaris/
101
+ end
102
+
44
103
  # http://stackoverflow.com/questions/1342535/how-can-i-tell-if-im-running-from-jruby-vs-ruby/1685970#1685970
45
104
  def jruby?
46
105
  defined? JRUBY_VERSION
47
106
  end
107
+
108
+ def rbx?
109
+ defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
110
+ end
48
111
  end
49
112
 
50
113
  include PlatformHelper
@@ -61,4 +124,28 @@ class Test::Unit::TestCase
61
124
  $VERBOSE = backup
62
125
  end
63
126
  end
127
+
128
+
129
+ private
130
+
131
+ def self.get_my_ipv4_address ip
132
+ orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
133
+ UDPSocket.open(Socket::AF_INET) do |s|
134
+ s.connect ip, 1
135
+ s.addr.last
136
+ end
137
+ ensure
138
+ Socket.do_not_reverse_lookup = orig
139
+ end
140
+
141
+ def self.get_my_ipv6_address ip
142
+ orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
143
+ UDPSocket.open(Socket::AF_INET6) do |s|
144
+ s.connect ip, 1
145
+ s.addr.last
146
+ end
147
+ ensure
148
+ Socket.do_not_reverse_lookup = orig
149
+ end
150
+
64
151
  end
@@ -4,6 +4,7 @@ require 'socket'
4
4
  class TestAttach < Test::Unit::TestCase
5
5
  class EchoServer < EM::Connection
6
6
  def receive_data data
7
+ $received_data << data
7
8
  send_data data
8
9
  end
9
10
  end
@@ -31,12 +32,14 @@ class TestAttach < Test::Unit::TestCase
31
32
  def setup
32
33
  @port = next_port
33
34
  $read, $r, $w, $fd = nil
35
+ $received_data = ""
34
36
  end
35
37
 
36
38
  def teardown
37
39
  [$r, $w].each do |io|
38
40
  io.close rescue nil
39
41
  end
42
+ $received_data = nil
40
43
  end
41
44
 
42
45
  def test_attach
@@ -63,6 +66,28 @@ class TestAttach < Test::Unit::TestCase
63
66
  end
64
67
  end
65
68
 
69
+ def test_attach_server
70
+ omit_if(jruby?)
71
+ $before = TCPServer.new("127.0.0.1", @port)
72
+ sig = nil
73
+ EM.run {
74
+ sig = EM.attach_server $before, EchoServer
75
+
76
+ handler = Class.new(EM::Connection) do
77
+ def initialize
78
+ send_data "hello world"
79
+ close_connection_after_writing
80
+ EM.add_timer(0.1) { EM.stop }
81
+ end
82
+ end
83
+ EM.connect("127.0.0.1", @port, handler)
84
+ }
85
+
86
+ assert_equal false, $before.closed?
87
+ assert_equal "hello world", $received_data
88
+ assert sig.is_a?(Integer)
89
+ end
90
+
66
91
  def test_attach_pipe
67
92
  EM.run{
68
93
  $r, $w = IO.pipe
@@ -93,15 +93,28 @@ class TestBasic < Test::Unit::TestCase
93
93
  end
94
94
  end
95
95
 
96
- def test_unbind_error
96
+ def test_unbind_error_during_stop
97
97
  assert_raises( UnbindError::ERR ) {
98
98
  EM.run {
99
99
  EM.start_server "127.0.0.1", @port
100
- EM.connect "127.0.0.1", @port, UnbindError
100
+ EM.connect "127.0.0.1", @port, UnbindError do
101
+ EM.stop
102
+ end
101
103
  }
102
104
  }
103
105
  end
104
106
 
107
+ def test_unbind_error
108
+ EM.run {
109
+ EM.error_handler do |e|
110
+ assert(e.is_a?(UnbindError::ERR))
111
+ EM.stop
112
+ end
113
+ EM.start_server "127.0.0.1", @port
114
+ EM.connect "127.0.0.1", @port, UnbindError
115
+ }
116
+ end
117
+
105
118
  module BrsTestSrv
106
119
  def receive_data data
107
120
  $received << data
@@ -131,6 +144,8 @@ class TestBasic < Test::Unit::TestCase
131
144
  end
132
145
 
133
146
  def test_bind_connect
147
+ pend('FIXME: this test is broken on Windows') if windows?
148
+
134
149
  local_ip = UDPSocket.open {|s| s.connect('google.com', 80); s.addr.last }
135
150
 
136
151
  bind_port = next_port
@@ -179,18 +194,15 @@ class TestBasic < Test::Unit::TestCase
179
194
  assert x
180
195
  end
181
196
 
182
- if EM.respond_to? :set_heartbeat_interval
183
- def test_set_heartbeat_interval
184
- interval = 0.5
185
- EM.run {
186
- EM.set_heartbeat_interval interval
187
- $interval = EM.get_heartbeat_interval
188
- EM.stop
189
- }
190
- assert_equal(interval, $interval)
191
- end
192
- else
193
- warn "EM.set_heartbeat_interval not implemented, skipping a test in #{__FILE__}"
197
+ def test_set_heartbeat_interval
198
+ omit_if(jruby?)
199
+ interval = 0.5
200
+ EM.run {
201
+ EM.set_heartbeat_interval interval
202
+ $interval = EM.get_heartbeat_interval
203
+ EM.stop
204
+ }
205
+ assert_equal(interval, $interval)
194
206
  end
195
207
 
196
208
  module PostInitRaiser
@@ -226,6 +238,7 @@ class TestBasic < Test::Unit::TestCase
226
238
  end
227
239
 
228
240
  def test_schedule_close
241
+ omit_if(jruby?)
229
242
  localhost, port = '127.0.0.1', 9000
230
243
  timer_ran = false
231
244
  num_close_scheduled = nil
@@ -246,30 +259,6 @@ class TestBasic < Test::Unit::TestCase
246
259
  assert_equal 1, num_close_scheduled
247
260
  end
248
261
 
249
- def test_fork_safe
250
- return unless cpid = fork { exit! } rescue false
251
-
252
- read, write = IO.pipe
253
- EM.run do
254
- cpid = fork do
255
- write.puts "forked"
256
- EM.run do
257
- EM.next_tick do
258
- write.puts "EM ran"
259
- exit!
260
- end
261
- end
262
- end
263
- EM.stop
264
- end
265
- Process.waitall
266
- assert_equal "forked\n", read.readline
267
- assert_equal "EM ran\n", read.readline
268
- ensure
269
- read.close rescue nil
270
- write.close rescue nil
271
- end
272
-
273
262
  def test_error_handler_idempotent # issue 185
274
263
  errors = []
275
264
  ticks = []
@@ -59,4 +59,17 @@ class TestEMChannel < Test::Unit::TestCase
59
59
 
60
60
  assert_equal [1,2,3], out
61
61
  end
62
- end
62
+
63
+ def test_channel_num_subscribers
64
+ subs = 0
65
+ EM.run do
66
+ c = EM::Channel.new
67
+ c.subscribe { |v| s = v }
68
+ c.subscribe { |v| s = v }
69
+ EM.next_tick { EM.stop }
70
+ subs = c.num_subscribers
71
+ end
72
+
73
+ assert_equal subs, 2
74
+ end
75
+ end
@@ -1,3 +1,4 @@
1
+ require 'em_test_helper'
1
2
  require 'em/completion'
2
3
 
3
4
  class TestCompletion < Test::Unit::TestCase
@@ -30,4 +30,25 @@ class TestConnectionCount < Test::Unit::TestCase
30
30
  assert_equal(1, $server_conns)
31
31
  assert_equal(4, $client_conns + $server_conns)
32
32
  end
33
- end
33
+
34
+ module DoubleCloseClient
35
+ def unbind
36
+ close_connection
37
+ $num_close_scheduled_1 = EM.num_close_scheduled
38
+ EM.next_tick do
39
+ $num_close_scheduled_2 = EM.num_close_scheduled
40
+ EM.stop
41
+ end
42
+ end
43
+ end
44
+
45
+ def test_num_close_scheduled
46
+ omit_if(jruby?)
47
+ EM.run {
48
+ assert_equal(0, EM.num_close_scheduled)
49
+ EM.connect("127.0.0.1", 9999, DoubleCloseClient) # nothing listening on 9999
50
+ }
51
+ assert_equal(1, $num_close_scheduled_1)
52
+ assert_equal(0, $num_close_scheduled_2)
53
+ end
54
+ end
@@ -0,0 +1,35 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestConnectionWrite < Test::Unit::TestCase
4
+
5
+ # This test takes advantage of the fact that EM::_RunSelectOnce iterates over the connections twice:
6
+ # - once to determine which ones to call Write() on
7
+ # - and once to call Write() on each of them.
8
+ #
9
+ # But state may change in the meantime before Write() is finally called.
10
+ # And that is what we try to exploit to get Write() to be called when bWatchOnly is true, and bNotifyWritable is false,
11
+ # to cause an assertion failure.
12
+
13
+ module SimpleClient
14
+ def notify_writable
15
+ $conn2.notify_writable = false # Being naughty in callback
16
+ # If this doesn't crash anything, the test passed!
17
+ end
18
+ end
19
+
20
+ def test_with_naughty_callback
21
+ EM.run do
22
+ r1, _ = IO.pipe
23
+ r2, _ = IO.pipe
24
+
25
+ # Adding EM.watches
26
+ $conn1 = EM.watch(r1, SimpleClient)
27
+ $conn2 = EM.watch(r2, SimpleClient)
28
+
29
+ $conn1.notify_writable = true
30
+ $conn2.notify_writable = true
31
+
32
+ EM.stop
33
+ end
34
+ end
35
+ end