concurrent-ruby 1.0.5 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/CHANGELOG.md +65 -0
 - data/Gemfile +39 -0
 - data/{LICENSE.txt → LICENSE.md} +2 -0
 - data/README.md +207 -105
 - data/Rakefile +314 -0
 - data/ext/concurrent-ruby/ConcurrentRubyService.java +17 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +175 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +248 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +93 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +113 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +159 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +306 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +31 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +3863 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +203 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +342 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +3800 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +204 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +291 -0
 - data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +199 -0
 - data/lib/concurrent/agent.rb +7 -7
 - data/lib/concurrent/array.rb +59 -32
 - data/lib/concurrent/async.rb +4 -4
 - data/lib/concurrent/atom.rb +9 -9
 - data/lib/concurrent/atomic/atomic_boolean.rb +24 -20
 - data/lib/concurrent/atomic/atomic_fixnum.rb +27 -23
 - data/lib/concurrent/atomic/atomic_markable_reference.rb +164 -0
 - data/lib/concurrent/atomic/atomic_reference.rb +185 -32
 - data/lib/concurrent/atomic/count_down_latch.rb +6 -6
 - data/lib/concurrent/atomic/cyclic_barrier.rb +1 -1
 - data/lib/concurrent/atomic/event.rb +1 -1
 - data/lib/concurrent/atomic/java_count_down_latch.rb +9 -6
 - data/lib/concurrent/atomic/mutex_atomic_boolean.rb +2 -0
 - data/lib/concurrent/atomic/mutex_count_down_latch.rb +1 -0
 - data/lib/concurrent/atomic/read_write_lock.rb +2 -1
 - data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
 - data/lib/concurrent/atomic/semaphore.rb +8 -8
 - data/lib/concurrent/atomic/thread_local_var.rb +7 -7
 - data/lib/concurrent/atomic_reference/mutex_atomic.rb +3 -8
 - data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +1 -1
 - data/lib/concurrent/atomics.rb +0 -43
 - data/lib/concurrent/collection/lock_free_stack.rb +158 -0
 - data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +3 -3
 - data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +1 -2
 - data/lib/concurrent/collection/non_concurrent_priority_queue.rb +29 -29
 - data/lib/concurrent/concern/dereferenceable.rb +1 -1
 - data/lib/concurrent/concern/logging.rb +6 -1
 - data/lib/concurrent/concern/observable.rb +7 -7
 - data/lib/concurrent/concurrent_ruby.jar +0 -0
 - data/lib/concurrent/configuration.rb +1 -6
 - data/lib/concurrent/constants.rb +1 -1
 - data/lib/concurrent/dataflow.rb +2 -1
 - data/lib/concurrent/delay.rb +9 -7
 - data/lib/concurrent/exchanger.rb +21 -25
 - data/lib/concurrent/executor/abstract_executor_service.rb +2 -2
 - data/lib/concurrent/executor/cached_thread_pool.rb +1 -1
 - data/lib/concurrent/executor/executor_service.rb +15 -15
 - data/lib/concurrent/executor/fixed_thread_pool.rb +18 -18
 - data/lib/concurrent/executor/java_thread_pool_executor.rb +10 -7
 - data/lib/concurrent/executor/single_thread_executor.rb +2 -2
 - data/lib/concurrent/executor/thread_pool_executor.rb +6 -6
 - data/lib/concurrent/executor/timer_set.rb +1 -1
 - data/lib/concurrent/future.rb +4 -1
 - data/lib/concurrent/hash.rb +53 -30
 - data/lib/concurrent/ivar.rb +5 -6
 - data/lib/concurrent/map.rb +178 -81
 - data/lib/concurrent/maybe.rb +1 -1
 - data/lib/concurrent/mutable_struct.rb +15 -14
 - data/lib/concurrent/mvar.rb +2 -2
 - data/lib/concurrent/promise.rb +53 -21
 - data/lib/concurrent/promises.rb +1936 -0
 - data/lib/concurrent/re_include.rb +58 -0
 - data/lib/concurrent/set.rb +66 -0
 - data/lib/concurrent/settable_struct.rb +1 -0
 - data/lib/concurrent/synchronization/abstract_lockable_object.rb +5 -5
 - data/lib/concurrent/synchronization/abstract_struct.rb +6 -4
 - data/lib/concurrent/synchronization/lockable_object.rb +6 -6
 - data/lib/concurrent/synchronization/{mri_lockable_object.rb → mutex_lockable_object.rb} +19 -14
 - data/lib/concurrent/synchronization/object.rb +8 -4
 - data/lib/concurrent/synchronization/truffleruby_object.rb +46 -0
 - data/lib/concurrent/synchronization/volatile.rb +11 -9
 - data/lib/concurrent/synchronization.rb +4 -5
 - data/lib/concurrent/thread_safe/util/data_structures.rb +63 -0
 - data/lib/concurrent/thread_safe/util/striped64.rb +9 -4
 - data/lib/concurrent/timer_task.rb +5 -2
 - data/lib/concurrent/tuple.rb +1 -1
 - data/lib/concurrent/tvar.rb +2 -2
 - data/lib/concurrent/utility/193.rb +17 -0
 - data/lib/concurrent/utility/at_exit.rb +1 -1
 - data/lib/concurrent/utility/engine.rb +4 -4
 - data/lib/concurrent/utility/monotonic_time.rb +3 -3
 - data/lib/concurrent/utility/native_extension_loader.rb +31 -33
 - data/lib/concurrent/utility/processor_counter.rb +0 -2
 - data/lib/concurrent/version.rb +2 -2
 - data/lib/concurrent-ruby.rb +1 -0
 - data/lib/concurrent.rb +26 -20
 - metadata +33 -18
 - data/lib/concurrent/atomic_reference/concurrent_update_error.rb +0 -8
 - data/lib/concurrent/atomic_reference/direct_update.rb +0 -81
 - data/lib/concurrent/atomic_reference/jruby+truffle.rb +0 -2
 - data/lib/concurrent/atomic_reference/jruby.rb +0 -16
 - data/lib/concurrent/atomic_reference/rbx.rb +0 -22
 - data/lib/concurrent/atomic_reference/ruby.rb +0 -32
 - data/lib/concurrent/edge.rb +0 -26
 - data/lib/concurrent/lazy_register.rb +0 -81
 - data/lib/concurrent/synchronization/truffle_lockable_object.rb +0 -9
 - data/lib/concurrent/synchronization/truffle_object.rb +0 -31
 - data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +0 -30
 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,314 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rake
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'lib/concurrent/version'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'lib/concurrent/utility/engine'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'lib/concurrent/utility/193'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec')
         
     | 
