concurrent-ruby 1.0.0.pre4-java → 1.0.0.pre5-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 +11 -1
 - data/lib/concurrent/agent.rb +5 -1
 - data/lib/concurrent/async.rb +77 -38
 - data/lib/concurrent/atom.rb +2 -1
 - data/lib/concurrent/atomic/atomic_boolean.rb +1 -1
 - data/lib/concurrent/atomic/atomic_fixnum.rb +1 -1
 - data/lib/concurrent/atomic/atomic_reference.rb +1 -1
 - data/lib/concurrent/atomic/semaphore.rb +1 -1
 - data/lib/concurrent/atomic_reference/jruby+truffle.rb +1 -0
 - data/lib/concurrent/atomic_reference/jruby.rb +1 -1
 - data/lib/concurrent/atomic_reference/ruby.rb +1 -1
 - data/lib/concurrent/concern/dereferenceable.rb +9 -24
 - data/lib/concurrent/concern/obligation.rb +11 -8
 - data/lib/concurrent/delay.rb +1 -1
 - data/lib/concurrent/exchanger.rb +30 -17
 - data/lib/concurrent/executor/ruby_thread_pool_executor.rb +6 -1
 - data/lib/concurrent/ivar.rb +1 -1
 - data/lib/concurrent/lazy_register.rb +11 -8
 - data/lib/concurrent/map.rb +1 -1
 - data/lib/concurrent/maybe.rb +6 -3
 - data/lib/concurrent/mvar.rb +26 -2
 - data/lib/concurrent/promise.rb +1 -1
 - data/lib/concurrent/synchronization.rb +3 -0
 - data/lib/concurrent/synchronization/abstract_lockable_object.rb +1 -20
 - data/lib/concurrent/synchronization/abstract_object.rb +1 -27
 - data/lib/concurrent/synchronization/jruby_object.rb +26 -18
 - data/lib/concurrent/synchronization/lockable_object.rb +29 -16
 - data/lib/concurrent/synchronization/mri_object.rb +27 -19
 - data/lib/concurrent/synchronization/object.rb +48 -53
 - data/lib/concurrent/synchronization/rbx_lockable_object.rb +9 -8
 - data/lib/concurrent/synchronization/rbx_object.rb +29 -21
 - data/lib/concurrent/synchronization/volatile.rb +34 -0
 - data/lib/concurrent/timer_task.rb +0 -1
 - data/lib/concurrent/tvar.rb +3 -1
 - data/lib/concurrent/utility/engine.rb +4 -0
 - data/lib/concurrent/utility/native_extension_loader.rb +6 -3
 - data/lib/concurrent/version.rb +2 -2
 - data/lib/concurrent_ruby_ext.jar +0 -0
 - metadata +7 -5
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 7d7b579740ce1202c660c37eb72e05a0097c49ab
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 37f19da839100f7d8002f64edcbcada96b751ccc
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ef72505a341a9a6b984b4946f754540df39fdba7a052c6dbdd6830ce3e9fedd5856b1e7563592557c3044ec6f30a92e845402bae1aa6447a6f7c93fb5ccb458d
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 29ac27d5f288f2fb6f7fb86894fa83b79a3e837cf3a0623a03d85cc4d00f0076f7fb49ea30ae313fc4d547e935ed2a7eb6903eb0cea1316c280e086631d750c8
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,6 +1,16 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ### Upcoming Release v1.0.0 (TBD)
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            ## Current Release v1.0.0. 
     | 
| 
      
 3 
     | 
    
         
            +
            ## Current Release v1.0.0.pre5 (04 November 2015)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            * Further updates and improvements to the synchronization layer.
         
     | 
| 
      
 6 
     | 
    
         
            +
            * Performance and memory usage performance with `Actor` logging.
         
     | 
| 
      
 7 
     | 
    
         
            +
            * Fixed `ThreadPoolExecutor` task count methods.
         
     | 
| 
      
 8 
     | 
    
         
            +
            * Improved `Async` performance for both short and long-lived objects.
         
     | 
| 
      
 9 
     | 
    
         
            +
            * Fixed bug in `LockFreeLinkedSet`.
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Fixed bug in which `Agent#await` triggered a validation failure.
         
     | 
| 
      
 11 
     | 
    
         
            +
            * Further `Channel` updates.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ### Release v1.0.0.pre4 (08 October 2015)
         
     | 
| 
       4 
14 
     | 
    
         | 
| 
       5 
15 
     | 
    
         
             
            * Adopted a project Code of Conduct
         
     | 
| 
       6 
16 
     | 
    
         
             
            * Cleared interpreter warnings
         
     | 
    
        data/lib/concurrent/agent.rb
    CHANGED
    
    | 
         @@ -166,6 +166,7 @@ module Concurrent 
     | 
|
| 
       166 
166 
     | 
    
         
             
                class Error < StandardError
         
     | 
| 
       167 
167 
     | 
    
         
             
                  def initialize(message = nil)
         
     | 
