diff --git a/.travis.yml b/.travis.yml index 240f8f2e4..157d8a95a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ branches: - master matrix: allow_failures: + - rvm: rbx-2 - rvm: ruby-head - rvm: jruby-head - rvm: 1.9.3 diff --git a/Rakefile b/Rakefile index 8f76de7be..094554f72 100644 --- a/Rakefile +++ b/Rakefile @@ -34,7 +34,7 @@ if defined?(JRUBY_VERSION) ext.ext_dir = 'ext' end -elsif Concurrent.use_c_extensions? +elsif Concurrent.allow_c_extensions? Rake::ExtensionTask.new(EXTENSION_NAME, GEMSPEC) do |ext| ext.ext_dir = "ext/#{EXTENSION_NAME}" diff --git a/ext/concurrent_ruby_ext/extconf.rb b/ext/concurrent_ruby_ext/extconf.rb index 6ea60adf4..eb635c2f9 100644 --- a/ext/concurrent_ruby_ext/extconf.rb +++ b/ext/concurrent_ruby_ext/extconf.rb @@ -12,7 +12,7 @@ def create_dummy_makefile end end -if defined?(JRUBY_VERSION) || ! Concurrent.use_c_extensions? +if defined?(JRUBY_VERSION) || ! Concurrent.allow_c_extensions? create_dummy_makefile warn 'C optimizations are not supported on this version of Ruby.' else diff --git a/lib/concurrent/atomic.rb b/lib/concurrent/atomic.rb index cdd3980d2..93121f0c4 100644 --- a/lib/concurrent/atomic.rb +++ b/lib/concurrent/atomic.rb @@ -57,19 +57,16 @@ class Concurrent::Atomic < Concurrent::JavaAtomic end -elsif defined? Concurrent::CAtomic +elsif defined? Concurrent::RbxAtomic - # @!macro [attach] concurrent_update_error - # - # This exception may be thrown by methods that have detected concurrent - # modification of an object when such modification is not permissible. - class Concurrent::Atomic < Concurrent::CAtomic + # @!macro atomic_reference + class Concurrent::Atomic < Concurrent::RbxAtomic end -elsif defined? Concurrent::RbxAtomic +elsif Concurrent.allow_c_native_class?('CAtomic') # @!macro atomic_reference - class Concurrent::Atomic < Concurrent::RbxAtomic + class Concurrent::Atomic < Concurrent::CAtomic end else diff --git a/lib/concurrent/atomic/atomic_boolean.rb b/lib/concurrent/atomic/atomic_boolean.rb index 02e51432b..2e88b2414 100644 --- a/lib/concurrent/atomic/atomic_boolean.rb +++ b/lib/concurrent/atomic/atomic_boolean.rb @@ -1,3 +1,6 @@ +require_relative '../../extension_helper' +Concurrent.safe_require_c_extensions + module Concurrent # @!macro [attach] atomic_boolean @@ -159,7 +162,7 @@ def make_false class AtomicBoolean < JavaAtomicBoolean end - elsif defined? Concurrent::CAtomicBoolean + elsif Concurrent.allow_c_native_class?('CAtomicBoolean') # @!macro atomic_boolean class CAtomicBoolean diff --git a/lib/concurrent/atomic/atomic_fixnum.rb b/lib/concurrent/atomic/atomic_fixnum.rb index 3049862bd..a1a2357a4 100644 --- a/lib/concurrent/atomic/atomic_fixnum.rb +++ b/lib/concurrent/atomic/atomic_fixnum.rb @@ -1,3 +1,6 @@ +require_relative '../../extension_helper' +Concurrent.safe_require_c_extensions + module Concurrent # @!macro [attach] atomic_fixnum @@ -163,7 +166,7 @@ def compare_and_set(expect, update) class AtomicFixnum < JavaAtomicFixnum end - elsif defined? Concurrent::CAtomicFixnum + elsif Concurrent.allow_c_native_class?('CAtomicFixnum') # @!macro atomic_fixnum class CAtomicFixnum diff --git a/lib/concurrent/atomic_reference/jruby.rb b/lib/concurrent/atomic_reference/jruby.rb index 2958a4640..7533aec01 100644 --- a/lib/concurrent/atomic_reference/jruby.rb +++ b/lib/concurrent/atomic_reference/jruby.rb @@ -1,10 +1,14 @@ -require 'concurrent_ruby_ext' -require 'concurrent/atomic_reference/direct_update' +require_relative '../../extension_helper' +Concurrent.safe_require_java_extensions -module Concurrent +if defined?(Concurrent::JavaAtomic) + require 'concurrent/atomic_reference/direct_update' - # @!macro atomic_reference - class JavaAtomic - include Concurrent::AtomicDirectUpdate + module Concurrent + + # @!macro atomic_reference + class JavaAtomic + include Concurrent::AtomicDirectUpdate + end end end diff --git a/lib/concurrent/atomic_reference/ruby.rb b/lib/concurrent/atomic_reference/ruby.rb index 20d15526f..437e1d3e4 100644 --- a/lib/concurrent/atomic_reference/ruby.rb +++ b/lib/concurrent/atomic_reference/ruby.rb @@ -1,8 +1,12 @@ -begin - require 'concurrent_ruby_ext' -rescue LoadError - # may be a Windows cross-compiled native gem - require "#{RUBY_VERSION[0..2]}/concurrent_ruby_ext" +require_relative '../../extension_helper' + +if Concurrent.allow_c_extensions? + begin + require 'concurrent_ruby_ext' + rescue LoadError + # may be a Windows cross-compiled native gem + require "#{RUBY_VERSION[0..2]}/concurrent_ruby_ext" + end end require 'concurrent/atomic_reference/direct_update' @@ -14,19 +18,19 @@ module Concurrent class CAtomic include Concurrent::AtomicDirectUpdate include Concurrent::AtomicNumericCompareAndSetWrapper - + # @!method initialize # @!macro atomic_reference_method_initialize - + # @!method get # @!macro atomic_reference_method_get - + # @!method set # @!macro atomic_reference_method_set - + # @!method get_and_set # @!macro atomic_reference_method_get_and_set - + # @!method _compare_and_set # @!macro atomic_reference_method_compare_and_set end diff --git a/lib/concurrent/version.rb b/lib/concurrent/version.rb index 60bef231a..505470fda 100644 --- a/lib/concurrent/version.rb +++ b/lib/concurrent/version.rb @@ -1,3 +1,3 @@ module Concurrent - VERSION = '0.7.0.rc2' + VERSION = '0.7.0.rc3' end diff --git a/lib/extension_helper.rb b/lib/extension_helper.rb index 4b0ffa7ac..a342b598f 100644 --- a/lib/extension_helper.rb +++ b/lib/extension_helper.rb @@ -1,9 +1,28 @@ -require 'rbconfig' - module Concurrent - def self.use_c_extensions? - host_os = RbConfig::CONFIG['host_os'] - ruby_name = RbConfig::CONFIG['ruby_install_name'] - (ruby_name =~ /^ruby$/i || host_os =~ /mswin32/i || host_os =~ /mingw32/i) + + # @!visibility private + def self.allow_c_extensions? + defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' + end + + # @!visibility private + def self.allow_c_native_class?(clazz) + allow_c_extensions? && Concurrent.const_defined?(clazz) + rescue + false + end + + # @!visibility private + def self.safe_require_c_extensions + require 'concurrent_ruby_ext' if allow_c_extensions? + rescue LoadError + #warn 'Attempted to load C extensions on unsupported platform. Continuing with pure-Ruby.' + end + + # @!visibility private + def self.safe_require_java_extensions + require 'concurrent_ruby_ext' if RUBY_PLATFORM == 'java' + rescue LoadError + #warn 'Attempted to load Java extensions on unsupported platform. Continuing with pure-Ruby.' end end diff --git a/spec/concurrent/atomic/atomic_boolean_spec.rb b/spec/concurrent/atomic/atomic_boolean_spec.rb index 242d04f86..573a97815 100644 --- a/spec/concurrent/atomic/atomic_boolean_spec.rb +++ b/spec/concurrent/atomic/atomic_boolean_spec.rb @@ -158,7 +158,7 @@ module Concurrent end end - if RUBY_PLATFORM == 'java' + if TestHelpers.jruby? describe JavaAtomicBoolean do it_should_behave_like :atomic_boolean @@ -166,14 +166,20 @@ module Concurrent end describe AtomicBoolean do - if defined? Concurrent::CAtomicBoolean - it 'inherits from CAtomicBoolean' do - expect(AtomicBoolean.ancestors).to include(CAtomicBoolean) + if RUBY_ENGINE != 'ruby' + it 'does not load the C extension' do + expect(defined?(Concurrent::CAtomicBoolean)).to be_falsey end - elsif RUBY_PLATFORM == 'java' + end + + if TestHelpers.jruby? it 'inherits from JavaAtomicBoolean' do expect(AtomicBoolean.ancestors).to include(JavaAtomicBoolean) end + elsif defined? Concurrent::CAtomicBoolean + it 'inherits from CAtomicBoolean' do + expect(AtomicBoolean.ancestors).to include(CAtomicBoolean) + end else it 'inherits from MutexAtomicBoolean' do expect(AtomicBoolean.ancestors).to include(MutexAtomicBoolean) diff --git a/spec/concurrent/atomic/atomic_fixnum_spec.rb b/spec/concurrent/atomic/atomic_fixnum_spec.rb index 51402046e..ae4e7e832 100644 --- a/spec/concurrent/atomic/atomic_fixnum_spec.rb +++ b/spec/concurrent/atomic/atomic_fixnum_spec.rb @@ -172,7 +172,7 @@ module Concurrent end end - if RUBY_PLATFORM == 'java' + if TestHelpers.jruby? describe JavaAtomicFixnum do it_should_behave_like :atomic_fixnum @@ -180,14 +180,20 @@ module Concurrent end describe AtomicFixnum do - if defined? Concurrent::CAtomicFixnum - it 'inherits from CAtomicFixnum' do - expect(AtomicFixnum.ancestors).to include(CAtomicFixnum) + if RUBY_ENGINE != 'ruby' + it 'does not load the C extension' do + expect(defined?(Concurrent::CAtomicFixnum)).to be_falsey end - elsif RUBY_PLATFORM == 'java' + end + + if TestHelpers.jruby? it 'inherits from JavaAtomicFixnum' do expect(AtomicFixnum.ancestors).to include(JavaAtomicFixnum) end + elsif defined? Concurrent::CAtomicFixnum + it 'inherits from CAtomicFixnum' do + expect(AtomicFixnum.ancestors).to include(CAtomicFixnum) + end else it 'inherits from MutexAtomicFixnum' do expect(AtomicFixnum.ancestors).to include(MutexAtomicFixnum) diff --git a/spec/concurrent/atomic_spec.rb b/spec/concurrent/atomic_spec.rb index c98a49ecd..f7343a9b9 100644 --- a/spec/concurrent/atomic_spec.rb +++ b/spec/concurrent/atomic_spec.rb @@ -152,14 +152,14 @@ module Concurrent end describe Atomic do - if TestHelpers.use_c_extensions? - it 'inherits from CAtomic' do - expect(Atomic.ancestors).to include(CAtomic) - end - elsif TestHelpers.jruby? + if TestHelpers.jruby? it 'inherits from JavaAtomic' do expect(Atomic.ancestors).to include(JavaAtomic) end + elsif TestHelpers.use_c_extensions? + it 'inherits from CAtomic' do + expect(Atomic.ancestors).to include(CAtomic) + end elsif TestHelpers.rbx? it 'inherits from RbxAtomic' do expect(Atomic.ancestors).to include(RbxAtomic) diff --git a/spec/support/example_group_extensions.rb b/spec/support/example_group_extensions.rb index d27b2bd45..c99b64eb9 100644 --- a/spec/support/example_group_extensions.rb +++ b/spec/support/example_group_extensions.rb @@ -12,19 +12,19 @@ def delta(v1, v2) end def mri? - RbConfig::CONFIG['ruby_install_name']=~ /^ruby$/i + RUBY_ENGINE == 'ruby' end def jruby? - RbConfig::CONFIG['ruby_install_name']=~ /^jruby$/i + RUBY_ENGINE == 'jruby' end def rbx? - RbConfig::CONFIG['ruby_install_name']=~ /^rbx$/i + RUBY_ENGINE == 'rbx' end def use_c_extensions? - Concurrent.use_c_extensions? # from extension_helper.rb + Concurrent.allow_c_extensions? # from extension_helper.rb end def do_no_reset!