concurrent-ruby 0.7.0.rc1-x86-mingw32 → 0.7.0.rc2-x86-mingw32
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 +8 -8
- data/README.md +3 -2
- data/ext/concurrent_ruby_ext/atomic_boolean.c +48 -0
- data/ext/concurrent_ruby_ext/atomic_boolean.h +16 -0
- data/ext/concurrent_ruby_ext/atomic_fixnum.c +50 -0
- data/ext/concurrent_ruby_ext/atomic_fixnum.h +13 -0
- data/ext/concurrent_ruby_ext/atomic_reference.c +44 -44
- data/ext/concurrent_ruby_ext/atomic_reference.h +8 -0
- data/ext/concurrent_ruby_ext/rb_concurrent.c +32 -3
- data/ext/concurrent_ruby_ext/ruby_193_compatible.h +28 -0
- data/lib/1.9/concurrent_ruby_ext.so +0 -0
- data/lib/2.0/concurrent_ruby_ext.so +0 -0
- data/lib/concurrent.rb +2 -1
- data/lib/concurrent/actor.rb +104 -0
- data/lib/concurrent/{actress → actor}/ad_hoc.rb +2 -3
- data/lib/concurrent/actor/behaviour.rb +70 -0
- data/lib/concurrent/actor/behaviour/abstract.rb +48 -0
- data/lib/concurrent/actor/behaviour/awaits.rb +21 -0
- data/lib/concurrent/actor/behaviour/buffer.rb +54 -0
- data/lib/concurrent/actor/behaviour/errors_on_unknown_message.rb +12 -0
- data/lib/concurrent/actor/behaviour/executes_context.rb +18 -0
- data/lib/concurrent/actor/behaviour/linking.rb +42 -0
- data/lib/concurrent/actor/behaviour/pausing.rb +77 -0
- data/lib/concurrent/actor/behaviour/removes_child.rb +16 -0
- data/lib/concurrent/actor/behaviour/sets_results.rb +36 -0
- data/lib/concurrent/actor/behaviour/supervised.rb +58 -0
- data/lib/concurrent/actor/behaviour/supervising.rb +34 -0
- data/lib/concurrent/actor/behaviour/terminates_children.rb +13 -0
- data/lib/concurrent/actor/behaviour/termination.rb +54 -0
- data/lib/concurrent/actor/context.rb +153 -0
- data/lib/concurrent/actor/core.rb +213 -0
- data/lib/concurrent/actor/default_dead_letter_handler.rb +9 -0
- data/lib/concurrent/{actress → actor}/envelope.rb +1 -1
- data/lib/concurrent/actor/errors.rb +27 -0
- data/lib/concurrent/actor/internal_delegations.rb +49 -0
- data/lib/concurrent/{actress/core_delegations.rb → actor/public_delegations.rb} +11 -13
- data/lib/concurrent/{actress → actor}/reference.rb +25 -8
- data/lib/concurrent/actor/root.rb +37 -0
- data/lib/concurrent/{actress → actor}/type_check.rb +1 -1
- data/lib/concurrent/actor/utills.rb +7 -0
- data/lib/concurrent/actor/utils/broadcast.rb +36 -0
- data/lib/concurrent/actress.rb +2 -224
- data/lib/concurrent/agent.rb +10 -12
- data/lib/concurrent/atomic.rb +32 -1
- data/lib/concurrent/atomic/atomic_boolean.rb +55 -13
- data/lib/concurrent/atomic/atomic_fixnum.rb +54 -16
- data/lib/concurrent/atomic/synchronization.rb +51 -0
- data/lib/concurrent/atomic/thread_local_var.rb +15 -50
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +1 -1
- data/lib/concurrent/atomic_reference/ruby.rb +15 -0
- data/lib/concurrent/atomics.rb +1 -0
- data/lib/concurrent/channel/unbuffered_channel.rb +2 -1
- data/lib/concurrent/configuration.rb +6 -3
- data/lib/concurrent/dataflow.rb +20 -3
- data/lib/concurrent/delay.rb +23 -31
- data/lib/concurrent/executor/executor.rb +7 -2
- data/lib/concurrent/executor/timer_set.rb +1 -1
- data/lib/concurrent/future.rb +2 -1
- data/lib/concurrent/lazy_register.rb +58 -0
- data/lib/concurrent/options_parser.rb +4 -2
- data/lib/concurrent/promise.rb +2 -1
- data/lib/concurrent/scheduled_task.rb +6 -5
- data/lib/concurrent/tvar.rb +6 -10
- data/lib/concurrent/utility/processor_count.rb +4 -2
- data/lib/concurrent/version.rb +1 -1
- data/lib/concurrent_ruby_ext.so +0 -0
- metadata +37 -10
- data/lib/concurrent/actress/context.rb +0 -98
- data/lib/concurrent/actress/core.rb +0 -228
- data/lib/concurrent/actress/errors.rb +0 -14
    
        data/lib/concurrent/agent.rb
    CHANGED
    
    | @@ -38,10 +38,6 @@ module Concurrent | |
