concurrent-ruby 0.9.2-java → 1.0.0-java
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 +4 -4
 - data/CHANGELOG.md +49 -1
 - data/README.md +86 -120
 - data/lib/concurrent.rb +14 -5
 - data/lib/concurrent/agent.rb +587 -0
 - data/lib/concurrent/array.rb +39 -0
 - data/lib/concurrent/async.rb +296 -149
 - data/lib/concurrent/atom.rb +135 -45
 - data/lib/concurrent/atomic/abstract_thread_local_var.rb +38 -0
 - data/lib/concurrent/atomic/atomic_boolean.rb +83 -118
 - data/lib/concurrent/atomic/atomic_fixnum.rb +101 -163
 - data/lib/concurrent/atomic/atomic_reference.rb +1 -8
 - data/lib/concurrent/atomic/count_down_latch.rb +62 -103
 - data/lib/concurrent/atomic/cyclic_barrier.rb +3 -1
 - data/lib/concurrent/atomic/event.rb +1 -1
 - data/lib/concurrent/atomic/java_count_down_latch.rb +39 -0
 - data/lib/concurrent/atomic/java_thread_local_var.rb +50 -0
 - data/lib/concurrent/atomic/mutex_atomic_boolean.rb +60 -0
 - data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +91 -0
 - data/lib/concurrent/atomic/mutex_count_down_latch.rb +43 -0
 - data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
 - data/lib/concurrent/atomic/read_write_lock.rb +5 -4
 - data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
 - data/lib/concurrent/atomic/ruby_thread_local_var.rb +172 -0
 - data/lib/concurrent/atomic/semaphore.rb +84 -178
 - data/lib/concurrent/atomic/thread_local_var.rb +65 -294
 - data/lib/concurrent/atomic_reference/jruby+truffle.rb +1 -0
 - data/lib/concurrent/atomic_reference/jruby.rb +1 -1
 - data/lib/concurrent/atomic_reference/mutex_atomic.rb +14 -8
 - data/lib/concurrent/atomic_reference/ruby.rb +1 -1
 - data/lib/concurrent/atomics.rb +7 -37
 - data/lib/concurrent/collection/copy_on_notify_observer_set.rb +7 -15
 - data/lib/concurrent/collection/copy_on_write_observer_set.rb +7 -15
 - data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
 - data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +927 -0
 - data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
 - data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +144 -0
 - data/lib/concurrent/collection/map/synchronized_map_backend.rb +86 -0
 - data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
 - data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
 - data/lib/concurrent/concern/dereferenceable.rb +9 -24
 - data/lib/concurrent/concern/logging.rb +1 -1
 - data/lib/concurrent/concern/obligation.rb +11 -20
 - data/lib/concurrent/concern/observable.rb +38 -13
 - data/lib/concurrent/configuration.rb +23 -152
 - data/lib/concurrent/constants.rb +8 -0
 - data/lib/concurrent/delay.rb +14 -12
 - data/lib/concurrent/exchanger.rb +339 -41
 - data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
 - data/lib/concurrent/executor/executor_service.rb +23 -359
 - data/lib/concurrent/executor/immediate_executor.rb +3 -2
 - data/lib/concurrent/executor/java_executor_service.rb +100 -0
 - data/lib/concurrent/executor/java_single_thread_executor.rb +3 -3
 - data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -4
 - data/lib/concurrent/executor/ruby_executor_service.rb +78 -0
 - data/lib/concurrent/executor/ruby_single_thread_executor.rb +10 -66
 - data/lib/concurrent/executor/ruby_thread_pool_executor.rb +25 -22
 - data/lib/concurrent/executor/safe_task_executor.rb +6 -7
 - data/lib/concurrent/executor/serial_executor_service.rb +34 -0
 - data/lib/concurrent/executor/serialized_execution.rb +10 -33
 - data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
 - data/lib/concurrent/executor/simple_executor_service.rb +1 -10
 - data/lib/concurrent/executor/single_thread_executor.rb +20 -10
 - data/lib/concurrent/executor/timer_set.rb +8 -10
 - data/lib/concurrent/executors.rb +12 -2
 - data/lib/concurrent/future.rb +6 -4
 - data/lib/concurrent/hash.rb +35 -0
 - data/lib/concurrent/immutable_struct.rb +5 -1
 - data/lib/concurrent/ivar.rb +12 -16
 - data/lib/concurrent/lazy_register.rb +11 -8
 - data/lib/concurrent/map.rb +180 -0
 - data/lib/concurrent/maybe.rb +6 -3
 - data/lib/concurrent/mutable_struct.rb +7 -6
 - data/lib/concurrent/mvar.rb +26 -2
 - data/lib/concurrent/{executor/executor.rb → options.rb} +5 -29
 - data/lib/concurrent/promise.rb +7 -5
 - data/lib/concurrent/scheduled_task.rb +13 -71
 - data/lib/concurrent/settable_struct.rb +5 -4
 - data/lib/concurrent/synchronization.rb +15 -3
 - data/lib/concurrent/synchronization/abstract_lockable_object.rb +98 -0
 - data/lib/concurrent/synchronization/abstract_object.rb +7 -146
 - data/lib/concurrent/synchronization/abstract_struct.rb +2 -3
 - data/lib/concurrent/synchronization/condition.rb +6 -4
 - data/lib/concurrent/synchronization/jruby_lockable_object.rb +13 -0
 - data/lib/concurrent/synchronization/jruby_object.rb +44 -0
 - data/lib/concurrent/synchronization/lock.rb +3 -2
 - data/lib/concurrent/synchronization/lockable_object.rb +72 -0
 - data/lib/concurrent/synchronization/mri_lockable_object.rb +71 -0
 - data/lib/concurrent/synchronization/mri_object.rb +43 -0
 - data/lib/concurrent/synchronization/object.rb +140 -73
 - data/lib/concurrent/synchronization/rbx_lockable_object.rb +65 -0
 - data/lib/concurrent/synchronization/rbx_object.rb +30 -73
 - data/lib/concurrent/synchronization/volatile.rb +34 -0
 - data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
 - data/lib/concurrent/thread_safe/util.rb +14 -0
 - data/lib/concurrent/thread_safe/util/adder.rb +74 -0
 - data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +30 -0
 - data/lib/concurrent/thread_safe/util/cheap_lockable.rb +118 -0
 - data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +38 -0
 - data/lib/concurrent/thread_safe/util/striped64.rb +241 -0
 - data/lib/concurrent/thread_safe/util/volatile.rb +75 -0
 - data/lib/concurrent/thread_safe/util/xor_shift_random.rb +50 -0
 - data/lib/concurrent/timer_task.rb +3 -4
 - data/lib/concurrent/tuple.rb +86 -0
 - data/lib/concurrent/tvar.rb +5 -1
 - data/lib/concurrent/utility/at_exit.rb +1 -1
 - data/lib/concurrent/utility/engine.rb +4 -0
 - data/lib/concurrent/utility/monotonic_time.rb +3 -4
 - data/lib/concurrent/utility/native_extension_loader.rb +50 -30
 - data/lib/concurrent/version.rb +2 -2
 - data/lib/concurrent_ruby_ext.jar +0 -0
 - metadata +47 -12
 - data/lib/concurrent/atomic/condition.rb +0 -78
 - data/lib/concurrent/collection/priority_queue.rb +0 -360
 - data/lib/concurrent/synchronization/java_object.rb +0 -34
 - data/lib/concurrent/synchronization/monitor_object.rb +0 -27
 - data/lib/concurrent/synchronization/mutex_object.rb +0 -43
 - data/lib/concurrent/utilities.rb +0 -5
 - data/lib/concurrent/utility/timeout.rb +0 -39
 - data/lib/concurrent/utility/timer.rb +0 -26
 - data/lib/concurrent_ruby.rb +0 -2
 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Concurrent
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Synchronization
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
      
 5 
     | 
    
         
            +
                # @!macro internal_implementation_note
         
     | 