| 
      
 8 
     | 
    
         
            +
            ext_gemspec  = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec')
         
     | 
| 
      
 9 
     | 
    
         
            +
            edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.gemspec')
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            require 'rake/javaextensiontask'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            JRUBY_JAR_PATH = '/usr/local/opt/rbenv/versions/jruby-9.1.17.0/lib/jruby.jar'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            class ConcurrentRubyJavaExtensionTask < Rake::JavaExtensionTask
         
     | 
| 
      
 16 
     | 
    
         
            +
              def java_classpath_arg(*args)
         
     | 
| 
      
 17 
     | 
    
         
            +
                jruby_cpath = nil
         
     | 
| 
      
 18 
     | 
    
         
            +
                if RUBY_PLATFORM =~ /java/
         
     | 
| 
      
 19 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 20 
     | 
    
         
            +
                    cpath       = Java::java.lang.System.getProperty('java.class.path').split(File::PATH_SEPARATOR)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    cpath       += Java::java.lang.System.getProperty('sun.boot.class.path').split(File::PATH_SEPARATOR)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    jruby_cpath = cpath.compact.join(File::PATH_SEPARATOR)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
                unless jruby_cpath
         
     | 
| 
      
 27 
     | 
    
         
            +
                  jruby_cpath = JRUBY_JAR_PATH
         
     | 
| 
      
 28 
     | 
    
         
            +
                  raise "#{jruby_cpath} does not exist" unless File.exist? jruby_cpath
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
                jruby_cpath += File::PATH_SEPARATOR + args.join(File::PATH_SEPARATOR) unless args.empty?
         
     | 
| 
      
 31 
     | 
    
         
            +
                jruby_cpath ? "-cp \"#{jruby_cpath}\"" : ""
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            ConcurrentRubyJavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext|
         
     | 
| 
      
 36 
     | 
    
         
            +
              ext.ext_dir = 'ext/concurrent-ruby'
         
     | 
| 
      
 37 
     | 
    
         
            +
              ext.lib_dir = 'lib/concurrent'
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            unless Concurrent.on_jruby?
         
     | 
| 
      
 41 
     | 
    
         
            +
              require 'rake/extensiontask'
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext|
         
     | 
| 
      
 44 
     | 
    
         
            +
                ext.ext_dir        = 'ext/concurrent-ruby-ext'
         
     | 
| 
      
 45 
     | 
    
         
            +
                ext.lib_dir        = 'lib/concurrent'
         
     | 
| 
      
 46 
     | 
    
         
            +
                ext.source_pattern = '*.{c,h}'
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                ext.cross_compile  = true
         
     | 
| 
      
 49 
     | 
    
         
            +
                ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            require 'rake_compiler_dock'
         
     | 
| 
      
 54 
     | 
    
         
            +
            namespace :repackage do
         
     | 
| 
      
 55 
     | 
    
         
            +
              desc '* with Windows fat distributions'
         
     | 
| 
      
 56 
     | 
    
         
            +
              task :all do
         
     | 
| 
      
 57 
     | 
    
         
            +
                Dir.chdir(__dir__) do
         
     | 
| 
      
 58 
     | 
    
         
            +
                  sh 'bundle package'
         
     | 
| 
      
 59 
     | 
    
         
            +
                  # needed only if the jar is built outside of docker
         
     | 
| 
      
 60 
     | 
    
         
            +
                  Rake::Task['lib/concurrent/concurrent_ruby.jar'].invoke
         
     | 
| 
      
 61 
     | 
    
         
            +
                  RakeCompilerDock.exec 'support/cross_building.sh'
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
            end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 67 
     | 
    
         
            +
            require 'rubygems/package_task'
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            Gem::PackageTask.new(core_gemspec) {} if core_gemspec
         
     | 
| 
      
 70 
     | 
    
         
            +
            Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && !Concurrent.on_jruby?
         
     | 
| 
      
 71 
     | 
    
         
            +
            Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            CLEAN.include('lib/concurrent/2.*', 'lib/concurrent/*.jar')
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            begin
         
     | 
| 
      
 76 
     | 
    
         
            +
              require 'rspec'
         
     | 
| 
      
 77 
     | 
    
         
            +
              require 'rspec/core/rake_task'
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              RSpec::Core::RakeTask.new(:spec)
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              options = %w[ --color
         
     | 
| 
      
 82 
     | 
    
         
            +
                            --backtrace
         
     | 
| 
      
 83 
     | 
    
         
            +
                            --seed 1
         
     | 
| 
      
 84 
     | 
    
         
            +
                            --format documentation
         
     | 
| 
      
 85 
     | 
    
         
            +
                            --tag ~notravis ]
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              namespace :spec do
         
     | 