| 38 38 | 
             
                include Concurrent::Observable
         | 
| 39 39 | 
             
                include Logging
         | 
| 40 40 |  | 
| 41 | 
            -
                # The default timeout value (in seconds); used when no timeout option
         | 
| 42 | 
            -
                # is given at initialization
         | 
| 43 | 
            -
                TIMEOUT = 5
         | 
| 44 | 
            -
             | 
| 45 41 | 
             
                attr_reader :timeout, :task_executor, :operation_executor
         | 
| 46 42 |  | 
| 47 43 | 
             
                # Initialize a new Agent with the given initial value and provided options.
         | 
| @@ -49,8 +45,6 @@ module Concurrent | |
| 49 45 | 
             
                # @param [Object] initial the initial value
         | 
| 50 46 | 
             
                # @param [Hash] opts the options used to define the behavior at update and deref
         | 
| 51 47 | 
             
                #
         | 
| 52 | 
            -
                # @option opts [Fixnum] :timeout (TIMEOUT) maximum number of seconds before an update is cancelled
         | 
| 53 | 
            -
                #
         | 
| 54 48 | 
             
                # @option opts [Boolean] :operation (false) when `true` will execute the future on the global
         | 
| 55 49 | 
             
                #   operation pool (for long-running operations), when `false` will execute the future on the
         | 
| 56 50 | 
             
                #   global task pool (for short-running tasks)
         | 
| @@ -65,7 +59,6 @@ module Concurrent | |
| 65 59 | 
             
                  @value                = initial
         | 
| 66 60 | 
             
                  @rescuers             = []
         | 
| 67 61 | 
             
                  @validator            = Proc.new { |result| true }
         | 
| 68 | 
            -
                  @timeout              = opts.fetch(:timeout, TIMEOUT).freeze
         | 
| 69 62 | 
             
                  self.observers        = CopyOnWriteObserverSet.new
         | 
| 70 63 | 
             
                  @serialized_execution = SerializedExecution.new
         | 
| 71 64 | 
             
                  @task_executor        = OptionsParser.get_task_executor_from(opts)
         | 
| @@ -145,12 +138,19 @@ module Concurrent | |
| 145 138 | 
             
                # Update the current value with the result of the given block operation,
         | 
| 146 139 | 
             
                # block can do blocking calls
         | 
| 147 140 | 
             
                #
         | 
| 141 | 
            +
                # @param [Fixnum, nil] timeout maximum number of seconds before an update is cancelled
         | 
| 142 | 
            +
                #
         | 
| 148 143 | 
             
                # @yield the operation to be performed with the current value in order to calculate
         | 
| 149 144 | 
             
                #   the new value
         | 
| 150 145 | 
             
                # @yieldparam [Object] value the current value
         | 
| 151 146 | 
             
                # @yieldreturn [Object] the new value
         | 
| 152 147 | 
             
                # @return [true, nil] nil when no block is given
         | 
| 153 | 
            -
                def post_off(&block)
         | 
| 148 | 
            +
                def post_off(timeout = nil, &block)
         | 
| 149 | 
            +
                  block = if timeout
         | 
| 150 | 
            +
                            lambda { |value| Concurrent::timeout(timeout) { block.call(value) } }
         | 
| 151 | 
            +
                          else
         | 
| 152 | 
            +
                            block
         | 
| 153 | 
            +
                          end
         | 
| 154 154 | 
             
                  post_on(@operation_executor, &block)
         | 
| 155 155 | 
             
                end
         | 
| 156 156 |  | 
| @@ -203,10 +203,8 @@ module Concurrent | |
| 203 203 | 
             
                  validator, value = mutex.synchronize { [@validator, @value] }
         | 