| 
      
 6 
     | 
    
         
            +
                class RbxLockableObject < AbstractLockableObject
         
     | 
| 
      
 7 
     | 
    
         
            +
                  safe_initialization!
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(*defaults)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(*defaults)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @__Waiters__ = []
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @__owner__   = nil
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def synchronize(&block)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    if @__owner__ == Thread.current
         
     | 
| 
      
 19 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 20 
     | 
    
         
            +
                    else
         
     | 
| 
      
 21 
     | 
    
         
            +
                      result = nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                      Rubinius.synchronize(self) do
         
     | 
| 
      
 23 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 24 
     | 
    
         
            +
                          @__owner__ = Thread.current
         
     | 
| 
      
 25 
     | 
    
         
            +
                          result     = yield
         
     | 
| 
      
 26 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 27 
     | 
    
         
            +
                          @__owner__ = nil
         
     | 
| 
      
 28 
     | 
    
         
            +
                        end
         
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
                      result
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def ns_wait(timeout = nil)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    wchan = Rubinius::Channel.new
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 38 
     | 
    
         
            +
                      @__Waiters__.push wchan
         
     | 
| 
      
 39 
     | 
    
         
            +
                      Rubinius.unlock(self)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      signaled = wchan.receive_timeout timeout
         
     | 