| 
      
 88 
     | 
    
         
            +
                desc '* Configured for ci'
         
     | 
| 
      
 89 
     | 
    
         
            +
                RSpec::Core::RakeTask.new(:ci) do |t|
         
     | 
| 
      
 90 
     | 
    
         
            +
                  t.rspec_opts = [*options].join(' ')
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                desc '* test packaged and installed gems instead of local files'
         
     | 
| 
      
 94 
     | 
    
         
            +
                task :installed do
         
     | 
| 
      
 95 
     | 
    
         
            +
                  Dir.chdir(__dir__) do
         
     | 
| 
      
 96 
     | 
    
         
            +
                    sh "gem install pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
         
     | 
| 
      
 97 
     | 
    
         
            +
                    sh "gem install pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if Concurrent.on_cruby?
         
     | 
| 
      
 98 
     | 
    
         
            +
                    sh "gem install pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem"
         
     | 
| 
      
 99 
     | 
    
         
            +
                    ENV['NO_PATH'] = 'true'
         
     | 
| 
      
 100 
     | 
    
         
            +
                    sh 'bundle update'
         
     | 
| 
      
 101 
     | 
    
         
            +
                    sh 'bundle exec rake spec:ci'
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
                end
         
     | 
| 
      
 104 
     | 
    
         
            +
              end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
              desc 'executed in CI'
         
     | 
| 
      
 107 
     | 
    
         
            +
              task :ci => [:compile, 'spec:ci']
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
              task :default => [:clobber, :compile, :spec]
         
     | 
| 
      
 110 
     | 
    
         
            +
            rescue LoadError => e
         
     | 
| 
      
 111 
     | 
    
         
            +
              puts 'RSpec is not installed, skipping test task definitions: ' + e.message
         
     | 
| 
      
 112 
     | 
    
         
            +
            end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            current_yard_version_name = Concurrent::VERSION.split('.')[0..2].join('.')
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            begin
         
     | 
| 
      
 117 
     | 
    
         
            +
              require 'yard'
         
     | 
| 
      
 118 
     | 
    
         
            +
              require 'md_ruby_eval'
         
     | 
| 
      
 119 
     | 
    
         
            +
              require_relative 'support/yard_full_types'
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
              common_yard_options = ['--no-yardopts',
         
     | 
| 
      
 122 
     | 
    
         
            +
                                     '--no-document',
         
     | 
| 
      
 123 
     | 
    
         
            +
                                     '--no-private',
         
     | 
| 
      
 124 
     | 
    
         
            +
                                     '--embed-mixins',
         
     | 
| 
      
 125 
     | 
    
         
            +
                                     '--markup', 'markdown',
         
     | 
| 
      
 126 
     | 
    
         
            +
                                     '--title', 'Concurrent Ruby',
         
     | 
| 
      
 127 
     | 
    
         
            +
                                     '--template', 'default',
         
     | 
| 
      
 128 
     | 
    
         
            +
                                     '--template-path', 'yard-template',
         
     | 
| 
      
 129 
     | 
    
         
            +
                                     '--default-return', 'undocumented']
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
              desc 'Generate YARD Documentation (signpost, master)'
         
     | 
| 
      
 132 
     | 
    
         
            +
              task :yard => ['yard:signpost', 'yard:master']
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
              namespace :yard do
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                desc '* eval markdown files'
         
     | 
| 
      
 137 
     | 
    
         
            +
                task :eval_md do
         
     | 
| 
      
 138 
     | 
    
         
            +
                  Dir.chdir File.join(__dir__, 'docs-source') do
         
     | 
| 
      
 139 
     | 
    
         
            +
                    sh 'bundle exec md-ruby-eval --auto'
         
     | 
| 
      
 140 
     | 
    
         
            +
                  end
         
     | 
| 
      
 141 
     | 
    
         
            +
                end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                task :update_readme do
         
     | 
| 
      
 144 
     | 
    
         
            +
                  Dir.chdir __dir__ do
         
     | 
| 
      
 145 
     | 
    
         
            +
                    content = File.read(File.join('README.md')).
         
     | 
| 
      
 146 
     | 
    
         
            +
                        gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_|
         
     | 
| 
      
 147 
     | 
    
         
            +
                      case $1
         
     | 
| 
      
 148 
     | 
    
         
            +
                      when 'LockFreeLinkedSet'
         
     | 
| 
      
 149 
     | 
    
         
            +
                        "{Concurrent::Edge::#{$1} #{$1}}"
         
     | 
| 
      
 150 
     | 
    
         
            +
                      when '.dataflow'
         
     | 
| 
      
 151 
     | 
    
         
            +
                        '{Concurrent.dataflow Concurrent.dataflow}'
         
     | 
| 
      
 152 
     | 
    
         
            +
                      when 'thread pool'
         
     | 
| 
      
 153 
     | 
    
         
            +
                        '{file:thread_pools.md thread pool}'
         
     | 
| 
      
 154 
     | 
    
         
            +
                      else
         
     | 
| 
      
 155 
     | 
    
         
            +
                        "{Concurrent::#{$1} #{$1}}"
         
     | 
| 
      
 156 
     | 
    
         
            +
                      end
         
     | 
| 
      
 157 
     | 
    
         
            +
                    end
         
     | 
| 
      
 158 
     | 
    
         
            +
                    FileUtils.mkpath 'tmp'
         
     | 
| 
      
 159 
     | 
    
         
            +
                    File.write 'tmp/README.md', content
         
     | 
| 
      
 160 
     | 
    
         
            +
                  end
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                define_yard_task = -> name do
         
     | 