| 204 204 |  | 
| 205 205 | 
             
                  begin
         | 
| 206 | 
            -
                    result | 
| 207 | 
            -
             | 
| 208 | 
            -
                      [result, validator.call(result)]
         | 
| 209 | 
            -
                    end
         | 
| 206 | 
            +
                    result = handler.call(value)
         | 
| 207 | 
            +
                    valid  = validator.call(result)
         | 
| 210 208 | 
             
                  rescue Exception => ex
         | 
| 211 209 | 
             
                    exception = ex
         | 
| 212 210 | 
             
                  end
         | 
    
        data/lib/concurrent/atomic.rb
    CHANGED
    
    | @@ -20,7 +20,38 @@ if defined? Concurrent::JavaAtomic | |
| 20 20 | 
             
              #
         | 
| 21 21 | 
             
              #   An object reference that may be updated atomically.
         | 
| 22 22 | 
             
              #
         | 
| 23 | 
            -
              # | 
| 23 | 
            +
              #       Testing with ruby 2.1.2
         | 
| 24 | 
            +
              #       
         | 
| 25 | 
            +
              #       *** Sequential updates ***
         | 
| 26 | 
            +
              #                        user     system      total        real
         | 
| 27 | 
            +
              #       no lock      0.000000   0.000000   0.000000 (  0.005502)
         | 
| 28 | 
            +
              #       mutex        0.030000   0.000000   0.030000 (  0.025158)
         | 
| 29 | 
            +
              #       MutexAtomic  0.100000   0.000000   0.100000 (  0.103096)
         | 
| 30 | 
            +
              #       CAtomic      0.040000   0.000000   0.040000 (  0.034012)
         | 
| 31 | 
            +
              #       
         | 
| 32 | 
            +
              #       *** Parallel updates ***
         | 
| 33 | 
            +
              #                        user     system      total        real
         | 
| 34 | 
            +
              #       no lock      0.010000   0.000000   0.010000 (  0.009387)
         | 
| 35 | 
            +
              #       mutex        0.030000   0.010000   0.040000 (  0.032545)
         | 
| 36 | 
            +
              #       MutexAtomic  0.830000   2.280000   3.110000 (  2.146622)
         | 
| 37 | 
            +
              #       CAtomic      0.040000   0.000000   0.040000 (  0.038332)
         | 
| 38 | 
            +
              #
         | 
| 39 | 
            +
              #       Testing with jruby 1.9.3
         | 
| 40 | 
            +
              #       
         | 
| 41 | 
            +
              #       *** Sequential updates ***
         | 
| 42 | 
            +
              #                        user     system      total        real
         | 
| 43 | 
            +
              #       no lock      0.170000   0.000000   0.170000 (  0.051000)
         | 
| 44 | 
            +
              #       mutex        0.370000   0.010000   0.380000 (  0.121000)
         | 
| 45 | 
            +
              #       MutexAtomic  1.530000   0.020000   1.550000 (  0.471000)
         | 
| 46 | 
            +
              #       JavaAtomic   0.370000   0.010000   0.380000 (  0.112000)
         | 
| 47 | 
            +
              #       
         | 
| 48 | 
            +
              #       *** Parallel updates ***
         | 
| 49 | 
            +
              #                        user     system      total        real
         | 
| 50 | 
            +
              #       no lock      0.390000   0.000000   0.390000 (  0.105000)
         | 
| 51 | 
            +
              #       mutex        0.480000   0.040000   0.520000 (  0.145000)
         | 
| 52 | 
            +
              #       MutexAtomic  1.600000   0.180000   1.780000 (  0.511000)
         | 
| 53 | 
            +
              #       JavaAtomic   0.460000   0.010000   0.470000 (  0.131000)
         | 
| 54 | 
            +
              #
         | 
| 24 55 | 
             
              #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html
         | 
| 25 56 | 
             
              #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html
         | 
| 26 57 | 
             
              class Concurrent::Atomic < Concurrent::JavaAtomic
         | 
| @@ -6,21 +6,32 @@ module Concurrent | |
| 6 6 | 
             
              #   boolean and thread-safe and guaranteed to succeed. Reads and writes may block
         | 
| 7 7 | 
             
              #   briefly but no explicit locking is required.
         | 
| 8 8 | 
             
              #
         | 
| 9 | 
            -
              # | 