| 
      
 41 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 42 
     | 
    
         
            +
                      Rubinius.lock(self)
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                      if !signaled && !@__Waiters__.delete(wchan)
         
     | 
| 
      
 45 
     | 
    
         
            +
                        # we timed out, but got signaled afterwards,
         
     | 
| 
      
 46 
     | 
    
         
            +
                        # so pass that signal on to the next waiter
         
     | 
| 
      
 47 
     | 
    
         
            +
                        @__Waiters__.shift << true unless @__Waiters__.empty?
         
     | 
| 
      
 48 
     | 
    
         
            +
                      end
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    self
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def ns_signal
         
     | 
| 
      
 55 
     | 
    
         
            +
                    @__Waiters__.shift << true unless @__Waiters__.empty?
         
     | 
| 
      
 56 
     | 
    
         
            +
                    self
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  def ns_broadcast
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @__Waiters__.shift << true until @__Waiters__.empty?
         
     | 
| 
      
 61 
     | 
    
         
            +
                    self
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,88 +1,45 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Concurrent
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Synchronization
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
                 
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
                   
     | 
| 
       8 
     | 
    
         
            -
                  class RbxObject < AbstractObject
         
     | 
| 
       9 
     | 
    
         
            -
                    def initialize
         
     | 
| 
       10 
     | 
    
         
            -
                      @__Waiters__ = []
         
     | 
| 
       11 
     | 
    
         
            -
                      @__owner__   = nil
         
     | 
| 
       12 
     | 
    
         
            -
                      ensure_ivar_visibility!
         
     | 
| 
       13 
     | 
    
         
            -
                    end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                    protected
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                    def synchronize(&block)
         
     | 
| 
       18 
     | 
    
         
            -
                      if @__owner__ == Thread.current
         
     | 
| 
       19 
     | 
    
         
            -
                        yield
         
     | 
| 
       20 
     | 
    
         
            -
                      else
         
     | 
| 
       21 
     | 
    
         
            -
                        Rubinius.lock(self)
         
     | 
| 
       22 
     | 
    
         
            -
                        begin
         
     | 
| 
       23 
     | 
    
         
            -
                          @__owner__ = Thread.current
         
     | 
| 
       24 
     | 
    
         
            -
                          result = yield
         
     | 
| 
       25 
     | 
    
         
            -
                        ensure
         
     | 
| 
       26 
     | 
    
         
            -
                          @__owner__ = nil
         
     | 
| 
       27 
     | 
    
         
            -
                          Rubinius.unlock(self)
         
     | 
| 
       28 
     | 
    
         
            -
                          result
         
     | 
| 
       29 
     | 
    
         
            -
                        end
         
     | 
| 
       30 
     | 
    
         
            -
                      end
         
     | 
| 
       31 
     | 
    
         
            -
                    end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                    def ns_wait(timeout = nil)
         
     | 
| 
       34 
     | 
    
         
            -
                      wchan = Rubinius::Channel.new
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                      begin
         
     | 
| 
       37 
     | 
    
         
            -
                        @__Waiters__.push wchan
         
     | 
| 
       38 
     | 
    
         
            -
                        Rubinius.unlock(self)
         
     | 
| 
       39 
     | 
    
         
            -
                        signaled = wchan.receive_timeout timeout
         
     | 
| 
       40 
     | 
    
         
            -
                      ensure
         
     | 