| 
      
 164 
     | 
    
         
            +
                  desc "* of #{name} into subdir #{name}"
         
     | 
| 
      
 165 
     | 
    
         
            +
                  YARD::Rake::YardocTask.new(name) do |yard|
         
     | 
| 
      
 166 
     | 
    
         
            +
                    yard.options.push(
         
     | 
| 
      
 167 
     | 
    
         
            +
                        '--output-dir', "docs/#{name}",
         
     | 
| 
      
 168 
     | 
    
         
            +
                        '--main', 'tmp/README.md',
         
     | 
| 
      
 169 
     | 
    
         
            +
                        *common_yard_options)
         
     | 
| 
      
 170 
     | 
    
         
            +
                    yard.files = ['./lib/**/*.rb',
         
     | 
| 
      
 171 
     | 
    
         
            +
                                  './lib-edge/**/*.rb',
         
     | 
| 
      
 172 
     | 
    
         
            +
                                  './ext/concurrent_ruby_ext/**/*.c',
         
     | 
| 
      
 173 
     | 
    
         
            +
                                  '-',
         
     | 
| 
      
 174 
     | 
    
         
            +
                                  'docs-source/thread_pools.md',
         
     | 
| 
      
 175 
     | 
    
         
            +
                                  'docs-source/promises.out.md',
         
     | 
| 
      
 176 
     | 
    
         
            +
                                  'LICENSE.md',
         
     | 
| 
      
 177 
     | 
    
         
            +
                                  'CHANGELOG.md']
         
     | 
| 
      
 178 
     | 
    
         
            +
                  end
         
     | 
| 
      
 179 
     | 
    
         
            +
                  Rake::Task[name].prerequisites.push 'yard:eval_md', 'yard:update_readme'
         
     | 
| 
      
 180 
     | 
    
         
            +
                end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                define_yard_task.call current_yard_version_name
         
     | 
| 
      
 183 
     | 
    
         
            +
                define_yard_task.call 'master'
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                desc "* signpost for versions"
         
     | 
| 
      
 186 
     | 
    
         
            +
                YARD::Rake::YardocTask.new(:signpost) do |yard|
         
     | 
| 
      
 187 
     | 
    
         
            +
                  yard.options.push(
         
     | 
| 
      
 188 
     | 
    
         
            +
                      '--output-dir', 'docs',
         
     | 
| 
      
 189 
     | 
    
         
            +
                      '--main', 'docs-source/signpost.md',
         
     | 
| 
      
 190 
     | 
    
         
            +
                      *common_yard_options)
         
     | 
| 
      
 191 
     | 
    
         
            +
                  yard.files = ['no-lib']
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                define_uptodate_task = -> name do
         
     | 
| 
      
 195 
     | 
    
         
            +
                  namespace name do
         
     | 
| 
      
 196 
     | 
    
         
            +
                    desc "** ensure that #{name} generated documentation is matching the source code"
         
     | 
| 
      
 197 
     | 
    
         
            +
                    task :uptodate do
         
     | 
| 
      
 198 
     | 
    
         
            +
                      Dir.chdir(__dir__) do
         
     | 
| 
      
 199 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 200 
     | 
    
         
            +
                          FileUtils.cp_r 'docs', 'docs-copy', verbose: true
         
     | 
| 
      
 201 
     | 
    
         
            +
                          Rake::Task["yard:#{name}"].invoke
         
     | 
| 
      
 202 
     | 
    
         
            +
                          sh 'diff -r docs/ docs-copy/'
         
     | 
| 
      
 203 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 204 
     | 
    
         
            +
                          FileUtils.rm_rf 'docs-copy', verbose: true
         
     | 
| 
      
 205 
     | 
    
         
            +
                        end
         
     | 
| 
      
 206 
     | 
    
         
            +
                      end
         
     | 
| 
      
 207 
     | 
    
         
            +
                    end
         
     | 
| 
      
 208 
     | 
    
         
            +
                  end
         
     | 
| 
      
 209 
     | 
    
         
            +
                end
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
                define_uptodate_task.call current_yard_version_name
         
     | 
| 
      
 212 
     | 
    
         
            +
                define_uptodate_task.call 'master'
         
     | 
| 
      
 213 
     | 
    
         
            +
              end
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
            rescue LoadError => e
         
     | 
| 
      
 216 
     | 
    
         
            +
              puts 'YARD is not installed, skipping documentation task definitions: ' + e.message
         
     | 
| 
      
 217 
     | 
    
         
            +
            end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
            desc 'build, test, and publish the gem'
         
     | 
| 
      
 220 
     | 
    
         
            +
            task :release => ['release:checks', 'release:build', 'release:test', 'release:publish']
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
            namespace :release do
         
     | 
| 
      
 223 
     | 
    
         
            +
              # Depends on environment of @pitr-ch
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
              mri_version   = '2.5.1'
         
     | 
| 
      
 226 
     | 
    
         
            +
              jruby_version = 'jruby-9.1.17.1'
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
              task :checks => "yard:#{current_yard_version_name}:uptodate" do
         
     | 
| 
      
 229 
     | 
    
         
            +
                Dir.chdir(__dir__) do
         
     | 
| 
      
 230 
     | 
    
         
            +
                  sh 'test -z "$(git status --porcelain)"' do |ok, res|
         
     | 
| 
      
 231 
     | 
    
         
            +
                    unless ok
         
     | 
| 
      
 232 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 233 
     | 
    
         
            +
                        STDOUT.puts 'Command failed. Continue? (y/n)'
         
     | 
| 
      
 234 
     | 
    
         
            +
                        input = STDIN.gets.strip.downcase
         
     | 