| 9 | 
            +
              #       Testing with ruby 2.1.2
         | 
| 10 | 
            +
              #       Testing with Concurrent::MutexAtomicBoolean...
         | 
| 11 | 
            +
              #         2.790000   0.000000   2.790000 (  2.791454)
         | 
| 12 | 
            +
              #       Testing with Concurrent::CAtomicBoolean...
         | 
| 13 | 
            +
              #         0.740000   0.000000   0.740000 (  0.740206)
         | 
| 14 | 
            +
              #
         | 
| 15 | 
            +
              #       Testing with jruby 1.9.3
         | 
| 16 | 
            +
              #       Testing with Concurrent::MutexAtomicBoolean...
         | 
| 17 | 
            +
              #         5.240000   2.520000   7.760000 (  3.683000)
         | 
| 18 | 
            +
              #       Testing with Concurrent::JavaAtomicBoolean...
         | 
| 19 | 
            +
              #         3.340000   0.010000   3.350000 (  0.855000)
         | 
| 20 | 
            +
              #
         | 
| 10 21 | 
             
              #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean
         | 
| 11 22 | 
             
              class MutexAtomicBoolean
         | 
| 12 23 |  | 
| 13 24 | 
             
                # @!macro [attach] atomic_boolean_method_initialize
         | 
| 14 25 | 
             
                #
         | 
| 15 | 
            -
                # | 
| 26 | 
            +
                #   Creates a new `AtomicBoolean` with the given initial value.
         | 
| 16 27 | 
             
                #
         | 
| 17 | 
            -
                # | 
| 28 | 
            +
                #   @param [Boolean] initial the initial value
         | 
| 18 29 | 
             
                def initialize(initial = false)
         | 
| 19 30 | 
             
                  @value = !!initial
         | 
| 20 31 | 
             
                  @mutex = Mutex.new
         | 
| 21 32 | 
             
                end
         | 
| 22 33 |  | 
| 23 | 
            -
                # @!macro [attach]  | 
| 34 | 
            +
                # @!macro [attach] atomic_boolean_method_value_get
         | 
| 24 35 | 
             
                #
         | 
| 25 36 | 
             
                #   Retrieves the current `Boolean` value.
         | 
| 26 37 | 
             
                #
         | 
| @@ -32,7 +43,7 @@ module Concurrent | |
| 32 43 | 
             
                  @mutex.unlock
         | 
| 33 44 | 
             
                end
         | 
| 34 45 |  | 
| 35 | 
            -
                # @!macro [attach]  | 
| 46 | 
            +
                # @!macro [attach] atomic_boolean_method_value_set
         | 
| 36 47 | 
             
                #
         | 
| 37 48 | 
             
                #   Explicitly sets the value.
         | 
| 38 49 | 
             
                #
         | 
| @@ -47,9 +58,9 @@ module Concurrent | |
| 47 58 | 
             
                  @mutex.unlock
         | 
| 48 59 | 
             
                end
         | 
| 49 60 |  | 
| 50 | 
            -
                # @!macro [attach]  | 
| 61 | 
            +
                # @!macro [attach] atomic_boolean_method_true_question
         | 
| 51 62 | 
             
                #
         | 
| 52 | 
            -
                #   Is the current value `true | 
| 63 | 
            +
                #   Is the current value `true`
         | 
| 53 64 | 
             
                #
         | 
| 54 65 | 
             
                #   @return [Boolean] true if the current value is `true`, else false
         | 
| 55 66 | 
             
                def true?
         | 
| @@ -59,9 +70,9 @@ module Concurrent | |
| 59 70 | 
             
                  @mutex.unlock
         | 
| 60 71 | 
             
                end
         | 
| 61 72 |  | 
| 62 | 
            -
                # @!macro  | 
| 73 | 
            +
                # @!macro atomic_boolean_method_false_question
         | 
| 63 74 | 
             
                #
         | 
| 64 | 
            -
                #   Is the current value ` | 
| 75 | 
            +
                #   Is the current value `false`
         | 
| 65 76 | 
             
                #
         | 
| 66 77 | 
             
                #   @return [Boolean] true if the current value is `false`, else false
         | 
| 67 78 | 
             
                def false?
         | 
| @@ -111,24 +122,24 @@ module Concurrent | |
| 111 122 | 
             
                    @atomic = java.util.concurrent.atomic.AtomicBoolean.new(!!initial)
         | 
