Skip to content

Commit 916c342

Browse files
committed
Merge pull request #434 from ruby-concurrency/better-java-ext-loading
Improved java extension loading.
2 parents e79b75b + 7a6cb23 commit 916c342

File tree

9 files changed

+74
-56
lines changed

9 files changed

+74
-56
lines changed

lib/concurrent/atomic/atomic_boolean.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module Concurrent
4848
# Explicitly sets the value to false.
4949
#
5050
# @return [Boolean] true is value has changed, otherwise false
51-
51+
5252
###################################################################
5353

5454
# @!macro [new] atomic_boolean_public_api
@@ -79,7 +79,7 @@ module Concurrent
7979
# @!visibility private
8080
# @!macro internal_implementation_note
8181
AtomicBooleanImplementation = case
82-
when Concurrent.on_jruby?
82+
when defined?(JavaAtomicBoolean)
8383
JavaAtomicBoolean
8484
when defined?(CAtomicBoolean)
8585
CAtomicBoolean

lib/concurrent/atomic/atomic_fixnum.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ module Concurrent
9696
# @!visibility private
9797
# @!macro internal_implementation_note
9898
AtomicFixnumImplementation = case
99-
when Concurrent.on_jruby?
99+
when defined?(JavaAtomicFixnum)
100100
JavaAtomicFixnum
101101
when defined?(CAtomicFixnum)
102102
CAtomicFixnum

lib/concurrent/atomic/semaphore.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ module Concurrent
9191
# @!visibility private
9292
# @!macro internal_implementation_note
9393
SemaphoreImplementation = case
94-
when Concurrent.on_jruby?
94+
when defined?(JavaSemaphore)
9595
JavaSemaphore
9696
else
9797
MutexSemaphore

lib/concurrent/map.rb

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
11
require 'thread'
22
require 'concurrent/constants'
3+
require 'concurrent/utility/native_extension_loader'
34

45
module Concurrent
56
# @!visibility private
67
module Collection
78

89
# @!visibility private
9-
MapImplementation = if defined?(RUBY_ENGINE)
10-
case RUBY_ENGINE
11-
when 'jruby'
12-
# noinspection RubyResolve
13-
JRubyMapBackend
14-
when 'ruby'
15-
require 'concurrent/collection/map/mri_map_backend'
16-
MriMapBackend
17-
when 'rbx'
18-
require 'concurrent/collection/map/atomic_reference_map_backend'
19-
AtomicReferenceMapBackend
20-
else
21-
warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation' if $VERBOSE
22-
require 'concurrent/collection/map/synchronized_map_backend'
23-
SynchronizedMapBackend
24-
end
25-
else
26-
MriMapBackend
27-
end
10+
MapImplementation = if Concurrent.java_extensions_loaded?
11+
# noinspection RubyResolve
12+
JRubyMapBackend
13+
elsif defined?(RUBY_ENGINE)
14+
case RUBY_ENGINE
15+
when 'ruby'
16+
require 'concurrent/collection/map/mri_map_backend'
17+
MriMapBackend
18+
when 'rbx'
19+
require 'concurrent/collection/map/atomic_reference_map_backend'
20+
AtomicReferenceMapBackend
21+
else
22+
warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation' if $VERBOSE
23+
require 'concurrent/collection/map/synchronized_map_backend'
24+
SynchronizedMapBackend
25+
end
26+
else
27+
MriMapBackend
28+
end
2829
end
2930

3031
# `Concurrent::Map` is a hash-like object and should have much better performance

lib/concurrent/synchronization/jruby_lockable_object.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Concurrent
22
module Synchronization
33

4-
if Concurrent.on_jruby?
4+
if Concurrent.on_jruby? && Concurrent.java_extensions_loaded?
55

66
# @!visibility private
77
# @!macro internal_implementation_note

lib/concurrent/synchronization/jruby_object.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Concurrent
22
module Synchronization
33

4-
if Concurrent.on_jruby?
4+
if Concurrent.on_jruby? && Concurrent.java_extensions_loaded?
55

66
# @!visibility private
77
# @!macro internal_implementation_note

lib/concurrent/synchronization/lockable_object.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module Synchronization
88
MriMonitorLockableObject
99
when Concurrent.on_cruby? && Concurrent.ruby_version(:>, 1, 9, 3)
1010
MriMutexLockableObject
11-
when Concurrent.on_jruby?
11+
when defined? JRubyLockableObject
1212
JRubyLockableObject
1313
when Concurrent.on_rbx?
1414
RbxLockableObject

lib/concurrent/synchronization/object.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Synchronization
66
ObjectImplementation = case
77
when Concurrent.on_cruby?
88
MriObject
9-
when Concurrent.on_jruby?
9+
when defined? JRubyObject
1010
JRubyObject
1111
when Concurrent.on_rbx?
1212
RbxObject

lib/concurrent/utility/native_extension_loader.rb

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,57 @@ module Utility
77
# @!visibility private
88
module NativeExtensionLoader
99

10-
@c_ext_loaded ||= false
11-
@java_ext_loaded ||= false
12-
13-
# @!visibility private
1410
def allow_c_extensions?
1511
Concurrent.on_cruby?
1612
end
1713

18-
if Concurrent.on_cruby? && !@c_ext_loaded
19-
tries = [
20-
lambda do
21-
require 'concurrent/extension'
22-
@c_ext_loaded = true
23-
end,
24-
lambda do
25-
# may be a Windows cross-compiled native gem
26-
require "concurrent/#{RUBY_VERSION[0..2]}/extension"
27-
@c_ext_loaded = true
28-
end]
29-
30-
tries.each do |try|
31-
begin
32-
try.call
33-
break
34-
rescue LoadError
35-
next
14+
def c_extensions_loaded?
15+
@c_extensions_loaded ||= false
16+
end
17+
18+
def java_extensions_loaded?
19+
@java_extensions_loaded ||= false
20+
end
21+
22+
def set_c_extensions_loaded
23+
@c_extensions_loaded = true
24+
end
25+
26+
def set_java_extensions_loaded
27+
@java_extensions_loaded = true
28+
end
29+
30+
def load_native_extensions
31+
if Concurrent.on_cruby? && !c_extensions_loaded?
32+
tries = [
33+
lambda do
34+
require 'concurrent/extension'
35+
set_c_extensions_loaded
36+
end,
37+
lambda do
38+
# may be a Windows cross-compiled native gem
39+
require "concurrent/#{RUBY_VERSION[0..2]}/extension"
40+
set_c_extensions_loaded
41+
end]
42+
43+
tries.each do |try|
44+
begin
45+
try.call
46+
break
47+
rescue LoadError
48+
next
49+
end
3650
end
3751
end
38-
end
3952

40-
if Concurrent.on_jruby? && !@java_ext_loaded
41-
begin
42-
require 'concurrent_ruby_ext'
43-
@java_ext_loaded = true
44-
rescue LoadError
45-
# move on with pure-Ruby implementations
53+
if Concurrent.on_jruby? && !java_extensions_loaded?
54+
begin
55+
require 'concurrent_ruby_ext'
56+
set_java_extensions_loaded
57+
rescue LoadError
58+
# move on with pure-Ruby implementations
59+
warn 'On JRuby but Java extensions failed to load.'
60+
end
4661
end
4762
end
4863
end
@@ -51,3 +66,5 @@ def allow_c_extensions?
5166
# @!visibility private
5267
extend Utility::NativeExtensionLoader
5368
end
69+
70+
Concurrent.load_native_extensions

0 commit comments

Comments
 (0)