| 
       168 
168 
     | 
    
         
             
                    message ||= 'agent must be restarted before jobs can post'
         
     | 
| 
      
 169 
     | 
    
         
            +
                    super(message)
         
     | 
| 
       169 
170 
     | 
    
         
             
                  end
         
     | 
| 
       170 
171 
     | 
    
         
             
                end
         
     | 
| 
       171 
172 
     | 
    
         | 
| 
         @@ -174,6 +175,7 @@ module Concurrent 
     | 
|
| 
       174 
175 
     | 
    
         
             
                class ValidationError < Error
         
     | 
| 
       175 
176 
     | 
    
         
             
                  def initialize(message = nil)
         
     | 
| 
       176 
177 
     | 
    
         
             
                    message ||= 'invalid value'
         
     | 
| 
      
 178 
     | 
    
         
            +
                    super(message)
         
     | 
| 
       177 
179 
     | 
    
         
             
                  end
         
     | 
| 
       178 
180 
     | 
    
         
             
                end
         
     | 
| 
       179 
181 
     | 
    
         | 
| 
         @@ -545,7 +547,9 @@ module Concurrent 
     | 
|
| 
       545 
547 
     | 
    
         
             
                  new_value     = job.action.call(old_value, *job.args)
         
     | 
| 
       546 
548 
     | 
    
         
             
                  @caller.value = nil
         
     | 
| 
       547 
549 
     | 
    
         | 
| 
       548 
     | 
    
         
            -
                  if new_value  
     | 
| 
      
 550 
     | 
    
         
            +
                  return if new_value == AWAIT_FLAG
         
     | 
| 
      
 551 
     | 
    
         
            +
             
     | 
| 
      
 552 
     | 
    
         
            +
                  if ns_validate(new_value)
         
     | 
| 
       549 
553 
     | 
    
         
             
                    @current.value = new_value
         
     | 
| 
       550 
554 
     | 
    
         
             
                    observers.notify_observers(Time.now, old_value, new_value)
         
     | 
| 
       551 
555 
     | 
    
         
             
                  else
         
     | 
    
        data/lib/concurrent/async.rb
    CHANGED
    
    | 
         @@ -1,5 +1,6 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'concurrent/configuration'
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'concurrent/ivar'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'concurrent/ 
     | 
| 
      
 3 
     | 
    
         
            +
            require 'concurrent/synchronization/lockable_object'
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
       4 
5 
     | 
    
         
             
            module Concurrent
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
         @@ -10,14 +11,14 @@ module Concurrent 
     | 
|
| 
       10 
11 
     | 
    
         
             
              #
         
     | 
| 
       11 
12 
     | 
    
         
             
              # A more feature-rich {Concurrent::Actor} is also available when the
         
     | 
| 
       12 
13 
     | 
    
         
             
              # capabilities of `Async` are too limited.
         
     | 
| 
       13 
     | 
    
         
            -
              # 
     | 
| 
      
 14 
     | 
    
         
            +
              #
         
     | 
| 
       14 
15 
     | 
    
         
             
              # ```cucumber
         
     | 
| 
       15 
16 
     | 
    
         
             
              # Feature:
         
     | 
| 
       16 
17 
     | 
    
         
             
              #   As a stateful, plain old Ruby class
         
     | 
| 
       17 
18 
     | 
    
         
             
              #   I want safe, asynchronous behavior
         
     | 
| 
       18 
19 
     | 
    
         
             
              #   So my long-running methods don't block the main thread
         
     | 
| 
       19 
20 
     | 
    
         
             
              # ```
         
     | 
| 
       20 
     | 
    
         
            -
              # 
     | 
| 
      
 21 
     | 
    
         
            +
              #
         
     | 
| 
       21 
22 
     | 
    
         
             
              # The `Async` module is a way to mix simple yet powerful asynchronous
         
     | 
| 
       22 
23 
     | 
    
         
             
              # capabilities into any plain old Ruby object or class, turning each object
         
     | 
| 
       23 
24 
     | 
    
         
             
              # into a simple Actor. Method calls are processed on a background thread. The
         
     | 
| 
         @@ -37,14 +38,13 @@ module Concurrent 
     | 
|
| 
       37 
38 
     | 
    
         
             
              # send messages to the `gen_server` via the `cast` and `call` methods. Unlike
         
     | 
| 
       38 
39 
     | 
    
         
             
              # Erlang's `gen_server`, however, `Async` classes do not support linking or
         
     | 
| 
       39 
40 
     | 
    
         
             
              # supervision trees.
         
     | 
| 
       40 
     | 
    
         
            -
              # 
     | 
| 
      
 41 
     | 
    
         
            +
              #
         
     | 
| 
       41 
42 
     | 
    
         
             
              # ## Basic Usage
         
     | 
| 
       42 
43 
     | 
    
         
             
              #
         
     | 
| 
       43 
44 
     | 
    
         
             
              # When this module is mixed into a class, objects of the class become inherently
         
     | 