| 112 123 | 
             
                  end
         | 
| 113 124 |  | 
| 114 | 
            -
                  # @!macro  | 
| 125 | 
            +
                  # @!macro atomic_boolean_method_value_get
         | 
| 115 126 | 
             
                  #
         | 
| 116 127 | 
             
                  def value
         | 
| 117 128 | 
             
                    @atomic.get
         | 
| 118 129 | 
             
                  end
         | 
| 119 130 |  | 
| 120 | 
            -
                  # @!macro  | 
| 131 | 
            +
                  # @!macro atomic_boolean_method_value_set
         | 
| 121 132 | 
             
                  #
         | 
| 122 133 | 
             
                  def value=(value)
         | 
| 123 134 | 
             
                    @atomic.set(!!value)
         | 
| 124 135 | 
             
                  end
         | 
| 125 136 |  | 
| 126 | 
            -
                  # @!macro  | 
| 137 | 
            +
                  # @!macro atomic_boolean_method_true_question
         | 
| 127 138 | 
             
                  def true?
         | 
| 128 139 | 
             
                    @atomic.get
         | 
| 129 140 | 
             
                  end
         | 
| 130 141 |  | 
| 131 | 
            -
                  # @!macro  | 
| 142 | 
            +
                  # @!macro atomic_boolean_method_false_question
         | 
| 132 143 | 
             
                  def false?
         | 
| 133 144 | 
             
                    !@atomic.get
         | 
| 134 145 | 
             
                  end
         | 
| @@ -148,6 +159,37 @@ module Concurrent | |
| 148 159 | 
             
                class AtomicBoolean < JavaAtomicBoolean
         | 
| 149 160 | 
             
                end
         | 
| 150 161 |  | 
| 162 | 
            +
              elsif defined? Concurrent::CAtomicBoolean
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                # @!macro atomic_boolean
         | 
| 165 | 
            +
                class CAtomicBoolean
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                  # @!method initialize
         | 
| 168 | 
            +
                  #   @!macro atomic_boolean_method_initialize
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                  # @!method value
         | 
| 171 | 
            +
                  #   @!macro atomic_boolean_method_value_get
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                  # @!method value=
         | 
| 174 | 
            +
                  #   @!macro atomic_boolean_method_value_set
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                  # @!method true?
         | 
| 177 | 
            +
                  #   @!macro atomic_boolean_method_true_question
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                  # @!method false?
         | 
| 180 | 
            +
                  #   @!macro atomic_boolean_method_false_question
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                  # @!method make_true
         | 
| 183 | 
            +
                  #   @!macro atomic_boolean_method_make_true
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                  # @!method make_false
         | 
| 186 | 
            +
                  #   @!macro atomic_boolean_method_make_false
         | 
| 187 | 
            +
                end
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                # @!macro atomic_boolean
         | 
| 190 | 
            +
                class AtomicBoolean < CAtomicBoolean
         | 
| 191 | 
            +
                end
         | 
| 192 | 
            +
             | 
| 151 193 | 
             
              else
         | 
| 152 194 |  | 
| 153 195 | 
             
                # @!macro atomic_boolean
         | 
| @@ -6,23 +6,38 @@ module Concurrent | |
| 6 6 | 
             
              #   fixnum and thread-safe and guaranteed to succeed. Reads and writes may block
         | 
| 7 7 | 
             
              #   briefly but no explicit locking is required.
         | 
| 8 8 | 
             
              #
         | 
| 9 | 
            -
              # | 
| 9 | 
            +
              #       Testing with ruby 2.1.2
         | 
| 10 | 
            +
              #       Testing with Concurrent::MutexAtomicFixnum...
         | 
| 11 | 
            +
              #         3.130000   0.000000   3.130000 (  3.136505)
         | 
| 12 | 
            +
              #       Testing with Concurrent::CAtomicFixnum...
         | 
| 13 | 
            +
              #         0.790000   0.000000   0.790000 (  0.785550)
         | 
| 14 | 
            +
              #
         | 
| 15 | 
            +
              #       Testing with jruby 1.9.3
         | 
| 16 | 
            +
              #       Testing with Concurrent::MutexAtomicFixnum...
         | 
| 17 | 
            +
              #         5.460000   2.460000   7.920000 (  3.715000)
         | 