| 
      
 235 
     | 
    
         
            +
                      end until %w(y n).include?(input)
         
     | 
| 
      
 236 
     | 
    
         
            +
                      exit 1 if input == 'n'
         
     | 
| 
      
 237 
     | 
    
         
            +
                    end
         
     | 
| 
      
 238 
     | 
    
         
            +
                  end
         
     | 
| 
      
 239 
     | 
    
         
            +
                  sh 'git fetch'
         
     | 
| 
      
 240 
     | 
    
         
            +
                  sh 'test $(git show-ref --verify --hash refs/heads/master) = ' +
         
     | 
| 
      
 241 
     | 
    
         
            +
                         '$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res|
         
     | 
| 
      
 242 
     | 
    
         
            +
                    unless ok
         
     | 
| 
      
 243 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 244 
     | 
    
         
            +
                        STDOUT.puts 'Command failed. Continue? (y/n)'
         
     | 
| 
      
 245 
     | 
    
         
            +
                        input = STDIN.gets.strip.downcase
         
     | 
| 
      
 246 
     | 
    
         
            +
                      end until %w(y n).include?(input)
         
     | 
| 
      
 247 
     | 
    
         
            +
                      exit 1 if input == 'n'
         
     | 
| 
      
 248 
     | 
    
         
            +
                    end
         
     | 
| 
      
 249 
     | 
    
         
            +
                  end
         
     | 
| 
      
 250 
     | 
    
         
            +
                end
         
     | 
| 
      
 251 
     | 
    
         
            +
              end
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
      
 253 
     | 
    
         
            +
              desc '* build all *.gem files necessary for release'
         
     | 
| 
      
 254 
     | 
    
         
            +
              task :build => 'repackage:all'
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
              desc '* test actual installed gems instead of cloned repository on MRI and JRuby'
         
     | 
| 
      
 257 
     | 
    
         
            +
              task :test do
         
     | 
| 
      
 258 
     | 
    
         
            +
                Dir.chdir(__dir__) do
         
     | 
| 
      
 259 
     | 
    
         
            +
                  old = ENV['RBENV_VERSION']
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                  ENV['RBENV_VERSION'] = mri_version
         
     | 
| 
      
 262 
     | 
    
         
            +
                  sh 'rbenv version'
         
     | 
| 
      
 263 
     | 
    
         
            +
                  sh 'bundle exec rake spec:installed'
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
                  ENV['RBENV_VERSION'] = jruby_version
         
     | 
| 
      
 266 
     | 
    
         
            +
                  sh 'rbenv version'
         
     | 
| 
      
 267 
     | 
    
         
            +
                  sh 'bundle exec rake spec:installed'
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
                  puts 'Windows build is untested'
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
                  ENV['RBENV_VERSION'] = old
         
     | 
| 
      
 272 
     | 
    
         
            +
                end
         
     | 
| 
      
 273 
     | 
    
         
            +
              end
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
              desc '* do all nested steps'
         
     | 
| 
      
 276 
     | 
    
         
            +
              task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps']
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
              namespace :publish do
         
     | 
| 
      
 279 
     | 
    
         
            +
                task :ask do
         
     | 
| 
      
 280 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 281 
     | 
    
         
            +
                    STDOUT.puts 'Do you want to publish? (y/n)'
         
     | 
| 
      
 282 
     | 
    
         
            +
                    input = STDIN.gets.strip.downcase
         
     | 
| 
      
 283 
     | 
    
         
            +
                  end until %w(y n).include?(input)
         
     | 
| 
      
 284 
     | 
    
         
            +
                  exit 1 if input == 'n'
         
     | 
| 
      
 285 
     | 
    
         
            +
                end
         
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
      
 287 
     | 
    
         
            +
                desc '** tag HEAD with current version and push to github'
         
     | 
| 
      
 288 
     | 
    
         
            +
                task :tag do
         
     | 
| 
      
 289 
     | 
    
         
            +
                  Dir.chdir(__dir__) do
         
     | 
| 
      
 290 
     | 
    
         
            +
                    sh "git tag v#{Concurrent::VERSION}"
         
     | 
| 
      
 291 
     | 
    
         
            +
                    sh "git tag edge-v#{Concurrent::EDGE_VERSION}"
         
     | 
| 
      
 292 
     | 
    
         
            +
                    sh "git push origin v#{Concurrent::VERSION} edge-v#{Concurrent::EDGE_VERSION}"
         
     | 
| 
      
 293 
     | 
    
         
            +
                  end
         
     | 
| 
      
 294 
     | 
    
         
            +
                end
         
     | 
| 
      
 295 
     | 
    
         
            +
             
     | 
| 
      
 296 
     | 
    
         
            +
                desc '** push all *.gem files to rubygems'
         
     | 
| 
      
 297 
     | 
    
         
            +
                task :rubygems do
         
     | 
| 
      
 298 
     | 
    
         
            +
                  Dir.chdir(__dir__) do
         
     | 
| 
      
 299 
     | 
    
         
            +
                    sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
         
     | 
| 
      
 300 
     | 
    
         
            +
                    sh "gem push pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem"
         
     | 
| 
      
 301 
     | 
    
         
            +
                    sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem"
         
     | 
| 
      
 302 
     | 
    
         
            +
                    sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem"
         
     | 
| 
      
 303 
     | 
    
         
            +
                    sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem"
         
     | 
| 
      
 304 
     | 
    
         
            +
                  end
         
     | 
| 
      
 305 
     | 
    
         
            +
                end
         
     | 
| 
      
 306 
     | 
    
         
            +
             
     | 
| 
      
 307 
     | 
    
         
            +
                desc '** print post release steps'
         
     | 
