From 9caecc5b4f6aa6799c4336e070a3c9a7aad1550e Mon Sep 17 00:00:00 2001 From: Jerry D'Antonio Date: Tue, 9 Dec 2014 22:45:01 -0500 Subject: [PATCH] Builds two gems from one repo. Specs and docs need updated. --- Gemfile | 2 +- Rakefile | 46 ++++++++++++++++++------ concurrent-ruby-ext.gemspec | 30 ++++++++++++++++ concurrent-ruby.gemspec | 9 ++--- examples/atomic_example.rb | 2 +- examples/bench_atomic.rb | 3 +- examples/bench_atomic_1.rb | 6 +++- examples/benchmark_atomic_boolean.rb | 2 +- examples/benchmark_atomic_fixnum.rb | 2 +- lib/concurrent/atomic.rb | 3 +- lib/concurrent/atomic/atomic_boolean.rb | 3 +- lib/concurrent/atomic/atomic_fixnum.rb | 3 +- lib/concurrent/atomic_reference/jruby.rb | 1 - lib/concurrent/atomic_reference/ruby.rb | 10 ------ lib/concurrent/version.rb | 2 +- lib/extension_helper.rb | 42 ++++++++++++---------- 16 files changed, 106 insertions(+), 60 deletions(-) create mode 100644 concurrent-ruby-ext.gemspec diff --git a/Gemfile b/Gemfile index 848592d37..abfcd79c1 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gemspec +gemspec name: 'concurrent-ruby' group :development do gem 'rake', '~> 10.3.2' diff --git a/Rakefile b/Rakefile index 094554f72..76489bed0 100644 --- a/Rakefile +++ b/Rakefile @@ -1,12 +1,7 @@ -require 'bundler/gem_tasks' -require 'rake/extensiontask' -require 'rake/javaextensiontask' - -GEMSPEC = Gem::Specification.load('concurrent-ruby.gemspec') +CORE_GEMSPEC = Gem::Specification.load('concurrent-ruby.gemspec') +EXT_GEMSPEC = Gem::Specification.load('concurrent-ruby-ext.gemspec') EXTENSION_NAME = 'concurrent_ruby_ext' -Bundler::GemHelper.install_tasks - $:.push File.join(File.dirname(__FILE__), 'lib') require 'extension_helper' @@ -23,20 +18,22 @@ Dir.glob('tasks/**/*.rake').each do |rakefile| safe_load rakefile end -desc 'Run benchmarks' +#desc 'Run benchmarks' task :bench do exec 'ruby -Ilib -Iext examples/bench_atomic.rb' end if defined?(JRUBY_VERSION) + require 'rake/javaextensiontask' - Rake::JavaExtensionTask.new(EXTENSION_NAME, GEMSPEC) do |ext| + Rake::JavaExtensionTask.new(EXTENSION_NAME, CORE_GEMSPEC) do |ext| ext.ext_dir = 'ext' end elsif Concurrent.allow_c_extensions? + require 'rake/extensiontask' - Rake::ExtensionTask.new(EXTENSION_NAME, GEMSPEC) do |ext| + Rake::ExtensionTask.new(EXTENSION_NAME, EXT_GEMSPEC) do |ext| ext.ext_dir = "ext/#{EXTENSION_NAME}" ext.cross_compile = true ext.cross_platform = ['x86-mingw32', 'x64-mingw32'] @@ -61,7 +58,6 @@ elsif Concurrent.allow_c_extensions? else task :clean task :compile - task "compile:#{EXTENSION_NAME}" end Rake::Task[:clean].enhance do @@ -71,6 +67,7 @@ Rake::Task[:clean].enhance do rm_rf 'lib/2.0' rm_f Dir.glob('./lib/*.jar') rm_f Dir.glob('./**/*.bundle') + mkdir_p 'pkg' end begin @@ -85,3 +82,30 @@ begin rescue LoadError puts 'Error loading Rspec rake tasks, probably building the gem...' end + +namespace :build do + + build_deps = [:clean] + build_deps << :compile if defined?(JRUBY_VERSION) + + desc 'Build the concurrent-ruby gem' + task :core => build_deps do + sh "gem build #{CORE_GEMSPEC.name}.gemspec" + sh 'mv *.gem pkg/' + Rake::Task[:clean].execute + end + + if Concurrent.allow_c_extensions? + desc 'Build the concurrent-ruby-ext gem' + task :ext => [:clean, :compile] do + sh "gem build #{EXT_GEMSPEC.name}.gemspec" + sh 'mv *.gem pkg/' + Rake::Task[:clean].execute + end + else + task :ext + end +end + +desc 'Build all gems for this platform' +task :build => ['build:core', 'build:ext'] diff --git a/concurrent-ruby-ext.gemspec b/concurrent-ruby-ext.gemspec new file mode 100644 index 000000000..f09fb562b --- /dev/null +++ b/concurrent-ruby-ext.gemspec @@ -0,0 +1,30 @@ +Gem::Specification.new do |s| + s.name = 'concurrent-ruby-ext' + s.version = '0.1.0.pre1' + s.platform = Gem::Platform::RUBY + s.author = "Jerry D'Antonio" + s.email = 'jerry.dantonio@gmail.com' + s.homepage = 'http://www.concurrent-ruby.com' + s.summary = 'C extensions to optimize concurrent-ruby under MRI.' + s.license = 'MIT' + s.date = Time.now.strftime('%Y-%m-%d') + + s.description = <<-EOF + Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more. + Inspired by Erlang, Clojure, Go, JavaScript, actors, and classic concurrency patterns. + EOF + + s.files = Dir['ext/**/*.{h,c,cpp}'] + s.files += [ + 'lib/concurrent/atomic_reference/concurrent_update_error.rb', + 'lib/concurrent/atomic_reference/direct_update.rb', + 'lib/concurrent/atomic_reference/numeric_cas_wrapper.rb', + ] + s.extra_rdoc_files = Dir['README*', 'LICENSE*', 'CHANGELOG*'] + s.require_paths = ['lib'] + s.extensions = 'ext/concurrent_ruby_ext/extconf.rb' + + s.required_ruby_version = '>= 1.9.3' + + s.add_runtime_dependency 'concurrent-ruby', '~> 0.8.0.pre1' +end diff --git a/concurrent-ruby.gemspec b/concurrent-ruby.gemspec index 63f7142f3..7ffbe62b4 100644 --- a/concurrent-ruby.gemspec +++ b/concurrent-ruby.gemspec @@ -25,14 +25,9 @@ Gem::Specification.new do |s| if defined?(JRUBY_VERSION) s.files += Dir['lib/concurrent_ruby_ext.jar'] s.platform = 'java' - elsif ! ENV['BUILD_PURE_RUBY'] - s.extensions = 'ext/concurrent_ruby_ext/extconf.rb' - s.files += Dir['ext/**/*.{h,c,cpp}'] + else + s.add_runtime_dependency 'ref', '~> 1.0', '>= 1.0.5' end s.required_ruby_version = '>= 1.9.3' - - unless defined?(JRUBY_VERSION) - s.add_dependency 'ref', '~> 1.0.5' - end end diff --git a/examples/atomic_example.rb b/examples/atomic_example.rb index 5debe298f..0c97b2c24 100644 --- a/examples/atomic_example.rb +++ b/examples/atomic_example.rb @@ -1,4 +1,4 @@ -require 'concurrent' +require 'concurrent/atomic' my_atomic = Concurrent::Atomic.new(0) my_atomic.update {|v| v + 1} diff --git a/examples/bench_atomic.rb b/examples/bench_atomic.rb index f4b164eb0..a5701f643 100644 --- a/examples/bench_atomic.rb +++ b/examples/bench_atomic.rb @@ -1,7 +1,8 @@ require 'benchmark' require 'rbconfig' require 'thread' -require 'concurrent' +require 'concurrent/atomic' + Thread.abort_on_exception = true $go = false # for synchronizing parallel threads diff --git a/examples/bench_atomic_1.rb b/examples/bench_atomic_1.rb index c945e75ea..5f5585e49 100644 --- a/examples/bench_atomic_1.rb +++ b/examples/bench_atomic_1.rb @@ -6,7 +6,11 @@ require 'thread' require 'benchmark' -require 'concurrent' +begin + require 'concurrent-ext' +rescue LoadError + require 'concurrent' +end Thread.abort_on_exception = true diff --git a/examples/benchmark_atomic_boolean.rb b/examples/benchmark_atomic_boolean.rb index 6f6fda918..29e17069f 100755 --- a/examples/benchmark_atomic_boolean.rb +++ b/examples/benchmark_atomic_boolean.rb @@ -2,7 +2,7 @@ $:.push File.join(File.dirname(__FILE__), '../lib') -require 'concurrent' +require 'concurrent/atomics' require 'benchmark' require 'rbconfig' diff --git a/examples/benchmark_atomic_fixnum.rb b/examples/benchmark_atomic_fixnum.rb index f1c5c081f..f096c6d2a 100755 --- a/examples/benchmark_atomic_fixnum.rb +++ b/examples/benchmark_atomic_fixnum.rb @@ -2,7 +2,7 @@ $:.push File.join(File.dirname(__FILE__), '../lib') -require 'concurrent' +require 'concurrent/atomics' require 'benchmark' require 'rbconfig' diff --git a/lib/concurrent/atomic.rb b/lib/concurrent/atomic.rb index ab65c2bae..d18172b80 100644 --- a/lib/concurrent/atomic.rb +++ b/lib/concurrent/atomic.rb @@ -12,6 +12,7 @@ end ##################################################################### +require_relative '../extension_helper' require 'concurrent/atomic_reference/concurrent_update_error' require 'concurrent/atomic_reference/mutex_atomic' @@ -77,7 +78,7 @@ class Concurrent::Atomic < Concurrent::JavaAtomic class Concurrent::Atomic < Concurrent::RbxAtomic end -elsif Concurrent.allow_c_native_class?('CAtomic') +elsif defined?(CAtomic) # @!macro atomic_reference class Concurrent::Atomic < Concurrent::CAtomic diff --git a/lib/concurrent/atomic/atomic_boolean.rb b/lib/concurrent/atomic/atomic_boolean.rb index 2e88b2414..7bcdfe6e4 100644 --- a/lib/concurrent/atomic/atomic_boolean.rb +++ b/lib/concurrent/atomic/atomic_boolean.rb @@ -1,5 +1,4 @@ require_relative '../../extension_helper' -Concurrent.safe_require_c_extensions module Concurrent @@ -162,7 +161,7 @@ def make_false class AtomicBoolean < JavaAtomicBoolean end - elsif Concurrent.allow_c_native_class?('CAtomicBoolean') + elsif defined?(CAtomicBoolean) # @!macro atomic_boolean class CAtomicBoolean diff --git a/lib/concurrent/atomic/atomic_fixnum.rb b/lib/concurrent/atomic/atomic_fixnum.rb index 31863112f..87e474e8e 100644 --- a/lib/concurrent/atomic/atomic_fixnum.rb +++ b/lib/concurrent/atomic/atomic_fixnum.rb @@ -1,5 +1,4 @@ require_relative '../../extension_helper' -Concurrent.safe_require_c_extensions module Concurrent @@ -166,7 +165,7 @@ def compare_and_set(expect, update) class AtomicFixnum < JavaAtomicFixnum end - elsif Concurrent.allow_c_native_class?('CAtomicFixnum') + elsif defined?(CAtomicFixnum) # @!macro atomic_fixnum class CAtomicFixnum diff --git a/lib/concurrent/atomic_reference/jruby.rb b/lib/concurrent/atomic_reference/jruby.rb index 7533aec01..adb7e23e4 100644 --- a/lib/concurrent/atomic_reference/jruby.rb +++ b/lib/concurrent/atomic_reference/jruby.rb @@ -1,5 +1,4 @@ require_relative '../../extension_helper' -Concurrent.safe_require_java_extensions if defined?(Concurrent::JavaAtomic) require 'concurrent/atomic_reference/direct_update' diff --git a/lib/concurrent/atomic_reference/ruby.rb b/lib/concurrent/atomic_reference/ruby.rb index 437e1d3e4..b35d67bc0 100644 --- a/lib/concurrent/atomic_reference/ruby.rb +++ b/lib/concurrent/atomic_reference/ruby.rb @@ -1,14 +1,4 @@ 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' require 'concurrent/atomic_reference/numeric_cas_wrapper' diff --git a/lib/concurrent/version.rb b/lib/concurrent/version.rb index 867a4a65e..204f3ba24 100644 --- a/lib/concurrent/version.rb +++ b/lib/concurrent/version.rb @@ -1,3 +1,3 @@ module Concurrent - VERSION = '0.7.1' + VERSION = '0.8.0.pre1' end diff --git a/lib/extension_helper.rb b/lib/extension_helper.rb index a342b598f..8f53d3c9a 100644 --- a/lib/extension_helper.rb +++ b/lib/extension_helper.rb @@ -1,28 +1,32 @@ module Concurrent + + @@c_ext_loaded ||= false + @@java_ext_loaded ||= false # @!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.' + if allow_c_extensions? && !@@c_ext_loaded + begin + require 'concurrent_ruby_ext' + @@c_ext_loaded = true + rescue LoadError + # may be a Windows cross-compiled native gem + begin + require "#{RUBY_VERSION[0..2]}/concurrent_ruby_ext" + @@c_ext_loaded = true + rescue LoadError + warn 'Performance on MRI may be improved with the concurrent-ruby-ext gem. Please see http://concurrent-ruby.com' + end + end + elsif RUBY_PLATFORM == 'java' && !@@java_ext_loaded + begin + require 'concurrent_ruby_ext' + @@java_ext_loaded = true + rescue LoadError + #warn 'Attempted to load Java extensions on unsupported platform. Continuing with pure-Ruby.' + end end end