| 18 | 
            +
              #       Testing with Concurrent::JavaAtomicFixnum...
         | 
| 19 | 
            +
              #         4.520000   0.030000   4.550000 (  1.187000)
         | 
| 20 | 
            +
              #
         | 
| 10 21 | 
             
              #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicLong.html java.util.concurrent.atomic.AtomicLong
         | 
| 11 22 | 
             
              class MutexAtomicFixnum
         | 
| 12 23 |  | 
| 24 | 
            +
                # http://stackoverflow.com/questions/535721/ruby-max-integer
         | 
| 25 | 
            +
                MIN_VALUE = -(2**(0.size * 8 -2))
         | 
| 26 | 
            +
                MAX_VALUE = (2**(0.size * 8 -2) -1)
         | 
| 27 | 
            +
             | 
| 13 28 | 
             
                # @!macro [attach] atomic_fixnum_method_initialize
         | 
| 14 29 | 
             
                #
         | 
| 15 | 
            -
                # | 
| 30 | 
            +
                #   Creates a new `AtomicFixnum` with the given initial value.
         | 
| 16 31 | 
             
                #
         | 
| 17 | 
            -
                # | 
| 18 | 
            -
                # | 
| 32 | 
            +
                #   @param [Fixnum] init the initial value
         | 
| 33 | 
            +
                #   @raise [ArgumentError] if the initial value is not a `Fixnum`
         | 
| 19 34 | 
             
                def initialize(init = 0)
         | 
| 20 35 | 
             
                  raise ArgumentError.new('initial value must be a Fixnum') unless init.is_a?(Fixnum)
         | 
| 21 36 | 
             
                  @value = init
         | 
| 22 37 | 
             
                  @mutex = Mutex.new
         | 
| 23 38 | 
             
                end
         | 
| 24 39 |  | 
| 25 | 
            -
                # @!macro [attach]  | 
| 40 | 
            +
                # @!macro [attach] atomic_fixnum_method_value_get
         | 
| 26 41 | 
             
                #
         | 
| 27 42 | 
             
                #   Retrieves the current `Fixnum` value.
         | 
| 28 43 | 
             
                #
         | 
| @@ -34,7 +49,7 @@ module Concurrent | |
| 34 49 | 
             
                  @mutex.unlock
         | 
| 35 50 | 
             
                end
         | 
| 36 51 |  | 
| 37 | 
            -
                # @!macro [attach]  | 
| 52 | 
            +
                # @!macro [attach] atomic_fixnum_method_value_set
         | 
| 38 53 | 
             
                #
         | 
| 39 54 | 
             
                #   Explicitly sets the value.
         | 
| 40 55 | 
             
                #
         | 
| @@ -106,44 +121,39 @@ module Concurrent | |
| 106 121 | 
             
                # @!macro atomic_fixnum
         | 
| 107 122 | 
             
                class JavaAtomicFixnum
         | 
| 108 123 |  | 
| 124 | 
            +
                  MIN_VALUE = Java::JavaLang::Long::MIN_VALUE
         | 
| 125 | 
            +
                  MAX_VALUE = Java::JavaLang::Long::MAX_VALUE
         | 
| 126 | 
            +
             | 
| 109 127 | 
             
                  # @!macro atomic_fixnum_method_initialize
         | 
| 110 | 
            -
                  #
         | 
| 111 128 | 
             
                  def initialize(init = 0)
         | 
| 112 129 | 
             
                    raise ArgumentError.new('initial value must be a Fixnum') unless init.is_a?(Fixnum)
         | 
| 113 130 | 
             
                    @atomic = java.util.concurrent.atomic.AtomicLong.new(init)
         | 
| 114 131 | 
             
                  end
         | 
| 115 132 |  | 
| 116 | 
            -
                  # @!macro  | 
| 117 | 
            -
                  #
         | 
| 133 | 
            +
                  # @!macro atomic_fixnum_method_value_get
         | 
| 118 134 | 
             
                  def value
         | 
| 119 135 | 
             
                    @atomic.get
         | 
| 120 136 | 
             
                  end
         | 
| 121 137 |  | 
| 122 | 
            -
                  # @!macro  | 
| 123 | 
            -
                  #
         | 
| 138 | 
            +
                  # @!macro atomic_fixnum_method_value_set
         | 
| 124 139 | 
             
                  def value=(value)
         | 