| 
      
 308 
     | 
    
         
            +
                task :post_steps do
         
     | 
| 
      
 309 
     | 
    
         
            +
                  puts 'Manually: create a release on GitHub with relevant changelog part'
         
     | 
| 
      
 310 
     | 
    
         
            +
                  puts 'Manually: send email same as release with relevant changelog part'
         
     | 
| 
      
 311 
     | 
    
         
            +
                  puts 'Manually: tweet'
         
     | 
| 
      
 312 
     | 
    
         
            +
                end
         
     | 
| 
      
 313 
     | 
    
         
            +
              end
         
     | 
| 
      
 314 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import org.jruby.Ruby;
         
     | 
| 
      
 2 
     | 
    
         
            +
            import org.jruby.runtime.load.BasicLibraryService;
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            import java.io.IOException;
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            public class ConcurrentRubyService implements BasicLibraryService {
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                public boolean basicLoad(final Ruby runtime) throws IOException {
         
     | 
| 
      
 9 
     | 
    
         
            +
                    new com.concurrent_ruby.ext.AtomicReferenceLibrary().load(runtime, false);
         
     | 
| 
      
 10 
     | 
    
         
            +
                    new com.concurrent_ruby.ext.JavaAtomicBooleanLibrary().load(runtime, false);
         
     | 
| 
      
 11 
     | 
    
         
            +
                    new com.concurrent_ruby.ext.JavaAtomicFixnumLibrary().load(runtime, false);
         
     | 
| 
      
 12 
     | 
    
         
            +
                    new com.concurrent_ruby.ext.JavaSemaphoreLibrary().load(runtime, false);
         
     | 
| 
      
 13 
     | 
    
         
            +
                    new com.concurrent_ruby.ext.SynchronizationLibrary().load(runtime, false);
         
     | 
| 
      
 14 
     | 
    
         
            +
                    new com.concurrent_ruby.ext.JRubyMapBackendLibrary().load(runtime, false);
         
     | 
| 
      
 15 
     | 
    
         
            +
                    return true;
         
     | 
| 
      
 16 
     | 
    
         
            +
                }
         
     | 
| 
      
 17 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,175 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            package com.concurrent_ruby.ext;
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            import java.lang.reflect.Field;
         
     | 
| 
      
 4 
     | 
    
         
            +
            import java.io.IOException;
         
     | 
| 
      
 5 
     | 
    
         
            +
            import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
         
     | 
| 
      
 6 
     | 
    
         
            +
            import org.jruby.Ruby;
         
     | 
| 
      
 7 
     | 
    
         
            +
            import org.jruby.RubyClass;
         
     | 
| 
      
 8 
     | 
    
         
            +
            import org.jruby.RubyModule;
         
     | 
| 
      
 9 
     | 
    
         
            +
            import org.jruby.RubyNumeric;
         
     | 
| 
      
 10 
     | 
    
         
            +
            import org.jruby.RubyObject;
         
     | 
| 
      
 11 
     | 
    
         
            +
            import org.jruby.anno.JRubyClass;
         
     | 
| 
      
 12 
     | 
    
         
            +
            import org.jruby.anno.JRubyMethod;
         
     | 
| 
      
 13 
     | 
    
         
            +
            import org.jruby.runtime.ObjectAllocator;
         
     | 
| 
      
 14 
     | 
    
         
            +
            import org.jruby.runtime.ThreadContext;
         
     | 
| 
      
 15 
     | 
    
         
            +
            import org.jruby.runtime.builtin.IRubyObject;
         
     | 
| 
      
 16 
     | 
    
         
            +
            import org.jruby.runtime.load.Library;
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            /**
         
     | 
| 
      
 19 
     | 
    
         
            +
             * This library adds an atomic reference type to JRuby for use in the atomic
         
     | 
| 
      
 20 
     | 
    
         
            +
             * library. We do a native version to avoid the implicit value coercion that
         
     | 
| 
      
 21 
     | 
    
         
            +
             * normally happens through JI.
         
     | 
| 
      
 22 
     | 
    
         
            +
             * 
         
     | 
| 
      
 23 
     | 
    
         
            +
             * @author headius
         
     | 
| 
      
 24 
     | 
    
         
            +
             */
         
     | 
| 
      
 25 
     | 
    
         
            +
            public class AtomicReferenceLibrary implements Library {
         
     | 
| 
      
 26 
     | 
    
         
            +
                public void load(Ruby runtime, boolean wrap) throws IOException {
         
     | 
| 
      
 27 
     | 
    
         
            +
                    RubyModule concurrentMod = runtime.defineModule("Concurrent");
         
     | 
| 
      
 28 
     | 
    
         
            +
                    RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicReference", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR);
         
     | 
| 
      
 29 
     | 
    
         
            +
                    try {
         
     | 
| 
      
 30 
     | 
    
         
            +
                        sun.misc.Unsafe.class.getMethod("getAndSetObject", Object.class);
         
     | 
| 
      
 31 
     | 
    
         
            +
                        atomicCls.setAllocator(JRUBYREFERENCE8_ALLOCATOR);
         
     | 
| 
      
 32 
     | 
    
         
            +
                    } catch (Exception e) {
         
     | 
| 
      
 33 
     | 
    
         
            +
                        // leave it as Java 6/7 version
         
     | 
| 
      
 34 
     | 
    
         
            +
                    }
         
     | 
| 
      
 35 
     | 
    
         
            +
                    atomicCls.defineAnnotatedMethods(JRubyReference.class);
         
     | 
| 
      
 36 
     | 
    
         
            +
                }
         
     | 
| 
      
 37 
     | 
    
         
            +
                
         
     | 
| 
      
 38 
     | 
    
         
            +
                private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() {
         
     | 
| 
      
 39 
     | 
    
         
            +
                    public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
         
     | 
| 
      
 40 
     | 
    
         
            +
                        return new JRubyReference(runtime, klazz);
         
     | 
| 
      
 41 
     | 
    
         
            +
                    }
         
     | 
| 
      
 42 
     | 
    
         
            +
                };
         
     | 
| 
      
 43 
     | 
    
         
            +
                
         
     | 
| 
      
 44 
     | 
    
         
            +
                private static final ObjectAllocator JRUBYREFERENCE8_ALLOCATOR = new ObjectAllocator() {
         
     | 
| 
      
 45 
     | 
    
         
            +
                    public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
         
     | 
| 
      
 46 
     | 
    
         
            +
                        return new JRubyReference8(runtime, klazz);
         
     | 
| 
      
 47 
     | 
    
         
            +
                    }
         
     | 
| 
      
 48 
     | 
    
         
            +
                };
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                @JRubyClass(name="JRubyReference", parent="Object")
         
     | 