| 
       41 
     | 
    
         
            -
                        Rubinius.lock(self)
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                        if !signaled && !@__Waiters__.delete(wchan)
         
     | 
| 
       44 
     | 
    
         
            -
                          # we timed out, but got signaled afterwards,
         
     | 
| 
       45 
     | 
    
         
            -
                          # so pass that signal on to the next waiter
         
     | 
| 
       46 
     | 
    
         
            -
                          @__Waiters__.shift << true unless @__Waiters__.empty?
         
     | 
| 
       47 
     | 
    
         
            -
                        end
         
     | 
| 
       48 
     | 
    
         
            -
                      end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                      self
         
     | 
| 
       51 
     | 
    
         
            -
                    end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                    def ns_signal
         
     | 
| 
       54 
     | 
    
         
            -
                      @__Waiters__.shift << true unless @__Waiters__.empty?
         
     | 
| 
       55 
     | 
    
         
            -
                      self
         
     | 
| 
       56 
     | 
    
         
            -
                    end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                    def ns_broadcast
         
     | 
| 
       59 
     | 
    
         
            -
                      @__Waiters__.shift << true until @__Waiters__.empty?
         
     | 
| 
       60 
     | 
    
         
            -
                      self
         
     | 
| 
       61 
     | 
    
         
            -
                    end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                    def ensure_ivar_visibility!
         
     | 
| 
       64 
     | 
    
         
            -
                      # Rubinius instance variables are not volatile so we need to insert barrier
         
     | 
| 
       65 
     | 
    
         
            -
                      Rubinius.memory_barrier
         
     | 
| 
       66 
     | 
    
         
            -
                    end
         
     | 
| 
      
 4 
     | 
    
         
            +
                module RbxAttrVolatile
         
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.included(base)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    base.extend(ClassMethods)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
       67 
8 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
      
 9 
     | 
    
         
            +
                  module ClassMethods
         
     | 
| 
      
 10 
     | 
    
         
            +
                    def attr_volatile(*names)
         
     | 
| 
       69 
11 
     | 
    
         
             
                      names.each do |name|
         
     | 
| 
       70 
12 
     | 
    
         
             
                        ivar = :"@volatile_#{name}"
         
     | 
| 
       71 
13 
     | 
    
         
             
                        class_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
                          def #{name}
         
     | 
| 
      
 15 
     | 
    
         
            +
                            Rubinius.memory_barrier
         
     | 
| 
      
 16 
     | 
    
         
            +
                            #{ivar}
         
     | 
| 
      
 17 
     | 
    
         
            +
                          end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                          def #{name}=(value)
         
     | 
| 
      
 20 
     | 
    
         
            +
                            #{ivar} = value
         
     | 
| 
      
 21 
     | 
    
         
            +
                            Rubinius.memory_barrier
         
     | 
| 
      
 22 
     | 
    
         
            +
                          end
         
     | 
| 
       81 
23 
     | 
    
         
             
                        RUBY
         
     | 
| 
       82 
24 
     | 
    
         
             
                      end
         
     | 
| 
       83 
25 
     | 
    
         
             
                      names.map { |n| [n, :"#{n}="] }.flatten
         
     | 
| 
       84 
26 
     | 
    
         
             
                    end
         
     | 
| 
       85 
27 
     | 
    
         
             
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def full_memory_barrier
         
     | 
| 
      
 30 
     | 
    
         
            +
                    # Rubinius instance variables are not volatile so we need to insert barrier
         
     | 
| 
      
 31 
     | 
    
         
            +
                    Rubinius.memory_barrier
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
      
 36 
     | 
    
         
            +
                # @!macro internal_implementation_note
         
     | 
| 
      
 37 
     | 
    
         
            +
                class RbxObject < AbstractObject
         
     | 
| 
      
 38 
     | 
    
         
            +
                  include RbxAttrVolatile
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 41 
     | 
    
         
            +
                    # nothing to do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
       86 
43 
     | 
    
         
             
                end
         
     | 
| 
       87 
44 
     | 
    
         
             
              end
         
     | 
| 
       88 
45 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Concurrent
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Synchronization
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                # Volatile adds the attr_volatile class method when included.
         
     | 
| 
      
 5 
     | 
    
         
            +
                #
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 7 
     | 
    
         
            +
                #   class Foo
         
     | 