| 125 140 | 
             
                    raise ArgumentError.new('value must be a Fixnum') unless value.is_a?(Fixnum)
         | 
| 126 141 | 
             
                    @atomic.set(value)
         | 
| 127 142 | 
             
                  end
         | 
| 128 143 |  | 
| 129 144 | 
             
                  # @!macro atomic_fixnum_method_increment
         | 
| 130 | 
            -
                  #
         | 
| 131 145 | 
             
                  def increment
         | 
| 132 146 | 
             
                    @atomic.increment_and_get
         | 
| 133 147 | 
             
                  end
         | 
| 134 | 
            -
             | 
| 135 148 | 
             
                  alias_method :up, :increment
         | 
| 136 149 |  | 
| 137 150 | 
             
                  # @!macro atomic_fixnum_method_decrement
         | 
| 138 | 
            -
                  #
         | 
| 139 151 | 
             
                  def decrement
         | 
| 140 152 | 
             
                    @atomic.decrement_and_get
         | 
| 141 153 | 
             
                  end
         | 
| 142 | 
            -
             | 
| 143 154 | 
             
                  alias_method :down, :decrement
         | 
| 144 155 |  | 
| 145 156 | 
             
                  # @!macro atomic_fixnum_method_compare_and_set
         | 
| 146 | 
            -
                  #
         | 
| 147 157 | 
             
                  def compare_and_set(expect, update)
         | 
| 148 158 | 
             
                    @atomic.compare_and_set(expect, update)
         | 
| 149 159 | 
             
                  end
         | 
| @@ -153,6 +163,34 @@ module Concurrent | |
| 153 163 | 
             
                class AtomicFixnum < JavaAtomicFixnum
         | 
| 154 164 | 
             
                end
         | 
| 155 165 |  | 
| 166 | 
            +
              elsif defined? Concurrent::CAtomicFixnum
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                # @!macro atomic_fixnum
         | 
| 169 | 
            +
                class CAtomicFixnum
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                  # @!method initialize
         | 
| 172 | 
            +
                  #   @!macro atomic_fixnum_method_initialize
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                  # @!method value
         | 
| 175 | 
            +
                  #   @!macro atomic_fixnum_method_value_get
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                  # @!method value=
         | 
| 178 | 
            +
                  #   @!macro atomic_fixnum_method_value_set
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                  # @!method increment
         | 
| 181 | 
            +
                  #   @!macro atomic_fixnum_method_increment
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                  # @!method decrement
         | 
| 184 | 
            +
                  #   @!macro atomic_fixnum_method_decrement
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                  # @!method compare_and_set
         | 
| 187 | 
            +
                  #   @!macro atomic_fixnum_method_compare_and_set
         | 
| 188 | 
            +
                end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                # @!macro atomic_fixnum
         | 
| 191 | 
            +
                class AtomicFixnum < CAtomicFixnum
         | 
| 192 | 
            +
                end
         | 
| 193 | 
            +
             | 
| 156 194 | 
             
              else
         | 
| 157 195 |  | 
| 158 196 | 
             
                # @!macro atomic_fixnum
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            module Concurrent
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              # Safe synchronization under JRuby, prevents reading uninitialized @mutex variable.
         | 
| 4 | 
            +
              # @note synchronized needs to be called in #initialize for this module to work properly
         | 
| 5 | 
            +
              # @example usage
         | 
| 6 | 
            +
              #     class AClass
         | 
| 7 | 
            +
              #       include Synchronized
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              #       def initialize
         | 
| 10 | 
            +
              #         synchronize do
         | 
| 11 | 
            +
              #           # body of the constructor ...
         | 
| 12 | 
            +
              #         end
         | 
| 13 | 
            +
              #       end
         | 
| 14 | 
            +
              #
         | 
| 15 | 
            +
              #       def a_method
         | 
| 16 | 
            +
              #         synchronize do
         | 
| 17 | 
            +
              #           # body of a_method ...
         | 
| 18 | 
            +
              #         end
         | 
| 19 | 
            +
              #       end
         | 
| 20 | 
            +
              #     end
         | 
| 21 | 
            +
              module Synchronization
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                case engine
         | 
| 26 | 
            +
                when 'jruby'
         | 
| 27 | 
            +
                  require 'jruby'
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  def synchronize
         | 
| 30 | 
            +
                    JRuby.reference0(self).synchronized { yield }
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                when 'rbx'
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def synchronize
         | 