| 
      
 51 
     | 
    
         
            +
                public static class JRubyReference extends RubyObject {
         
     | 
| 
      
 52 
     | 
    
         
            +
                    volatile IRubyObject reference;
         
     | 
| 
      
 53 
     | 
    
         
            +
                    
         
     | 
| 
      
 54 
     | 
    
         
            +
                    static final sun.misc.Unsafe UNSAFE;
         
     | 
| 
      
 55 
     | 
    
         
            +
                    static final long referenceOffset;
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    static {
         
     | 
| 
      
 58 
     | 
    
         
            +
                        try {
         
     | 
| 
      
 59 
     | 
    
         
            +
                            UNSAFE = UnsafeHolder.U;
         
     | 
| 
      
 60 
     | 
    
         
            +
                            Class k = JRubyReference.class;
         
     | 
| 
      
 61 
     | 
    
         
            +
                            referenceOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("reference"));
         
     | 
| 
      
 62 
     | 
    
         
            +
                        } catch (Exception e) {
         
     | 
| 
      
 63 
     | 
    
         
            +
                            throw new RuntimeException(e);
         
     | 
| 
      
 64 
     | 
    
         
            +
                        }
         
     | 
| 
      
 65 
     | 
    
         
            +
                    }
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                    public JRubyReference(Ruby runtime, RubyClass klass) {
         
     | 
| 
      
 68 
     | 
    
         
            +
                        super(runtime, klass);
         
     | 
| 
      
 69 
     | 
    
         
            +
                    }
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    @JRubyMethod
         
     | 
| 
      
 72 
     | 
    
         
            +
                    public IRubyObject initialize(ThreadContext context) {
         
     | 
| 
      
 73 
     | 
    
         
            +
                        UNSAFE.putObject(this, referenceOffset, context.nil);
         
     | 
| 
      
 74 
     | 
    
         
            +
                        return context.nil;
         
     | 
| 
      
 75 
     | 
    
         
            +
                    }
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    @JRubyMethod
         
     | 
| 
      
 78 
     | 
    
         
            +
                    public IRubyObject initialize(ThreadContext context, IRubyObject value) {
         
     | 
| 
      
 79 
     | 
    
         
            +
                        UNSAFE.putObject(this, referenceOffset, value);
         
     | 
| 
      
 80 
     | 
    
         
            +
                        return context.nil;
         
     | 
| 
      
 81 
     | 
    
         
            +
                    }
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                    @JRubyMethod(name = {"get", "value"})
         
     | 
| 
      
 84 
     | 
    
         
            +
                    public IRubyObject get() {
         
     | 
| 
      
 85 
     | 
    
         
            +
                        return reference;
         
     | 
| 
      
 86 
     | 
    
         
            +
                    }
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                    @JRubyMethod(name = {"set", "value="})
         
     | 
| 
      
 89 
     | 
    
         
            +
                    public IRubyObject set(IRubyObject newValue) {
         
     | 
| 
      
 90 
     | 
    
         
            +
                        UNSAFE.putObjectVolatile(this, referenceOffset, newValue);
         
     | 
| 
      
 91 
     | 
    
         
            +
                        return newValue;
         
     | 
| 
      
 92 
     | 
    
         
            +
                    }
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                    @JRubyMethod(name = {"compare_and_set", "compare_and_swap"})
         
     | 
| 
      
 95 
     | 
    
         
            +
                    public IRubyObject compare_and_set(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
         
     | 
| 
      
 96 
     | 
    
         
            +
                        Ruby runtime = context.runtime;
         
     | 
| 
      
 97 
     | 
    
         
            +
                        
         
     | 
| 
      
 98 
     | 
    
         
            +
                        if (expectedValue instanceof RubyNumeric) {
         
     | 
| 
      
 99 
     | 
    
         
            +
                            // numerics are not always idempotent in Ruby, so we need to do slower logic
         
     | 
| 
      
 100 
     | 
    
         
            +
                            return compareAndSetNumeric(context, expectedValue, newValue);
         
     | 
| 
      
 101 
     | 
    
         
            +
                        }
         
     | 
| 
      
 102 
     | 
    
         
            +
                        
         
     | 
| 
      
 103 
     | 
    
         
            +
                        return runtime.newBoolean(UNSAFE.compareAndSwapObject(this, referenceOffset, expectedValue, newValue));
         
     | 
| 
      
 104 
     | 
    
         
            +
                    }
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                    @JRubyMethod(name = {"get_and_set", "swap"})
         
     | 