| 
      
 8 
     | 
    
         
            +
                #     include Concurrent::Synchronization::Volatile
         
     | 
| 
      
 9 
     | 
    
         
            +
                #
         
     | 
| 
      
 10 
     | 
    
         
            +
                #     attr_volatile :bar
         
     | 
| 
      
 11 
     | 
    
         
            +
                #
         
     | 
| 
      
 12 
     | 
    
         
            +
                #     def initialize
         
     | 
| 
      
 13 
     | 
    
         
            +
                #       self.bar = 1
         
     | 
| 
      
 14 
     | 
    
         
            +
                #     end
         
     | 
| 
      
 15 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 16 
     | 
    
         
            +
                #
         
     | 
| 
      
 17 
     | 
    
         
            +
                #  foo = Foo.new
         
     | 
| 
      
 18 
     | 
    
         
            +
                #  foo.bar
         
     | 
| 
      
 19 
     | 
    
         
            +
                #  => 1
         
     | 
| 
      
 20 
     | 
    
         
            +
                #  foo.bar = 2
         
     | 
| 
      
 21 
     | 
    
         
            +
                #  => 2
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                Volatile = case
         
     | 
| 
      
 24 
     | 
    
         
            +
                when Concurrent.on_cruby?
         
     | 
| 
      
 25 
     | 
    
         
            +
                  MriAttrVolatile
         
     | 
| 
      
 26 
     | 
    
         
            +
                when Concurrent.on_jruby?
         
     | 
| 
      
 27 
     | 
    
         
            +
                  JRubyAttrVolatile
         
     | 
| 
      
 28 
     | 
    
         
            +
                when Concurrent.on_rbx? || Concurrent.on_truffle?
         
     | 
| 
      
 29 
     | 
    
         
            +
                  RbxAttrVolatile
         
     | 
| 
      
 30 
     | 
    
         
            +
                else
         
     | 
| 
      
 31 
     | 
    
         
            +
                  MriAttrVolatile
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'delegate'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'monitor'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Concurrent
         
     | 
| 
      
 5 
     | 
    
         
            +
              unless defined?(SynchronizedDelegator)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                # This class provides a trivial way to synchronize all calls to a given object
         
     | 
| 
      
 8 
     | 
    
         
            +
                # by wrapping it with a `Delegator` that performs `Monitor#enter/exit` calls
         
     | 
| 
      
 9 
     | 
    
         
            +
                # around the delegated `#send`. Example:
         
     | 
| 
      
 10 
     | 
    
         
            +
                #
         
     | 
| 
      
 11 
     | 
    
         
            +
                #   array = [] # not thread-safe on many impls
         
     | 
| 
      
 12 
     | 
    
         
            +
                #   array = SynchronizedDelegator.new([]) # thread-safe
         
     | 
| 
      
 13 
     | 
    
         
            +
                #
         
     | 
| 
      
 14 
     | 
    
         
            +
                # A simple `Monitor` provides a very coarse-grained way to synchronize a given
         
     | 
| 
      
 15 
     | 
    
         
            +
                # object, in that it will cause synchronization for methods that have no need
         
     | 
| 
      
 16 
     | 
    
         
            +
                # for it, but this is a trivial way to get thread-safety where none may exist
         
     | 
| 
      
 17 
     | 
    
         
            +
                # currently on some implementations.
         
     | 
| 
      
 18 
     | 
    
         
            +
                #
         
     | 
| 
      
 19 
     | 
    
         
            +
                # This class is currently being considered for inclusion into stdlib, via
         
     | 
| 
      
 20 
     | 
    
         
            +
                # https://bugs.ruby-lang.org/issues/8556
         
     | 
| 
      
 21 
     | 
    
         
            +
                #
         
     | 
| 
      
 22 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
      
 23 
     | 
    
         
            +
                class SynchronizedDelegator < SimpleDelegator
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def setup
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @old_abort = Thread.abort_on_exception
         
     | 
| 
      
 26 
     | 
    
         
            +
                    Thread.abort_on_exception = true
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def teardown
         
     | 
| 
      
 30 
     | 
    
         
            +
                    Thread.abort_on_exception = @old_abort
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def initialize(obj)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    __setobj__(obj)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @monitor = Monitor.new
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def method_missing(method, *args, &block)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    monitor = @monitor
         
     | 