| 36 | 
            +
                    Rubinius.lock(self)
         | 
| 37 | 
            +
                    yield
         | 
| 38 | 
            +
                  ensure
         | 
| 39 | 
            +
                    Rubinius.unlock(self)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                else
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  def synchronize
         | 
| 45 | 
            +
                    @mutex ||= Mutex.new
         | 
| 46 | 
            +
                    @mutex.synchronize { yield }
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| @@ -1,54 +1,19 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
              module ThreadLocalSymbolAllocator
         | 
| 4 | 
            -
             | 
| 5 | 
            -
                COUNTER = AtomicFixnum.new
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                protected
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                def allocate_symbol
         | 
| 10 | 
            -
                  # Warning: this symbol may never be deallocated
         | 
| 11 | 
            -
                  @symbol = :"thread_local_symbol_#{COUNTER.increment}"
         | 
| 12 | 
            -
                end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
              end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              module ThreadLocalOldStorage
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                include ThreadLocalSymbolAllocator
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                protected
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                def allocate_storage
         | 
| 23 | 
            -
                  allocate_symbol
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                def get
         | 
| 27 | 
            -
                  Thread.current[@symbol]
         | 
| 28 | 
            -
                end
         | 
| 1 | 
            +
            require 'concurrent/atomic'
         | 
| 29 2 |  | 
| 30 | 
            -
             | 
| 31 | 
            -
                  Thread.current[@symbol] = value
         | 
| 32 | 
            -
                end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
              module ThreadLocalNewStorage
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                include ThreadLocalSymbolAllocator
         | 
| 3 | 
            +
            module Concurrent
         | 
| 39 4 |  | 
| 40 | 
            -
             | 
| 5 | 
            +
              module ThreadLocalRubyStorage
         | 
| 41 6 |  | 
| 42 7 | 
             
                def allocate_storage
         | 
| 43 | 
            -
                   | 
| 8 | 
            +
                  @storage = Atomic.new Hash.new
         | 
| 44 9 | 
             
                end
         | 
| 45 10 |  | 
| 46 11 | 
             
                def get
         | 
| 47 | 
            -
                  Thread.current | 
| 12 | 
            +
                  @storage.get[Thread.current]
         | 
| 48 13 | 
             
                end
         | 
| 49 14 |  | 
| 50 15 | 
             
                def set(value)
         | 
| 51 | 
            -
                  Thread.current | 
| 16 | 
            +
                  @storage.update { |s| s.merge Thread.current => value }
         | 
| 52 17 | 
             
                end
         | 
| 53 18 |  | 
| 54 19 | 
             
              end
         | 
| @@ -71,18 +36,10 @@ module Concurrent | |
| 71 36 |  | 
| 72 37 | 
             
              end
         | 
| 73 38 |  | 
| 74 | 
            -
              class  | 
| 39 | 
            +
              class AbstractThreadLocalVar
         | 
| 75 40 |  | 
| 76 41 | 
             
                NIL_SENTINEL = Object.new
         | 
| 77 42 |  | 
| 78 | 
            -
                if RUBY_PLATFORM == 'java'
         | 
| 79 | 
            -
                  include ThreadLocalJavaStorage
         | 
| 80 | 
            -
                elsif Thread.current.respond_to?(:thread_variable_set)
         | 
| 81 | 
            -
                  include ThreadLocalNewStorage
         | 
| 82 | 
            -
                else
         | 
| 83 | 
            -
                  include ThreadLocalOldStorage
         | 
| 84 | 
            -
                end
         | 
| 85 | 
            -
             | 
| 86 43 | 
             
                def initialize(default = nil)
         | 
| 87 44 | 
             
                  @default = default
         | 
| 88 45 | 
             
                  allocate_storage
         | 
| @@ -114,4 +71,12 @@ module Concurrent | |
| 114 71 |  | 
| 115 72 | 
             
              end
         | 
| 116 73 |  | 
| 74 | 
            +
              class ThreadLocalVar < AbstractThreadLocalVar
         | 
| 75 | 
            +
                if RUBY_PLATFORM == 'java'
         | 
| 76 | 
            +
                  include ThreadLocalJavaStorage
         | 
| 77 | 
            +
                else
         | 
| 78 | 
            +
                  include ThreadLocalRubyStorage
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 117 82 | 
             
            end
         |