eventmachine 1.0.9.1-java → 1.2.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +2 -2
- data/ext/cmain.cpp +77 -5
- data/ext/ed.cpp +112 -42
- data/ext/ed.h +27 -13
- data/ext/em.cpp +105 -163
- data/ext/em.h +10 -7
- data/ext/eventmachine.h +13 -1
- data/ext/extconf.rb +23 -14
- data/ext/fastfilereader/extconf.rb +1 -2
- data/ext/fastfilereader/rubymain.cpp +6 -6
- data/ext/project.h +9 -4
- data/ext/rubymain.cpp +155 -36
- data/ext/ssl.cpp +157 -13
- data/ext/ssl.h +7 -2
- data/lib/em/channel.rb +5 -0
- data/lib/em/completion.rb +2 -2
- data/lib/em/connection.rb +61 -3
- data/lib/em/iterator.rb +26 -5
- data/lib/em/pool.rb +1 -1
- data/lib/em/protocols/line_and_text.rb +1 -1
- data/lib/em/pure_ruby.rb +6 -1
- data/lib/em/queue.rb +16 -7
- data/lib/em/resolver.rb +46 -23
- data/lib/em/threaded_resource.rb +2 -2
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +59 -42
- data/lib/rubyeventmachine.jar +0 -0
- data/rakelib/package.rake +23 -1
- data/tests/dhparam.pem +13 -0
- data/tests/em_test_helper.rb +79 -0
- data/tests/test_basic.rb +17 -26
- data/tests/test_channel.rb +14 -1
- data/tests/test_connection_write.rb +2 -2
- data/tests/test_defer.rb +17 -0
- data/tests/test_epoll.rb +1 -1
- data/tests/test_fork.rb +75 -0
- data/tests/test_ipv4.rb +125 -0
- data/tests/test_ipv6.rb +131 -0
- data/tests/test_iterator.rb +18 -0
- data/tests/test_many_fds.rb +1 -1
- data/tests/test_queue.rb +14 -0
- data/tests/test_resolver.rb +23 -0
- data/tests/test_set_sock_opt.rb +2 -0
- data/tests/test_ssl_dhparam.rb +83 -0
- data/tests/test_ssl_ecdh_curve.rb +79 -0
- data/tests/test_ssl_extensions.rb +49 -0
- data/tests/test_ssl_methods.rb +19 -0
- data/tests/test_ssl_protocols.rb +246 -0
- data/tests/test_ssl_verify.rb +44 -0
- data/tests/test_system.rb +4 -0
- data/tests/test_unbind_reason.rb +5 -1
- metadata +101 -20
- data/.gitignore +0 -21
- data/.travis.yml +0 -22
- data/.yardopts +0 -7
- data/Gemfile +0 -2
- data/Rakefile +0 -20
- data/eventmachine.gemspec +0 -38
- data/rakelib/cpp.rake_example +0 -77
data/lib/em/pool.rb
CHANGED
data/lib/em/pure_ruby.rb
CHANGED
@@ -66,6 +66,11 @@ module EventMachine
|
|
66
66
|
def release_machine
|
67
67
|
end
|
68
68
|
|
69
|
+
|
70
|
+
def stopping?
|
71
|
+
return Reactor.instance.stop_scheduled
|
72
|
+
end
|
73
|
+
|
69
74
|
# @private
|
70
75
|
def stop
|
71
76
|
Reactor.instance.stop
|
@@ -273,7 +278,7 @@ module EventMachine
|
|
273
278
|
|
274
279
|
HeartbeatInterval = 2
|
275
280
|
|
276
|
-
attr_reader :current_loop_time
|
281
|
+
attr_reader :current_loop_time, :stop_scheduled
|
277
282
|
|
278
283
|
def initialize
|
279
284
|
initialize_for_run
|
data/lib/em/queue.rb
CHANGED
@@ -17,7 +17,8 @@ module EventMachine
|
|
17
17
|
#
|
18
18
|
class Queue
|
19
19
|
def initialize
|
20
|
-
@
|
20
|
+
@sink = []
|
21
|
+
@drain = []
|
21
22
|
@popq = []
|
22
23
|
end
|
23
24
|
|
@@ -29,10 +30,14 @@ module EventMachine
|
|
29
30
|
def pop(*a, &b)
|
30
31
|
cb = EM::Callback(*a, &b)
|
31
32
|
EM.schedule do
|
32
|
-
if @
|
33
|
+
if @drain.empty?
|
34
|
+
@drain = @sink
|
35
|
+
@sink = []
|
36
|
+
end
|
37
|
+
if @drain.empty?
|
33
38
|
@popq << cb
|
34
39
|
else
|
35
|
-
cb.call @
|
40
|
+
cb.call @drain.shift
|
36
41
|
end
|
37
42
|
end
|
38
43
|
nil # Always returns nil
|
@@ -43,8 +48,12 @@ module EventMachine
|
|
43
48
|
# next reactor tick.
|
44
49
|
def push(*items)
|
45
50
|
EM.schedule do
|
46
|
-
@
|
47
|
-
|
51
|
+
@sink.push(*items)
|
52
|
+
unless @popq.empty?
|
53
|
+
@drain = @sink
|
54
|
+
@sink = []
|
55
|
+
@popq.shift.call @drain.shift until @drain.empty? || @popq.empty?
|
56
|
+
end
|
48
57
|
end
|
49
58
|
end
|
50
59
|
alias :<< :push
|
@@ -52,13 +61,13 @@ module EventMachine
|
|
52
61
|
# @return [Boolean]
|
53
62
|
# @note This is a peek, it's not thread safe, and may only tend toward accuracy.
|
54
63
|
def empty?
|
55
|
-
@
|
64
|
+
@drain.empty? && @sink.empty?
|
56
65
|
end
|
57
66
|
|
58
67
|
# @return [Integer] Queue size
|
59
68
|
# @note This is a peek, it's not thread safe, and may only tend toward accuracy.
|
60
69
|
def size
|
61
|
-
@
|
70
|
+
@drain.size + @sink.size
|
62
71
|
end
|
63
72
|
|
64
73
|
# @return [Integer] Waiting size
|
data/lib/em/resolver.rb
CHANGED
@@ -2,30 +2,31 @@ module EventMachine
|
|
2
2
|
module DNS
|
3
3
|
class Resolver
|
4
4
|
|
5
|
+
def self.windows?
|
6
|
+
if RUBY_PLATFORM =~ /mswin32|cygwin|mingw|bccwin/
|
7
|
+
require 'win32/resolv'
|
8
|
+
true
|
9
|
+
else
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
HOSTS_FILE = windows? ? Win32::Resolv.get_hosts_path : '/etc/hosts'
|
15
|
+
|
16
|
+
@hosts = nil
|
17
|
+
@nameservers = nil
|
18
|
+
@socket = nil
|
19
|
+
|
5
20
|
def self.resolve(hostname)
|
6
21
|
Request.new(socket, hostname)
|
7
22
|
end
|
8
23
|
|
9
|
-
@socket = @nameservers = nil
|
10
|
-
|
11
24
|
def self.socket
|
12
|
-
if
|
25
|
+
if @socket && @socket.error?
|
13
26
|
@socket = Socket.open
|
14
|
-
|
15
|
-
@
|
16
|
-
IO.readlines('/etc/hosts').each do |line|
|
17
|
-
next if line =~ /^#/
|
18
|
-
addr, host = line.split(/\s+/)
|
19
|
-
|
20
|
-
if @hosts[host]
|
21
|
-
@hosts[host] << addr
|
22
|
-
else
|
23
|
-
@hosts[host] = [addr]
|
24
|
-
end
|
25
|
-
end
|
27
|
+
else
|
28
|
+
@socket ||= Socket.open
|
26
29
|
end
|
27
|
-
|
28
|
-
@socket
|
29
30
|
end
|
30
31
|
|
31
32
|
def self.nameservers=(ns)
|
@@ -33,15 +34,23 @@ module EventMachine
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def self.nameservers
|
36
|
-
if
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
return @nameservers if @nameservers
|
38
|
+
|
39
|
+
if windows?
|
40
|
+
_, ns = Win32::Resolv.get_resolv_info
|
41
|
+
return @nameservers = ns || []
|
42
|
+
end
|
43
|
+
|
44
|
+
@nameservers = []
|
45
|
+
IO.readlines('/etc/resolv.conf').each do |line|
|
46
|
+
if line =~ /^nameserver (.+)$/
|
47
|
+
@nameservers << $1.split(/\s+/).first
|
42
48
|
end
|
43
49
|
end
|
50
|
+
|
44
51
|
@nameservers
|
52
|
+
rescue
|
53
|
+
@nameservers = []
|
45
54
|
end
|
46
55
|
|
47
56
|
def self.nameserver
|
@@ -49,7 +58,21 @@ module EventMachine
|
|
49
58
|
end
|
50
59
|
|
51
60
|
def self.hosts
|
61
|
+
return @hosts if @hosts
|
62
|
+
|
63
|
+
@hosts = {}
|
64
|
+
IO.readlines(HOSTS_FILE).each do |line|
|
65
|
+
next if line =~ /^#/
|
66
|
+
addr, host = line.split(/\s+/)
|
67
|
+
|
68
|
+
next unless addr && host
|
69
|
+
@hosts[host] ||= []
|
70
|
+
@hosts[host] << addr
|
71
|
+
end
|
72
|
+
|
52
73
|
@hosts
|
74
|
+
rescue
|
75
|
+
@hosts = {}
|
53
76
|
end
|
54
77
|
end
|
55
78
|
|
data/lib/em/threaded_resource.rb
CHANGED
data/lib/em/version.rb
CHANGED
data/lib/eventmachine.rb
CHANGED
@@ -161,6 +161,7 @@ module EventMachine
|
|
161
161
|
# Clean up reactor state so a new reactor boots up in this child.
|
162
162
|
stop_event_loop
|
163
163
|
release_machine
|
164
|
+
cleanup_machine
|
164
165
|
@reactor_running = false
|
165
166
|
end
|
166
167
|
|
@@ -198,30 +199,8 @@ module EventMachine
|
|
198
199
|
@tails.pop.call
|
199
200
|
end
|
200
201
|
|
201
|
-
|
202
|
-
|
203
|
-
ensure
|
204
|
-
if @threadpool
|
205
|
-
@threadpool.each { |t| t.exit }
|
206
|
-
@threadpool.each do |t|
|
207
|
-
next unless t.alive?
|
208
|
-
begin
|
209
|
-
# Thread#kill! does not exist on 1.9 or rbx, and raises
|
210
|
-
# NotImplemented on jruby
|
211
|
-
t.kill!
|
212
|
-
rescue NoMethodError, NotImplementedError
|
213
|
-
t.kill
|
214
|
-
# XXX t.join here?
|
215
|
-
end
|
216
|
-
end
|
217
|
-
@threadqueue = nil
|
218
|
-
@resultqueue = nil
|
219
|
-
@threadpool = nil
|
220
|
-
@all_threads_spawned = false
|
221
|
-
end
|
222
|
-
|
223
|
-
@next_tick_queue = []
|
224
|
-
end
|
202
|
+
release_machine
|
203
|
+
cleanup_machine
|
225
204
|
@reactor_running = false
|
226
205
|
@reactor_thread = nil
|
227
206
|
end
|
@@ -266,13 +245,30 @@ module EventMachine
|
|
266
245
|
# Original patch by Aman Gupta.
|
267
246
|
#
|
268
247
|
Kernel.fork do
|
269
|
-
if
|
270
|
-
|
271
|
-
|
248
|
+
if reactor_running?
|
249
|
+
stop_event_loop
|
250
|
+
release_machine
|
251
|
+
cleanup_machine
|
272
252
|
@reactor_running = false
|
253
|
+
@reactor_thread = nil
|
273
254
|
end
|
274
|
-
|
255
|
+
run block
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# Clean up Ruby space following a release_machine
|
260
|
+
def self.cleanup_machine
|
261
|
+
if @threadpool && !@threadpool.empty?
|
262
|
+
# Tell the threads to stop
|
263
|
+
@threadpool.each { |t| t.exit }
|
264
|
+
# Join the threads or bump the stragglers one more time
|
265
|
+
@threadpool.each { |t| t.join 0.01 || t.exit }
|
275
266
|
end
|
267
|
+
@threadpool = nil
|
268
|
+
@threadqueue = nil
|
269
|
+
@resultqueue = nil
|
270
|
+
@all_threads_spawned = false
|
271
|
+
@next_tick_queue = []
|
276
272
|
end
|
277
273
|
|
278
274
|
# Adds a block to call as the reactor is shutting down.
|
@@ -997,11 +993,14 @@ module EventMachine
|
|
997
993
|
# EventMachine.defer is used for integrating blocking operations into EventMachine's control flow.
|
998
994
|
# The action of {.defer} is to take the block specified in the first parameter (the "operation")
|
999
995
|
# and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine.
|
1000
|
-
# When the operation completes, it will pass the result computed by the block (if any)
|
1001
|
-
#
|
1002
|
-
#
|
1003
|
-
#
|
1004
|
-
#
|
996
|
+
# When the operation completes, it will pass the result computed by the block (if any) back to the
|
997
|
+
# EventMachine reactor. Then, EventMachine calls the block specified in the second parameter to
|
998
|
+
# {.defer} (the "callback"), as part of its normal event handling loop. The result computed by the
|
999
|
+
# operation block is passed as a parameter to the callback. You may omit the callback parameter if
|
1000
|
+
# you don't need to execute any code after the operation completes. If the operation raises an
|
1001
|
+
# unhandled exception, the exception will be passed to the third parameter to {.defer} (the
|
1002
|
+
# "errback"), as part of its normal event handling loop. If no errback is provided, the exception
|
1003
|
+
# will be allowed to blow through to the main thread immediately.
|
1005
1004
|
#
|
1006
1005
|
# ## Caveats ##
|
1007
1006
|
#
|
@@ -1015,6 +1014,11 @@ module EventMachine
|
|
1015
1014
|
# the number of threads in its pool, so if you do this enough times, your subsequent deferred
|
1016
1015
|
# operations won't get a chance to run.
|
1017
1016
|
#
|
1017
|
+
# The threads within the EventMachine's thread pool have abort_on_exception set to true. As a result,
|
1018
|
+
# if an unhandled exception is raised by the deferred operation and an errback is not provided, it
|
1019
|
+
# will blow through to the main thread immediately. If the main thread is within an indiscriminate
|
1020
|
+
# rescue block at that time, the exception could be handled improperly by the main thread.
|
1021
|
+
#
|
1018
1022
|
# @example
|
1019
1023
|
#
|
1020
1024
|
# operation = proc {
|
@@ -1024,14 +1028,18 @@ module EventMachine
|
|
1024
1028
|
# callback = proc {|result|
|
1025
1029
|
# # do something with result here, such as send it back to a network client.
|
1026
1030
|
# }
|
1031
|
+
# errback = proc {|error|
|
1032
|
+
# # do something with error here, such as re-raising or logging.
|
1033
|
+
# }
|
1027
1034
|
#
|
1028
|
-
# EventMachine.defer(operation, callback)
|
1035
|
+
# EventMachine.defer(operation, callback, errback)
|
1029
1036
|
#
|
1030
1037
|
# @param [#call] op An operation you want to offload to EventMachine thread pool
|
1031
1038
|
# @param [#call] callback A callback that will be run on the event loop thread after `operation` finishes.
|
1039
|
+
# @param [#call] errback An errback that will be run on the event loop thread after `operation` raises an exception.
|
1032
1040
|
#
|
1033
1041
|
# @see EventMachine.threadpool_size
|
1034
|
-
def self.defer op = nil, callback = nil, &blk
|
1042
|
+
def self.defer op = nil, callback = nil, errback = nil, &blk
|
1035
1043
|
# OBSERVE that #next_tick hacks into this mechanism, so don't make any changes here
|
1036
1044
|
# without syncing there.
|
1037
1045
|
#
|
@@ -1048,7 +1056,7 @@ module EventMachine
|
|
1048
1056
|
spawn_threadpool
|
1049
1057
|
end
|
1050
1058
|
|
1051
|
-
@threadqueue << [op||blk,callback]
|
1059
|
+
@threadqueue << [op||blk,callback,errback]
|
1052
1060
|
end
|
1053
1061
|
|
1054
1062
|
|
@@ -1059,13 +1067,18 @@ module EventMachine
|
|
1059
1067
|
Thread.current.abort_on_exception = true
|
1060
1068
|
while true
|
1061
1069
|
begin
|
1062
|
-
op, cback = *@threadqueue.pop
|
1070
|
+
op, cback, eback = *@threadqueue.pop
|
1063
1071
|
rescue ThreadError
|
1064
1072
|
$stderr.puts $!.message
|
1065
1073
|
break # Ruby 2.0 may fail at Queue.pop
|
1066
1074
|
end
|
1067
|
-
|
1068
|
-
|
1075
|
+
begin
|
1076
|
+
result = op.call
|
1077
|
+
@resultqueue << [result, cback]
|
1078
|
+
rescue Exception => error
|
1079
|
+
raise error unless eback
|
1080
|
+
@resultqueue << [error, eback]
|
1081
|
+
end
|
1069
1082
|
EventMachine.signal_loopbreak
|
1070
1083
|
end
|
1071
1084
|
end
|
@@ -1477,9 +1490,13 @@ module EventMachine
|
|
1477
1490
|
rescue Errno::EBADF, IOError
|
1478
1491
|
end
|
1479
1492
|
end
|
1480
|
-
rescue
|
1481
|
-
|
1482
|
-
|
1493
|
+
rescue Exception => e
|
1494
|
+
if stopping?
|
1495
|
+
@wrapped_exception = $!
|
1496
|
+
stop
|
1497
|
+
else
|
1498
|
+
raise e
|
1499
|
+
end
|
1483
1500
|
end
|
1484
1501
|
elsif c = @acceptors.delete( conn_binding )
|
1485
1502
|
# no-op
|
Binary file
|
data/rakelib/package.rake
CHANGED
@@ -25,7 +25,7 @@ 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', '
|
28
|
+
ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
|
29
29
|
end
|
30
30
|
end
|
31
31
|
def hack_cross_compilation(ext)
|
@@ -96,3 +96,25 @@ def gem_cmd(action, name, *args)
|
|
96
96
|
end
|
97
97
|
|
98
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
|
data/tests/dhparam.pem
ADDED
@@ -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-----
|
data/tests/em_test_helper.rb
CHANGED
@@ -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
|
@@ -69,4 +124,28 @@ class Test::Unit::TestCase
|
|
69
124
|
$VERBOSE = backup
|
70
125
|
end
|
71
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
|
+
|
72
151
|
end
|