| 
      
 40 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 41 
     | 
    
         
            +
                      monitor.enter
         
     | 
| 
      
 42 
     | 
    
         
            +
                      super
         
     | 
| 
      
 43 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 44 
     | 
    
         
            +
                      monitor.exit
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Concurrent
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              # @!visibility private
         
     | 
| 
      
 4 
     | 
    
         
            +
              module ThreadSafe
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
      
 7 
     | 
    
         
            +
                module Util
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  FIXNUM_BIT_SIZE = (0.size * 8) - 2
         
     | 
| 
      
 10 
     | 
    
         
            +
                  MAX_INT         = (2 ** FIXNUM_BIT_SIZE) - 1
         
     | 
| 
      
 11 
     | 
    
         
            +
                  CPU_COUNT       = 16 # is there a way to determine this?
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'concurrent/thread_safe/util'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'concurrent/thread_safe/util/striped64'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Concurrent
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              # @!visibility private
         
     | 
| 
      
 7 
     | 
    
         
            +
              module ThreadSafe
         
     | 
| 
      
 8 
     | 
    
         
            +
                
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
      
 10 
     | 
    
         
            +
                module Util
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # A Ruby port of the Doug Lea's jsr166e.LondAdder class version 1.8
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # available in public domain.
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # Original source code available here:
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # One or more variables that together maintain an initially zero
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # sum. When updates (method +add+) are contended across threads,
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # the set of variables may grow dynamically to reduce contention.
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # Method +sum+ returns the current total combined across the
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # variables maintaining the sum.
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # This class is usually preferable to single +Atomic+ reference when
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # multiple threads update a common sum that is used for purposes such
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # as collecting statistics, not for fine-grained synchronization
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # control.  Under low update contention, the two classes have similar
         
     | 
| 
      
 28 
     | 
    
         
            +
                  # characteristics. But under high contention, expected throughput of
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # this class is significantly higher, at the expense of higher space
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # consumption.
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # 
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @!visibility private
         
     | 
| 
      
 33 
     | 
    
         
            +
                  class Adder < Striped64
         
     | 
| 
      
 34 
     | 
    
         
            +
                    # Adds the given value.
         
     | 
| 
      
 35 
     | 
    
         
            +
                    def add(x)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      if (current_cells = cells) || !cas_base_computed {|current_base| current_base + x}
         
     | 
| 
      
 37 
     | 
    
         
            +
                        was_uncontended = true
         
     | 
| 
      
 38 
     | 
    
         
            +
                        hash            = hash_code
         
     | 
| 
      
 39 
     | 
    
         
            +
                        unless current_cells && (cell = current_cells.volatile_get_by_hash(hash)) && (was_uncontended = cell.cas_computed {|current_value| current_value + x})
         
     | 
| 
      
 40 
     | 
    
         
            +
                          retry_update(x, hash, was_uncontended) {|current_value| current_value + x}
         
     | 
| 
      
 41 
     | 
    
         
            +
                        end
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    def increment
         
     | 
| 
      
 46 
     | 
    
         
            +
                      add(1)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    def decrement
         
     | 
| 
      
 50 
     | 
    
         
            +
                      add(-1)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    # Returns the current sum.  The returned value is _NOT_ an
         
     | 
| 
      
 54 
     | 
    
         
            +
                    # atomic snapshot: Invocation in the absence of concurrent
         
     | 
| 
      
 55 
     | 
    
         
            +
                    # updates returns an accurate result, but concurrent updates that
         
     | 
| 
      
 56 
     | 
    
         
            +
                    # occur while the sum is being calculated might not be
         
     | 
| 
      
 57 
     | 
    
         
            +
                    # incorporated.
         
     | 
| 
      
 58 
     | 
    
         
            +
                    def sum
         
     | 
| 
      
 59 
     | 
    
         
            +
                      x = base
         
     | 
| 
      
 60 
     | 
    
         
            +
                      if current_cells = cells
         
     | 
| 
      
 61 
     | 
    
         
            +
                        current_cells.each do |cell|
         
     | 
| 
      
 62 
     | 
    
         
            +
                          x += cell.value if cell
         
     | 