| 
      
 107 
     | 
    
         
            +
                    public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) {
         
     | 
| 
      
 108 
     | 
    
         
            +
                        // less-efficient version for Java 6 and 7
         
     | 
| 
      
 109 
     | 
    
         
            +
                        while (true) {
         
     | 
| 
      
 110 
     | 
    
         
            +
                            IRubyObject oldValue = get();
         
     | 
| 
      
 111 
     | 
    
         
            +
                            if (UNSAFE.compareAndSwapObject(this, referenceOffset, oldValue, newValue)) {
         
     | 
| 
      
 112 
     | 
    
         
            +
                                return oldValue;
         
     | 
| 
      
 113 
     | 
    
         
            +
                            }
         
     | 
| 
      
 114 
     | 
    
         
            +
                        }
         
     | 
| 
      
 115 
     | 
    
         
            +
                    }
         
     | 
| 
      
 116 
     | 
    
         
            +
                    
         
     | 
| 
      
 117 
     | 
    
         
            +
                    private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) {
         
     | 
| 
      
 118 
     | 
    
         
            +
                        Ruby runtime = context.runtime;
         
     | 
| 
      
 119 
     | 
    
         
            +
                        
         
     | 
| 
      
 120 
     | 
    
         
            +
                        // loop until:
         
     | 
| 
      
 121 
     | 
    
         
            +
                        // * reference CAS would succeed for same-valued objects
         
     | 
| 
      
 122 
     | 
    
         
            +
                        // * current and expected have different values as determined by #equals
         
     | 
| 
      
 123 
     | 
    
         
            +
                        while (true) {
         
     | 
| 
      
 124 
     | 
    
         
            +
                            IRubyObject current = reference;
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                            if (!(current instanceof RubyNumeric)) {
         
     | 
| 
      
 127 
     | 
    
         
            +
                                // old value is not numeric, CAS fails
         
     | 
| 
      
 128 
     | 
    
         
            +
                                return runtime.getFalse();
         
     | 
| 
      
 129 
     | 
    
         
            +
                            }
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                            RubyNumeric currentNumber = (RubyNumeric)current;
         
     | 
| 
      
 132 
     | 
    
         
            +
                            if (!currentNumber.equals(expectedValue)) {
         
     | 
| 
      
 133 
     | 
    
         
            +
                                // current number does not equal expected, fail CAS
         
     | 
| 
      
 134 
     | 
    
         
            +
                                return runtime.getFalse();
         
     | 
| 
      
 135 
     | 
    
         
            +
                            }
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                            // check that current has not changed, or else allow loop to repeat
         
     | 
| 
      
 138 
     | 
    
         
            +
                            boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue);
         
     | 
| 
      
 139 
     | 
    
         
            +
                            if (success) {
         
     | 
| 
      
 140 
     | 
    
         
            +
                                // value is same and did not change in interim...success
         
     | 
| 
      
 141 
     | 
    
         
            +
                                return runtime.getTrue();
         
     | 
| 
      
 142 
     | 
    
         
            +
                            }
         
     | 
| 
      
 143 
     | 
    
         
            +
                        }
         
     | 
| 
      
 144 
     | 
    
         
            +
                    }
         
     | 
| 
      
 145 
     | 
    
         
            +
                }
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                private static final class UnsafeHolder {
         
     | 
| 
      
 148 
     | 
    
         
            +
            	private UnsafeHolder(){}
         
     | 
| 
      
 149 
     | 
    
         
            +
            	    
         
     | 
| 
      
 150 
     | 
    
         
            +
            	public static final sun.misc.Unsafe U = loadUnsafe();
         
     | 
| 
      
 151 
     | 
    
         
            +
            	
         
     | 
| 
      
 152 
     | 
    
         
            +
            	private static sun.misc.Unsafe loadUnsafe() {
         
     | 
| 
      
 153 
     | 
    
         
            +
            	    try {
         
     | 
| 
      
 154 
     | 
    
         
            +
            		Class unsafeClass = Class.forName("sun.misc.Unsafe");
         
     | 
| 
      
 155 
     | 
    
         
            +
            		Field f = unsafeClass.getDeclaredField("theUnsafe");
         
     | 
| 
      
 156 
     | 
    
         
            +
            		f.setAccessible(true);
         
     | 
| 
      
 157 
     | 
    
         
            +
            		return (sun.misc.Unsafe) f.get(null);
         
     | 
| 
      
 158 
     | 
    
         
            +
            	    } catch (Exception e) {
         
     | 
| 
      
 159 
     | 
    
         
            +
            		return null;
         
     | 
| 
      
 160 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 161 
     | 
    
         
            +
            	}
         
     | 
| 
      
 162 
     | 
    
         
            +
                }
         
     | 
| 
      
 163 
     | 
    
         
            +
                
         
     | 
| 
      
 164 
     | 
    
         
            +
                public static class JRubyReference8 extends JRubyReference {
         
     | 
| 
      
 165 
     | 
    
         
            +
                    public JRubyReference8(Ruby runtime, RubyClass klass) {
         
     | 
| 
      
 166 
     | 
    
         
            +
                        super(runtime, klass);
         
     | 
| 
      
 167 
     | 
    
         
            +
                    }
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                    @Override
         
     | 
| 
      
 170 
     | 
    
         
            +
                    public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) {
         
     | 
| 
      
 171 
     | 
    
         
            +
                        // efficient version for Java 8
         
     | 
| 
      
 172 
     | 
    
         
            +
                        return (IRubyObject)UNSAFE.getAndSetObject(this, referenceOffset, newValue);
         
     | 
| 
      
 173 
     | 
    
         
            +
                    }
         
     | 
| 
      
 174 
     | 
    
         
            +
                }
         
     | 
| 
      
 175 
     | 
    
         
            +
            }
         
     |