| 
       44 
     | 
    
         
            -
              # asynchronous. Each object gets its own background thread  
     | 
| 
       45 
     | 
    
         
            -
              #  
     | 
| 
       46 
     | 
    
         
            -
              #  
     | 
| 
       47 
     | 
    
         
            -
              # the order they are received.
         
     | 
| 
      
 45 
     | 
    
         
            +
              # asynchronous. Each object gets its own background thread on which to post
         
     | 
| 
      
 46 
     | 
    
         
            +
              # asynchronous method calls. Asynchronous method calls are executed in the
         
     | 
| 
      
 47 
     | 
    
         
            +
              # background one at a time in the order they are received.
         
     | 
| 
       48 
48 
     | 
    
         
             
              #
         
     | 
| 
       49 
49 
     | 
    
         
             
              # To create an asynchronous class, simply mix in the `Concurrent::Async` module:
         
     | 
| 
       50 
50 
     | 
    
         
             
              #
         
     | 
| 
         @@ -200,30 +200,30 @@ module Concurrent 
     | 
|
| 
       200 
200 
     | 
    
         
             
              #
         
     | 
| 
       201 
201 
     | 
    
         
             
              # Class methods which are pure functions are safe. Class methods which modify
         
     | 
| 
       202 
202 
     | 
    
         
             
              # class variables should be avoided, for all the reasons listed above.
         
     | 
| 
       203 
     | 
    
         
            -
              # 
     | 
| 
      
 203 
     | 
    
         
            +
              #
         
     | 
| 
       204 
204 
     | 
    
         
             
              # ## An Important Note About Thread Safe Guarantees
         
     | 
| 
       205 
     | 
    
         
            -
              # 
     | 
| 
      
 205 
     | 
    
         
            +
              #
         
     | 
| 
       206 
206 
     | 
    
         
             
              # > Thread safe guarantees can only be made when asynchronous method calls
         
     | 
| 
       207 
207 
     | 
    
         
             
              # > are not mixed with direct method calls. Use only direct method calls
         
     | 
| 
       208 
208 
     | 
    
         
             
              # > when the object is used exclusively on a single thread. Use only
         
     | 
| 
       209 
209 
     | 
    
         
             
              # > `async` and `await` when the object is shared between threads. Once you
         
     | 
| 
       210 
210 
     | 
    
         
             
              # > call a method using `async` or `await`, you should no longer call methods
         
     | 
| 
       211 
211 
     | 
    
         
             
              # > directly on the object. Use `async` and `await` exclusively from then on.
         
     | 
| 
       212 
     | 
    
         
            -
              # 
     | 
| 
      
 212 
     | 
    
         
            +
              #
         
     | 
| 
       213 
213 
     | 
    
         
             
              # @example
         
     | 
| 
       214 
     | 
    
         
            -
              # 
     | 
| 
      
 214 
     | 
    
         
            +
              #
         
     | 
| 
       215 
215 
     | 
    
         
             
              #   class Echo
         
     | 
| 
       216 
216 
     | 
    
         
             
              #     include Concurrent::Async
         
     | 
| 
       217 
     | 
    
         
            -
              # 
     | 
| 
      
 217 
     | 
    
         
            +
              #
         
     | 
| 
       218 
218 
     | 
    
         
             
              #     def echo(msg)
         
     | 
| 
       219 
219 
     | 
    
         
             
              #       print "#{msg}\n"
         
     | 
| 
       220 
220 
     | 
    
         
             
              #     end
         
     | 
| 
       221 
221 
     | 
    
         
             
              #   end
         
     | 
| 
       222 
     | 
    
         
            -
              # 
     | 
| 
      
 222 
     | 
    
         
            +
              #
         
     | 
| 
       223 
223 
     | 
    
         
             
              #   horn = Echo.new
         
     | 
| 
       224 
224 
     | 
    
         
             
              #   horn.echo('zero')      # synchronous, not thread-safe
         
     | 
| 
       225 
225 
     | 
    
         
             
              #                          # returns the actual return value of the method
         
     | 
| 
       226 
     | 
    
         
            -
              # 
     | 
| 
      
 226 
     | 
    
         
            +
              #
         
     | 
| 
       227 
227 
     | 
    
         
             
              #   horn.async.echo('one') # asynchronous, non-blocking, thread-safe
         
     | 
| 
       228 
228 
     | 
    
         
             
              #                          # returns an IVar in the :pending state
         
     | 
| 
       229 
229 
     | 
    
         
             
              #
         
     | 
| 
         @@ -231,7 +231,6 @@ module Concurrent 
     | 
|
| 
       231 
231 
     | 
    
         
             
              #                          # returns an IVar in the :complete state
         
     | 
| 
       232 
232 
     | 
    
         
             
              #
         
     | 
| 
       233 
233 
     | 
    
         
             
              # @see Concurrent::Actor
         
     | 