| 
      
 63 
     | 
    
         
            +
                        end
         
     | 
| 
      
 64 
     | 
    
         
            +
                      end
         
     | 
| 
      
 65 
     | 
    
         
            +
                      x
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    def reset
         
     | 
| 
      
 69 
     | 
    
         
            +
                      internal_reset(0)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'concurrent/thread_safe/util'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Concurrent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module ThreadSafe
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Util
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.make_synchronized_on_rbx(klass)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    klass.class_eval do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      private
         
     | 
| 
      
 9 
     | 
    
         
            +
                      def _mon_initialize
         
     | 
| 
      
 10 
     | 
    
         
            +
                        @_monitor = Monitor.new unless @_monitor # avoid double initialisation
         
     | 
| 
      
 11 
     | 
    
         
            +
                      end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                      def self.allocate
         
     | 
| 
      
 14 
     | 
    
         
            +
                        obj = super
         
     | 
| 
      
 15 
     | 
    
         
            +
                        obj.send(:_mon_initialize)
         
     | 
| 
      
 16 
     | 
    
         
            +
                        obj
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    klass.superclass.instance_methods(false).each do |method|
         
     | 
| 
      
 21 
     | 
    
         
            +
                      klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
      
 22 
     | 
    
         
            +
                        def #{method}(*args)
         
     | 
| 
      
 23 
     | 
    
         
            +
                          @_monitor.synchronize { super }
         
     | 
| 
      
 24 
     | 
    
         
            +
                        end
         
     | 
| 
      
 25 
     | 
    
         
            +
                      RUBY
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,118 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'concurrent/thread_safe/util'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'concurrent/thread_safe/util/volatile'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Concurrent
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              # @!visibility private
         
     | 
| 
      
 7 
     | 
    
         
            +
              module ThreadSafe
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
      
 10 
     | 
    
         
            +
                module Util
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # Provides a cheapest possible (mainly in terms of memory usage) +Mutex+
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # with the +ConditionVariable+ bundled in.
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # Usage:
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   class A
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #     include CheapLockable
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #     def do_exlusively
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #       cheap_synchronize { yield }
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #     def wait_for_something
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #       cheap_synchronize do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #         cheap_wait until resource_available?
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #         do_something
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #         cheap_broadcast # wake up others
         
     | 
| 
      
 28 
     | 
    
         
            +
                  #       end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # 
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @!visibility private
         
     | 
| 
      
 33 
     | 
    
         
            +
                  module CheapLockable
         
     | 
| 
      
 34 
     | 
    
         
            +
                    private
         
     | 
| 
      
 35 
     | 
    
         
            +
                    engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
         
     | 
| 
      
 36 
     | 
    
         
            +
                    if engine == 'rbx'
         
     | 
| 
      
 37 
     | 
    
         
            +
                      # Making use of the Rubinius' ability to lock via object headers to avoid the overhead of the extra Mutex objects.
         
     | 
| 
      
 38 
     | 
    
         
            +
                      def cheap_synchronize
         
     | 
| 
      
 39 
     | 
    
         
            +
                        Rubinius.lock(self)
         
     | 
| 
      
 40 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 41 
     | 
    
         
            +
                          yield
         
     | 
| 
      
 42 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 43 
     | 
    
         
            +
                          Rubinius.unlock(self)
         
     | 
| 
      
 44 
     | 
    
         
            +
                        end
         
     | 
| 
      
 45 
     | 
    
         
            +
                      end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                      def cheap_wait
         
     | 
| 
      
 48 
     | 
    
         
            +
                        wchan = Rubinius::Channel.new
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 51 
     | 
    
         
            +
                          waiters = @waiters ||= []
         
     | 
| 
      
 52 
     | 
    
         
            +
                          waiters.push wchan
         
     | 
| 
      
 53 
     | 
    
         
            +
                          Rubinius.unlock(self)
         
     | 
| 
      
 54 
     | 
    
         
            +
                          signaled = wchan.receive_timeout nil
         
     | 
| 
      
 55 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 56 
     | 
    
         
            +
                          Rubinius.lock(self)
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                          unless signaled or waiters.delete(wchan)
         
     | 
| 
      
 59 
     | 
    
         
            +
                            # we timed out, but got signaled afterwards (e.g. while waiting to
         
     | 
| 
      
 60 
     | 
    
         
            +
                            # acquire @lock), so pass that signal on to the next waiter
         
     | 
| 
      
 61 
     | 
    
         
            +
                            waiters.shift << true unless waiters.empty?
         
     | 
| 
      
 62 
     | 
    
         
            +
                          end
         
     | 
| 
      
 63 
     | 
    
         
            +
                        end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                        self
         
     | 
| 
      
 66 
     | 
    
         
            +
                      end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                      def cheap_broadcast
         
     | 
| 
      
 69 
     | 
    
         
            +
                        waiters = @waiters ||= []
         
     | 
| 
      
 70 
     | 
    
         
            +
                        waiters.shift << true until waiters.empty?
         
     | 
| 
      
 71 
     | 
    
         
            +
                        self
         
     | 
| 
      
 72 
     | 
    
         
            +
                      end
         
     | 
| 
      
 73 
     | 
    
         
            +
                    elsif engine == 'jruby'
         
     | 
| 
      
 74 
     | 
    
         
            +
                      # Use Java's native synchronized (this) { wait(); notifyAll(); } to avoid the overhead of the extra Mutex objects
         
     | 
| 
      
 75 
     | 
    
         
            +
                      require 'jruby'
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                      def cheap_synchronize
         
     | 
| 
      
 78 
     | 
    
         
            +
                        JRuby.reference0(self).synchronized { yield }
         
     | 
| 
      
 79 
     | 
    
         
            +
                      end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                      def cheap_wait
         
     | 
| 
      
 82 
     | 
    
         
            +
                        JRuby.reference0(self).wait
         
     | 
| 
      
 83 
     | 
    
         
            +
                      end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                      def cheap_broadcast
         
     | 
| 
      
 86 
     | 
    
         
            +
                        JRuby.reference0(self).notify_all
         
     | 
| 
      
 87 
     | 
    
         
            +
                      end
         
     | 
| 
      
 88 
     | 
    
         
            +
                    else
         
     | 
| 
      
 89 
     | 
    
         
            +
                      require 'thread'
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                      extend Volatile
         
     | 
| 
      
 92 
     | 
    
         
            +
                      attr_volatile :mutex
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                      # Non-reentrant Mutex#syncrhonize
         
     | 
| 
      
 95 
     | 
    
         
            +
                      def cheap_synchronize
         
     | 
| 
      
 96 
     | 
    
         
            +
                        true until (my_mutex = mutex) || cas_mutex(nil, my_mutex = Mutex.new)
         
     | 
| 
      
 97 
     | 
    
         
            +
                        my_mutex.synchronize { yield }
         
     | 
| 
      
 98 
     | 
    
         
            +
                      end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                      # Releases this object's +cheap_synchronize+ lock and goes to sleep waiting for other threads to +cheap_broadcast+, reacquires the lock on wakeup.
         
     | 
| 
      
 101 
     | 
    
         
            +
                      # Must only be called in +cheap_broadcast+'s block.
         
     | 
| 
      
 102 
     | 
    
         
            +
                      def cheap_wait
         
     | 
| 
      
 103 
     | 
    
         
            +
                        conditional_variable = @conditional_variable ||= ConditionVariable.new
         
     | 
| 
      
 104 
     | 
    
         
            +
                        conditional_variable.wait(mutex)
         
     | 
| 
      
 105 
     | 
    
         
            +
                      end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                      # Wakes up all threads waiting for this object's +cheap_synchronize+ lock.
         
     | 
| 
      
 108 
     | 
    
         
            +
                      # Must only be called in +cheap_broadcast+'s block.
         
     | 
| 
      
 109 
     | 
    
         
            +
                      def cheap_broadcast
         
     | 
| 
      
 110 
     | 
    
         
            +
                        if conditional_variable = @conditional_variable
         
     | 
| 
      
 111 
     | 
    
         
            +
                          conditional_variable.broadcast
         
     | 
| 
      
 112 
     | 
    
         
            +
                        end
         
     | 
| 
      
 113 
     | 
    
         
            +
                      end
         
     | 
| 
      
 114 
     | 
    
         
            +
                    end
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
              end
         
     | 
| 
      
 118 
     | 
    
         
            +
            end
         
     |