| 
       234 
     | 
    
         
            -
              # @see Concurrent::SingleThreadExecutor
         
     | 
| 
       235 
234 
     | 
    
         
             
              # @see https://en.wikipedia.org/wiki/Actor_model "Actor Model" at Wikipedia
         
     | 
| 
       236 
235 
     | 
    
         
             
              # @see http://www.erlang.org/doc/man/gen_server.html Erlang gen_server
         
     | 
| 
       237 
236 
     | 
    
         
             
              # @see http://c2.com/cgi/wiki?LetItCrash "Let It Crash" at http://c2.com/
         
     | 
| 
         @@ -299,24 +298,20 @@ module Concurrent 
     | 
|
| 
       299 
298 
     | 
    
         
             
                # Delegates asynchronous, thread-safe method calls to the wrapped object.
         
     | 
| 
       300 
299 
     | 
    
         
             
                #
         
     | 
| 
       301 
300 
     | 
    
         
             
                # @!visibility private
         
     | 
| 
       302 
     | 
    
         
            -
                class AsyncDelegator
         
     | 
| 
      
 301 
     | 
    
         
            +
                class AsyncDelegator < Synchronization::LockableObject
         
     | 
| 
      
 302 
     | 
    
         
            +
                  safe_initialization!
         
     | 
| 
       303 
303 
     | 
    
         | 
| 
       304 
     | 
    
         
            -
                  # Create a new delegator object wrapping the given delegate 
     | 
| 
       305 
     | 
    
         
            -
                  # protecting it with the given serializer, and executing it on the
         
     | 
| 
       306 
     | 
    
         
            -
                  # given executor. Block if necessary.
         
     | 
| 
      
 304 
     | 
    
         
            +
                  # Create a new delegator object wrapping the given delegate.
         
     | 
| 
       307 
305 
     | 
    
         
             
                  #
         
     | 
| 
       308 
306 
     | 
    
         
             
                  # @param [Object] delegate the object to wrap and delegate method calls to
         
     | 
| 
       309 
     | 
    
         
            -
                   
     | 
| 
       310 
     | 
    
         
            -
             
     | 
| 
       311 
     | 
    
         
            -
                  def initialize(delegate, executor, blocking)
         
     | 
| 
      
 307 
     | 
    
         
            +
                  def initialize(delegate)
         
     | 
| 
      
 308 
     | 
    
         
            +
                    super()
         
     | 
| 
       312 
309 
     | 
    
         
             
                    @delegate = delegate
         
     | 
| 
       313 
     | 
    
         
            -
                    @ 
     | 
| 
       314 
     | 
    
         
            -
                    @ 
     | 
| 
      
 310 
     | 
    
         
            +
                    @queue = []
         
     | 
| 
      
 311 
     | 
    
         
            +
                    @executor = Concurrent.global_io_executor
         
     | 
| 
       315 
312 
     | 
    
         
             
                  end
         
     | 
| 
       316 
313 
     | 
    
         | 
| 
       317 
     | 
    
         
            -
                  # Delegates method calls to the wrapped object. 
     | 
| 
       318 
     | 
    
         
            -
                  # dynamically defines the given method on the delegator so that
         
     | 
| 
       319 
     | 
    
         
            -
                  # all future calls to `method` will not be directed here.
         
     | 
| 
      
 314 
     | 
    
         
            +
                  # Delegates method calls to the wrapped object.
         
     | 
| 
       320 
315 
     | 
    
         
             
                  #
         
     | 
| 
       321 
316 
     | 
    
         
             
                  # @param [Symbol] method the method being called
         
     | 
| 
       322 
317 
     | 
    
         
             
                  # @param [Array] args zero or more arguments to the method
         
     | 
| 
         @@ -330,19 +325,67 @@ module Concurrent 
     | 
|
| 
       330 
325 
     | 
    
         
             
                    Async::validate_argc(@delegate, method, *args)
         
     | 
| 
       331 
326 
     | 
    
         | 
| 
       332 
327 
     | 
    
         
             
                    ivar = Concurrent::IVar.new
         
     | 
| 
       333 
     | 
    
         
            -
                     
     | 
| 
      
 328 
     | 
    
         
            +
                    synchronize do
         
     | 
| 
      
 329 
     | 
    
         
            +
                      @queue.push [ivar, method, args, block]
         
     | 
| 
      
 330 
     | 
    
         
            +
                      @executor.post { perform } if @queue.length == 1
         
     | 
| 
      
 331 
     | 
    
         
            +
                    end
         
     | 
| 
      
 332 
     | 
    
         
            +
             
     | 
| 
      
 333 
     | 
    
         
            +
                    ivar
         
     | 
| 
      
 334 
     | 
    
         
            +
                  end
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
                  # Perform all enqueued tasks.
         
     | 
| 
      
 337 
     | 
    
         
            +
                  #
         
     | 
| 
      
 338 
     | 
    
         
            +
                  # This method must be called from within the executor. It must not be
         
     | 
| 
      
 339 
     | 
    
         
            +
                  # called while already running. It will loop until the queue is empty.
         
     | 
| 
      
 340 
     | 
    
         
            +
                  def perform
         
     | 
| 
      
 341 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 342 
     | 
    
         
            +
                      ivar, method, args, block = synchronize { @queue.first }
         
     | 
| 
      
 343 
     | 
    
         
            +
                      break unless ivar # queue is empty
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
       334 
345 
     | 
    
         
             
                      begin
         
     | 
| 
       335 
     | 
    
         
            -
                        ivar.set(@delegate.send(method, * 
     | 
| 
      
 346 
     | 
    
         
            +
                        ivar.set(@delegate.send(method, *args, &block))
         
     | 
| 
       336 
347 
     | 
    
         
             
                      rescue => error
         
     | 
| 
       337 
348 
     | 
    
         
             
                        ivar.fail(error)
         
     | 
| 
       338 
349 
     | 
    
         
             
                      end
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
                      synchronize do
         
     | 
| 
      
 352 
     | 
    
         
            +
                        @queue.shift
         
     | 
| 
      
 353 
     | 
    
         
            +
                        return if @queue.empty?
         
     | 
| 
      
 354 
     | 
    
         
            +
                      end
         
     | 
| 
       339 
355 
     | 
    
         
             
                    end
         
     | 
| 
       340 
     | 
    
         
            -
                    ivar.wait if @blocking
         
     | 
| 
       341 
     | 
    
         
            -
                    ivar
         
     | 
| 
       342 
356 
     | 
    
         
             
                  end
         
     | 
| 
       343 
357 
     | 
    
         
             
                end
         
     | 
| 
       344 
358 
     | 
    
         
             
                private_constant :AsyncDelegator
         
     | 
| 
       345 
359 
     | 
    
         | 
| 
      
 360 
     | 
    
         
            +
                # Delegates synchronous, thread-safe method calls to the wrapped object.
         
     | 
| 
      
 361 
     | 
    
         
            +
                #
         
     | 
| 
      
 362 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
      
 363 
     | 
    
         
            +
                class AwaitDelegator
         
     | 
| 
      
 364 
     | 
    
         
            +
             
     | 
| 
      
 365 
     | 
    
         
            +
                  # Create a new delegator object wrapping the given delegate.
         
     | 
| 
      
 366 
     | 
    
         
            +
                  #
         
     | 
| 
      
 367 
     | 
    
         
            +
                  # @param [AsyncDelegator] delegate the object to wrap and delegate method calls to
         
     | 
| 
      
 368 
     | 
    
         
            +
                  def initialize(delegate)
         
     | 
| 
      
 369 
     | 
    
         
            +
                    @delegate = delegate
         
     | 
| 
      
 370 
     | 
    
         
            +
                  end
         
     | 
| 
      
 371 
     | 
    
         
            +
             
     | 
| 
      
 372 
     | 
    
         
            +
                  # Delegates method calls to the wrapped object.
         
     | 
| 
      
 373 
     | 
    
         
            +
                  #
         
     | 
| 
      
 374 
     | 
    
         
            +
                  # @param [Symbol] method the method being called
         
     | 
| 
      
 375 
     | 
    
         
            +
                  # @param [Array] args zero or more arguments to the method
         
     | 
| 
      
 376 
     | 
    
         
            +
                  #
         
     | 
| 
      
 377 
     | 
    
         
            +
                  # @return [IVar] the result of the method call
         
     | 
| 
      
 378 
     | 
    
         
            +
                  #
         
     | 
| 
      
 379 
     | 
    
         
            +
                  # @raise [NameError] the object does not respond to `method` method
         
     | 
| 
      
 380 
     | 
    
         
            +
                  # @raise [ArgumentError] the given `args` do not match the arity of `method`
         
     | 
| 
      
 381 
     | 
    
         
            +
                  def method_missing(method, *args, &block)
         
     | 
| 
      
 382 
     | 
    
         
            +
                    ivar = @delegate.send(method, *args, &block)
         
     | 
| 
      
 383 
     | 
    
         
            +
                    ivar.wait
         
     | 
| 
      
 384 
     | 
    
         
            +
                    ivar
         
     | 
| 
      
 385 
     | 
    
         
            +
                  end
         
     | 
| 
      
 386 
     | 
    
         
            +
                end
         
     | 
| 
      
 387 
     | 
    
         
            +
                private_constant :AwaitDelegator
         
     | 
| 
      
 388 
     | 
    
         
            +
             
     | 
| 
       346 
389 
     | 
    
         
             
                # Causes the chained method call to be performed asynchronously on the
         
     | 
| 
       347 
390 
     | 
    
         
             
                # object's thread. The delegated method will return a future in the
         
     | 
| 
       348 
391 
     | 
    
         
             
                # `:pending` state and the method call will have been scheduled on the
         
     | 
| 
         @@ -385,8 +428,6 @@ module Concurrent 
     | 
|
| 
       385 
428 
     | 
    
         
             
                end
         
     | 
| 
       386 
429 
     | 
    
         
             
                alias_method :call, :await
         
     | 
| 
       387 
430 
     | 
    
         | 
| 
       388 
     | 
    
         
            -
                private
         
     | 
| 
       389 
     | 
    
         
            -
             
     | 
| 
       390 
431 
     | 
    
         
             
                # Initialize the internal serializer and other stnchronization mechanisms.
         
     | 
| 
       391 
432 
     | 
    
         
             
                #
         
     | 
| 
       392 
433 
     | 
    
         
             
                # @note This method *must* be called immediately upon object construction.
         
     | 
| 
         @@ -396,10 +437,8 @@ module Concurrent 
     | 
|
| 
       396 
437 
     | 
    
         
             
                def init_synchronization
         
     | 
| 
       397 
438 
     | 
    
         
             
                  return self if @__async_initialized__
         
     | 
| 
       398 
439 
     | 
    
         
             
                  @__async_initialized__ = true
         
     | 
| 
       399 
     | 
    
         
            -
                  @ 
     | 
| 
       400 
     | 
    
         
            -
             
     | 
| 
       401 
     | 
    
         
            -
                  @__await_delegator__ = AsyncDelegator.new(self, @__async_executor__, true)
         
     | 
| 
       402 
     | 
    
         
            -
                  @__async_delegator__ = AsyncDelegator.new(self, @__async_executor__, false)
         
     | 
| 
      
 440 
     | 
    
         
            +
                  @__async_delegator__ = AsyncDelegator.new(self)
         
     | 
| 
      
 441 
     | 
    
         
            +
                  @__await_delegator__ = AwaitDelegator.new(@__async_delegator__)
         
     | 
| 
       403 
442 
     | 
    
         
             
                  self
         
     | 
| 
       404 
443 
     | 
    
         
             
                end
         
     | 
| 
       405 
444 
     | 
    
         
             
              end
         
     | 
    
        data/lib/concurrent/atom.rb
    CHANGED
    
    | 
         @@ -111,9 +111,10 @@ module Concurrent 
     | 
|
| 
       111 
111 
     | 
    
         
             
                #
         
     | 
| 
       112 
112 
     | 
    
         
             
                # @raise [ArgumentError] if the validator is not a `Proc` (when given)
         
     | 
| 
       113 
113 
     | 
    
         
             
                def initialize(value, opts = {})
         
     | 
| 
      
 114 
     | 
    
         
            +
                  super()
         
     | 
| 
       114 
115 
     | 
    
         
             
                  @Validator     = opts.fetch(:validator, -> v { true })
         
     | 
| 
       115 
116 
     | 
    
         
             
                  self.observers = Collection::CopyOnNotifyObserverSet.new
         
     | 
| 
       116 
     | 
    
         
            -
                   
     | 
| 
      
 117 
     | 
    
         
            +
                  self.value     = value
         
     | 
| 
       117 
118 
     | 
    
         
             
                end
         
     | 
| 
       118 
119 
     | 
    
         | 
| 
       119 
120 
     | 
    
         
             
                # @!method value
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'concurrent/atomic_reference/rbx'
         
     | 
| 
         @@ -9,13 +9,17 @@ module Concurrent 
     | 
|
| 
       9 
9 
     | 
    
         
             
                #
         
     | 
| 
       10 
10 
     | 
    
         
             
                # @!macro copy_options
         
     | 
| 
       11 
11 
     | 
    
         
             
                module Dereferenceable
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # NOTE: This module is going away in 2.0. In the mean time we need it to
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # play nicely with the synchronization layer. This means that the
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # including class SHOULD be synchronized and it MUST implement a
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # `#synchronize` method. Not doing so will lead to runtime errors.
         
     | 
| 
       12 
16 
     | 
    
         | 
| 
       13 
17 
     | 
    
         
             
                  # Return the value this object represents after applying the options specified
         
     | 
| 
       14 
18 
     | 
    
         
             
                  # by the `#set_deref_options` method.
         
     | 
| 
       15 
19 
     | 
    
         
             
                  #
         
     | 
| 
       16 
20 
     | 
    
         
             
                  # @return [Object] the current value of the object
         
     | 
| 
       17 
21 
     | 
    
         
             
                  def value
         
     | 
| 
       18 
     | 
    
         
            -
                     
     | 
| 
      
 22 
     | 
    
         
            +
                    synchronize { apply_deref_options(@value) }
         
     | 
| 
       19 
23 
     | 
    
         
             
                  end
         
     | 
| 
       20 
24 
     | 
    
         
             
                  alias_method :deref, :value
         
     | 
| 
       21 
25 
     | 
    
         | 
| 
         @@ -25,43 +29,24 @@ module Concurrent 
     | 
|
| 
       25 
29 
     | 
    
         
             
                  #
         
     | 
| 
       26 
30 
     | 
    
         
             
                  # @param [Object] value the new value
         
     | 
| 
       27 
31 
     | 
    
         
             
                  def value=(value)
         
     | 
| 
       28 
     | 
    
         
            -
                     
     | 
| 
       29 
     | 
    
         
            -
                  end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                  # A mutex lock used for synchronizing thread-safe operations. Methods defined
         
     | 
| 
       32 
     | 
    
         
            -
                  # by `Dereferenceable` are synchronized using the `Mutex` returned from this
         
     | 
| 
       33 
     | 
    
         
            -
                  # method. Operations performed by the including class that operate on the
         
     | 
| 
       34 
     | 
    
         
            -
                  # `@value` instance variable should be locked with this `Mutex`.
         
     | 
| 
       35 
     | 
    
         
            -
                  #
         
     | 
| 
       36 
     | 
    
         
            -
                  # @return [Mutex] the synchronization object
         
     | 
| 
       37 
     | 
    
         
            -
                  def mutex
         
     | 
| 
       38 
     | 
    
         
            -
                    @mutex
         
     | 
| 
       39 
     | 
    
         
            -
                  end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                  # Initializes the internal `Mutex`.
         
     | 
| 
       42 
     | 
    
         
            -
                  #
         
     | 
| 
       43 
     | 
    
         
            -
                  # @note This method *must* be called from within the constructor of the including class.
         
     | 
| 
       44 
     | 
    
         
            -
                  #
         
     | 
| 
       45 
     | 
    
         
            -
                  # @see #mutex
         
     | 
| 
       46 
     | 
    
         
            -
                  def init_mutex(mutex = Mutex.new)
         
     | 
| 
       47 
     | 
    
         
            -
                    @mutex = mutex
         
     | 
| 
      
 32 
     | 
    
         
            +
                    synchronize{ @value = value }
         
     | 
| 
       48 
33 
     | 
    
         
             
                  end
         
     | 
| 
       49 
34 
     | 
    
         | 
| 
       50 
35 
     | 
    
         
             
                  # @!macro [attach] dereferenceable_set_deref_options
         
     | 
| 
       51 
36 
     | 
    
         
             
                  #   Set the options which define the operations #value performs before
         
     | 
| 
       52 
37 
     | 
    
         
             
                  #   returning data to the caller (dereferencing).
         
     | 
| 
       53 
     | 
    
         
            -
                  # 
     | 
| 
      
 38 
     | 
    
         
            +
                  #
         
     | 
| 
       54 
39 
     | 
    
         
             
                  #   @note Most classes that include this module will call `#set_deref_options`
         
     | 
| 
       55 
40 
     | 
    
         
             
                  #   from within the constructor, thus allowing these options to be set at
         
     | 
| 
       56 
41 
     | 
    
         
             
                  #   object creation.
         
     | 
| 
       57 
     | 
    
         
            -
                  # 
     | 
| 
      
 42 
     | 
    
         
            +
                  #
         
     | 
| 
       58 
43 
     | 
    
         
             
                  #   @param [Hash] opts the options defining dereference behavior.
         
     | 
| 
       59 
44 
     | 
    
         
             
                  #   @option opts [String] :dup_on_deref (false) call `#dup` before returning the data
         
     | 
| 
       60 
45 
     | 
    
         
             
                  #   @option opts [String] :freeze_on_deref (false) call `#freeze` before returning the data
         
     | 
| 
       61 
46 
     | 
    
         
             
                  #   @option opts [String] :copy_on_deref (nil) call the given `Proc` passing
         
     | 
| 
       62 
47 
     | 
    
         
             
                  #     the internal value and returning the value returned from the proc
         
     | 
| 
       63 
48 
     | 
    
         
             
                  def set_deref_options(opts = {})
         
     | 
| 
       64 
     | 
    
         
            -
                     
     | 
| 
      
 49 
     | 
    
         
            +
                    synchronize{ ns_set_deref_options(opts) }
         
     | 
| 
       65 
50 
     | 
    
         
             
                  end
         
     | 
| 
       66 
51 
     | 
    
         | 
| 
       67 
52 
     | 
    
         
             
                  # @!macro dereferenceable_set_deref_options
         
     | 
| 
         @@ -9,6 +9,10 @@ module Concurrent 
     | 
|
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
                module Obligation
         
     | 
| 
       11 
11 
     | 
    
         
             
                  include Concern::Dereferenceable
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # NOTE: The Dereferenceable module is going away in 2.0. In the mean time
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # we need it to place nicely with the synchronization layer. This means
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # that the including class SHOULD be synchronized and it MUST implement a
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # `#synchronize` method. Not doing so will lead to runtime errors.
         
     | 
| 
       12 
16 
     | 
    
         | 
| 
       13 
17 
     | 
    
         
             
                  # Has the obligation been fulfilled?
         
     | 
| 
       14 
18 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -104,7 +108,7 @@ module Concurrent 
     | 
|
| 
       104 
108 
     | 
    
         
             
                  #
         
     | 
| 
       105 
109 
     | 
    
         
             
                  # @return [Symbol] the current state
         
     | 
| 
       106 
110 
     | 
    
         
             
                  def state
         
     | 
| 
       107 
     | 
    
         
            -
                     
     | 
| 
      
 111 
     | 
    
         
            +
                    synchronize { @state }
         
     | 
| 
       108 
112 
     | 
    
         
             
                  end
         
     | 
| 
       109 
113 
     | 
    
         | 
| 
       110 
114 
     | 
    
         
             
                  # If an exception was raised during processing this will return the
         
     | 
| 
         @@ -113,7 +117,7 @@ module Concurrent 
     | 
|
| 
       113 
117 
     | 
    
         
             
                  #
         
     | 
| 
       114 
118 
     | 
    
         
             
                  # @return [Exception] the exception raised during processing or `nil`
         
     | 
| 
       115 
119 
     | 
    
         
             
                  def reason
         
     | 
| 
       116 
     | 
    
         
            -
                     
     | 
| 
      
 120 
     | 
    
         
            +
                    synchronize { @reason }
         
     | 
| 
       117 
121 
     | 
    
         
             
                  end
         
     | 
| 
       118 
122 
     | 
    
         | 
| 
       119 
123 
     | 
    
         
             
                  # @example allows Obligation to be risen
         
     | 
| 
         @@ -132,8 +136,7 @@ module Concurrent 
     | 
|
| 
       132 
136 
     | 
    
         
             
                  end
         
     | 
| 
       133 
137 
     | 
    
         | 
| 
       134 
138 
     | 
    
         
             
                  # @!visibility private
         
     | 
| 
       135 
     | 
    
         
            -
                  def init_obligation 
     | 
| 
       136 
     | 
    
         
            -
                    init_mutex(*args)
         
     | 
| 
      
 139 
     | 
    
         
            +
                  def init_obligation
         
     | 
| 
       137 
140 
     | 
    
         
             
                    @event = Event.new
         
     | 
| 
       138 
141 
     | 
    
         
             
                  end
         
     | 
| 
       139 
142 
     | 
    
         | 
| 
         @@ -155,7 +158,7 @@ module Concurrent 
     | 
|
| 
       155 
158 
     | 
    
         | 
| 
       156 
159 
     | 
    
         
             
                  # @!visibility private
         
     | 
| 
       157 
160 
     | 
    
         
             
                  def state=(value)
         
     | 
| 
       158 
     | 
    
         
            -
                     
     | 
| 
      
 161 
     | 
    
         
            +
                    synchronize { ns_set_state(value) }
         
     | 
| 
       159 
162 
     | 
    
         
             
                  end
         
     | 
| 
       160 
163 
     | 
    
         | 
| 
       161 
164 
     | 
    
         
             
                  # Atomic compare and set operation
         
     | 
| 
         @@ -163,12 +166,12 @@ module Concurrent 
     | 
|
| 
       163 
166 
     | 
    
         
             
                  #
         
     | 
| 
       164 
167 
     | 
    
         
             
                  # @param [Symbol] next_state
         
     | 
| 
       165 
168 
     | 
    
         
             
                  # @param [Symbol] expected_current
         
     | 
| 
       166 
     | 
    
         
            -
                  # 
     | 
| 
      
 169 
     | 
    
         
            +
                  #
         
     | 
| 
       167 
170 
     | 
    
         
             
                  # @return [Boolean] true is state is changed, false otherwise
         
     | 
| 
       168 
171 
     | 
    
         
             
                  #
         
     | 
| 
       169 
172 
     | 
    
         
             
                  # @!visibility private
         
     | 
| 
       170 
173 
     | 
    
         
             
                  def compare_and_set_state(next_state, *expected_current)
         
     | 
| 
       171 
     | 
    
         
            -
                     
     | 
| 
      
 174 
     | 
    
         
            +
                    synchronize do
         
     | 
| 
       172 
175 
     | 
    
         
             
                      if expected_current.include? @state
         
     | 
| 
       173 
176 
     | 
    
         
             
                        @state = next_state
         
     | 
| 
       174 
177 
     | 
    
         
             
                        true
         
     | 
| 
         @@ -184,7 +187,7 @@ module Concurrent 
     | 
|
| 
       184 
187 
     | 
    
         
             
                  #
         
     | 
| 
       185 
188 
     | 
    
         
             
                  # @!visibility private
         
     | 
| 
       186 
189 
     | 
    
         
             
                  def if_state(*expected_states)
         
     | 
| 
       187 
     | 
    
         
            -
                     
     | 
| 
      
 190 
     | 
    
         
            +
                    synchronize do
         
     | 
| 
       188 
191 
     | 
    
         
             
                      raise ArgumentError.new('no block given') unless block_given?
         
     | 
| 
       189 
192 
     | 
    
         | 
| 
       190 
193 
     | 
    
         
             
                      if expected_states.include? @state
         
     |