concurrent-ruby 1.0.5 → 1.1.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +42 -0
- data/Gemfile +39 -0
- data/{LICENSE.txt → LICENSE.md} +2 -0
- data/README.md +203 -105
- data/Rakefile +278 -0
- data/ext/concurrent-ruby/ConcurrentRubyService.java +17 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +175 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +248 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +93 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +113 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +159 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +304 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +31 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +3863 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +203 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +342 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +3800 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +204 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +291 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +199 -0
- data/lib/concurrent-ruby.rb +1 -0
- data/lib/concurrent.rb +24 -20
- data/lib/concurrent/agent.rb +7 -7
- data/lib/concurrent/array.rb +59 -32
- data/lib/concurrent/async.rb +4 -4
- data/lib/concurrent/atom.rb +9 -9
- data/lib/concurrent/atomic/atomic_boolean.rb +24 -20
- data/lib/concurrent/atomic/atomic_fixnum.rb +27 -23
- data/lib/concurrent/atomic/atomic_markable_reference.rb +164 -0
- data/lib/concurrent/atomic/atomic_reference.rb +176 -33
- data/lib/concurrent/atomic/count_down_latch.rb +6 -6
- data/lib/concurrent/atomic/cyclic_barrier.rb +1 -1
- data/lib/concurrent/atomic/event.rb +1 -1
- data/lib/concurrent/atomic/java_count_down_latch.rb +6 -5
- data/lib/concurrent/atomic/mutex_count_down_latch.rb +1 -0
- data/lib/concurrent/atomic/read_write_lock.rb +2 -1
- data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
- data/lib/concurrent/atomic/semaphore.rb +8 -8
- data/lib/concurrent/atomic/thread_local_var.rb +7 -7
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +3 -8
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +1 -1
- data/lib/concurrent/atomics.rb +0 -43
- data/lib/concurrent/collection/lock_free_stack.rb +127 -0
- data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +3 -3
- data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +1 -2
- data/lib/concurrent/collection/non_concurrent_priority_queue.rb +29 -29
- data/lib/concurrent/concern/dereferenceable.rb +1 -1
- data/lib/concurrent/concern/logging.rb +6 -1
- data/lib/concurrent/concern/observable.rb +7 -7
- data/lib/concurrent/concurrent_ruby.jar +0 -0
- data/lib/concurrent/configuration.rb +1 -6
- data/lib/concurrent/constants.rb +1 -1
- data/lib/concurrent/dataflow.rb +2 -1
- data/lib/concurrent/delay.rb +9 -7
- data/lib/concurrent/exchanger.rb +13 -21
- data/lib/concurrent/executor/abstract_executor_service.rb +2 -2
- data/lib/concurrent/executor/cached_thread_pool.rb +1 -1
- data/lib/concurrent/executor/executor_service.rb +15 -15
- data/lib/concurrent/executor/fixed_thread_pool.rb +18 -18
- data/lib/concurrent/executor/java_thread_pool_executor.rb +10 -7
- data/lib/concurrent/executor/single_thread_executor.rb +2 -2
- data/lib/concurrent/executor/thread_pool_executor.rb +6 -6
- data/lib/concurrent/executor/timer_set.rb +1 -1
- data/lib/concurrent/future.rb +4 -1
- data/lib/concurrent/hash.rb +53 -30
- data/lib/concurrent/ivar.rb +5 -6
- data/lib/concurrent/map.rb +20 -25
- data/lib/concurrent/maybe.rb +1 -1
- data/lib/concurrent/mutable_struct.rb +15 -14
- data/lib/concurrent/mvar.rb +2 -2
- data/lib/concurrent/promise.rb +53 -21
- data/lib/concurrent/promises.rb +1938 -0
- data/lib/concurrent/re_include.rb +58 -0
- data/lib/concurrent/set.rb +66 -0
- data/lib/concurrent/settable_struct.rb +1 -0
- data/lib/concurrent/synchronization.rb +4 -5
- data/lib/concurrent/synchronization/abstract_lockable_object.rb +5 -5
- data/lib/concurrent/synchronization/abstract_struct.rb +6 -4
- data/lib/concurrent/synchronization/lockable_object.rb +6 -6
- data/lib/concurrent/synchronization/{mri_lockable_object.rb → mutex_lockable_object.rb} +19 -14
- data/lib/concurrent/synchronization/object.rb +8 -4
- data/lib/concurrent/synchronization/truffleruby_object.rb +46 -0
- data/lib/concurrent/synchronization/volatile.rb +11 -9
- data/lib/concurrent/thread_safe/util/data_structures.rb +55 -0
- data/lib/concurrent/thread_safe/util/striped64.rb +9 -4
- data/lib/concurrent/timer_task.rb +5 -2
- data/lib/concurrent/tuple.rb +1 -1
- data/lib/concurrent/tvar.rb +2 -2
- data/lib/concurrent/utility/at_exit.rb +1 -1
- data/lib/concurrent/utility/engine.rb +2 -2
- data/lib/concurrent/utility/monotonic_time.rb +3 -3
- data/lib/concurrent/utility/native_extension_loader.rb +31 -33
- data/lib/concurrent/utility/processor_counter.rb +0 -2
- data/lib/concurrent/version.rb +2 -2
- metadata +35 -21
- data/lib/concurrent/atomic_reference/concurrent_update_error.rb +0 -8
- data/lib/concurrent/atomic_reference/direct_update.rb +0 -81
- data/lib/concurrent/atomic_reference/jruby+truffle.rb +0 -2
- data/lib/concurrent/atomic_reference/jruby.rb +0 -16
- data/lib/concurrent/atomic_reference/rbx.rb +0 -22
- data/lib/concurrent/atomic_reference/ruby.rb +0 -32
- data/lib/concurrent/edge.rb +0 -26
- data/lib/concurrent/lazy_register.rb +0 -81
- data/lib/concurrent/synchronization/truffle_lockable_object.rb +0 -9
- data/lib/concurrent/synchronization/truffle_object.rb +0 -31
- data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +0 -30
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'concurrent/atomic_reference/concurrent_update_error'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
# Define update methods that use direct paths
|
6
|
-
#
|
7
|
-
# @!visibility private
|
8
|
-
# @!macro internal_implementation_note
|
9
|
-
module AtomicDirectUpdate
|
10
|
-
|
11
|
-
# @!macro [attach] atomic_reference_method_update
|
12
|
-
#
|
13
|
-
# Pass the current value to the given block, replacing it
|
14
|
-
# with the block's result. May retry if the value changes
|
15
|
-
# during the block's execution.
|
16
|
-
#
|
17
|
-
# @yield [Object] Calculate a new value for the atomic reference using
|
18
|
-
# given (old) value
|
19
|
-
# @yieldparam [Object] old_value the starting value of the atomic reference
|
20
|
-
#
|
21
|
-
# @return [Object] the new value
|
22
|
-
def update
|
23
|
-
true until compare_and_set(old_value = get, new_value = yield(old_value))
|
24
|
-
new_value
|
25
|
-
end
|
26
|
-
|
27
|
-
# @!macro [attach] atomic_reference_method_try_update
|
28
|
-
#
|
29
|
-
# Pass the current value to the given block, replacing it
|
30
|
-
# with the block's result. Return nil if the update fails.
|
31
|
-
#
|
32
|
-
# @yield [Object] Calculate a new value for the atomic reference using
|
33
|
-
# given (old) value
|
34
|
-
# @yieldparam [Object] old_value the starting value of the atomic reference
|
35
|
-
#
|
36
|
-
# @note This method was altered to avoid raising an exception by default.
|
37
|
-
# Instead, this method now returns `nil` in case of failure. For more info,
|
38
|
-
# please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336
|
39
|
-
#
|
40
|
-
# @return [Object] the new value, or nil if update failed
|
41
|
-
def try_update
|
42
|
-
old_value = get
|
43
|
-
new_value = yield old_value
|
44
|
-
|
45
|
-
return unless compare_and_set old_value, new_value
|
46
|
-
|
47
|
-
new_value
|
48
|
-
end
|
49
|
-
|
50
|
-
# @!macro [attach] atomic_reference_method_try_update!
|
51
|
-
#
|
52
|
-
# Pass the current value to the given block, replacing it
|
53
|
-
# with the block's result. Raise an exception if the update
|
54
|
-
# fails.
|
55
|
-
#
|
56
|
-
# @yield [Object] Calculate a new value for the atomic reference using
|
57
|
-
# given (old) value
|
58
|
-
# @yieldparam [Object] old_value the starting value of the atomic reference
|
59
|
-
#
|
60
|
-
# @note This behavior mimics the behavior of the original
|
61
|
-
# `AtomicReference#try_update` API. The reason this was changed was to
|
62
|
-
# avoid raising exceptions (which are inherently slow) by default. For more
|
63
|
-
# info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336
|
64
|
-
#
|
65
|
-
# @return [Object] the new value
|
66
|
-
#
|
67
|
-
# @raise [Concurrent::ConcurrentUpdateError] if the update fails
|
68
|
-
def try_update!
|
69
|
-
old_value = get
|
70
|
-
new_value = yield old_value
|
71
|
-
unless compare_and_set(old_value, new_value)
|
72
|
-
if $VERBOSE
|
73
|
-
raise ConcurrentUpdateError, "Update failed"
|
74
|
-
else
|
75
|
-
raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE
|
76
|
-
end
|
77
|
-
end
|
78
|
-
new_value
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'concurrent/synchronization'
|
2
|
-
|
3
|
-
if defined?(Concurrent::JavaAtomicReference)
|
4
|
-
require 'concurrent/atomic_reference/direct_update'
|
5
|
-
|
6
|
-
module Concurrent
|
7
|
-
|
8
|
-
# @!macro atomic_reference
|
9
|
-
#
|
10
|
-
# @!visibility private
|
11
|
-
# @!macro internal_implementation_note
|
12
|
-
class JavaAtomicReference
|
13
|
-
include Concurrent::AtomicDirectUpdate
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'concurrent/atomic_reference/direct_update'
|
2
|
-
require 'concurrent/atomic_reference/numeric_cas_wrapper'
|
3
|
-
|
4
|
-
module Concurrent
|
5
|
-
|
6
|
-
# @!macro atomic_reference
|
7
|
-
#
|
8
|
-
# @note Extends `Rubinius::AtomicReference` version adding aliases
|
9
|
-
# and numeric logic.
|
10
|
-
#
|
11
|
-
# @!visibility private
|
12
|
-
# @!macro internal_implementation_note
|
13
|
-
class RbxAtomicReference < Rubinius::AtomicReference
|
14
|
-
alias _compare_and_set compare_and_set
|
15
|
-
include Concurrent::AtomicDirectUpdate
|
16
|
-
include Concurrent::AtomicNumericCompareAndSetWrapper
|
17
|
-
|
18
|
-
alias_method :value, :get
|
19
|
-
alias_method :value=, :set
|
20
|
-
alias_method :swap, :get_and_set
|
21
|
-
end
|
22
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
if defined? Concurrent::CAtomicReference
|
2
|
-
require 'concurrent/synchronization'
|
3
|
-
require 'concurrent/atomic_reference/direct_update'
|
4
|
-
require 'concurrent/atomic_reference/numeric_cas_wrapper'
|
5
|
-
|
6
|
-
module Concurrent
|
7
|
-
|
8
|
-
# @!macro atomic_reference
|
9
|
-
#
|
10
|
-
# @!visibility private
|
11
|
-
# @!macro internal_implementation_note
|
12
|
-
class CAtomicReference
|
13
|
-
include Concurrent::AtomicDirectUpdate
|
14
|
-
include Concurrent::AtomicNumericCompareAndSetWrapper
|
15
|
-
|
16
|
-
# @!method initialize
|
17
|
-
# @!macro atomic_reference_method_initialize
|
18
|
-
|
19
|
-
# @!method get
|
20
|
-
# @!macro atomic_reference_method_get
|
21
|
-
|
22
|
-
# @!method set
|
23
|
-
# @!macro atomic_reference_method_set
|
24
|
-
|
25
|
-
# @!method get_and_set
|
26
|
-
# @!macro atomic_reference_method_get_and_set
|
27
|
-
|
28
|
-
# @!method _compare_and_set
|
29
|
-
# @!macro atomic_reference_method_compare_and_set
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
data/lib/concurrent/edge.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module Concurrent
|
2
|
-
|
3
|
-
# A submodule for unstable, highly experimental features that are likely to
|
4
|
-
# change often and which may never become part of the core gem. Also for
|
5
|
-
# new, experimental version of abstractions already in the core gem.
|
6
|
-
#
|
7
|
-
# Most new features should start in this module, clearly indicating the
|
8
|
-
# experimental and unstable nature of the feature. Once a feature becomes
|
9
|
-
# more stable and is a candidate for inclusion in the core gem it should
|
10
|
-
# be moved up to the `Concurrent` module, where it would reside once merged
|
11
|
-
# into the core gem.
|
12
|
-
#
|
13
|
-
# The only exception to this is for features which *replace* features from
|
14
|
-
# the core gem in ways that are breaking and not backward compatible. These
|
15
|
-
# features should remain in this module until merged into the core gem. This
|
16
|
-
# will prevent namespace collisions.
|
17
|
-
#
|
18
|
-
# @!macro [attach] edge_warning
|
19
|
-
# @api Edge
|
20
|
-
# @note **Edge Feature:** Edge features are under active development and may change frequently. They are expected not to
|
21
|
-
# keep backward compatibility (there may also lack tests and documentation). Semantic versions will
|
22
|
-
# be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move
|
23
|
-
# to `concurrent-ruby` when final.
|
24
|
-
module Edge
|
25
|
-
end
|
26
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'concurrent/atomic/atomic_reference'
|
2
|
-
require 'concurrent/delay'
|
3
|
-
|
4
|
-
module Concurrent
|
5
|
-
|
6
|
-
# Hash-like collection that store lazys evaluated values.
|
7
|
-
#
|
8
|
-
# @example
|
9
|
-
# register = Concurrent::LazyRegister.new
|
10
|
-
# #=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @Data=#<Concurrent::AtomicReference:0x007fd7ecd5e1e0>>
|
11
|
-
# register[:key]
|
12
|
-
# #=> nil
|
13
|
-
# register.add(:key) { Concurrent::Actor.spawn!(Actor::AdHoc, :ping) { -> message { message } } }
|
14
|
-
# #=> #<Concurrent::LazyRegister:0x007fd7ecd5e230 @Data=#<Concurrent::AtomicReference:0x007fd7ecd5e1e0>>
|
15
|
-
# register[:key]
|
16
|
-
# #=> #<Concurrent::Actor::Reference /ping (Concurrent::Actor::AdHoc)>
|
17
|
-
#
|
18
|
-
# @!macro edge_warning
|
19
|
-
class LazyRegister < Synchronization::Object
|
20
|
-
|
21
|
-
private(*attr_atomic(:data))
|
22
|
-
|
23
|
-
def initialize
|
24
|
-
super
|
25
|
-
self.data = {}
|
26
|
-
end
|
27
|
-
|
28
|
-
# Element reference. Retrieves the value object corresponding to the
|
29
|
-
# key object. Returns nil if the key is not found. Raises an exception
|
30
|
-
# if the stored item raised an exception when the block was evaluated.
|
31
|
-
#
|
32
|
-
# @param [Object] key
|
33
|
-
# @return [Object] value stored for the key or nil if the key is not found
|
34
|
-
#
|
35
|
-
# @raise Exception when the initialization block fails
|
36
|
-
def [](key)
|
37
|
-
delay = data[key]
|
38
|
-
delay ? delay.value! : nil
|
39
|
-
end
|
40
|
-
|
41
|
-
# Returns true if the given key is present.
|
42
|
-
#
|
43
|
-
# @param [Object] key
|
44
|
-
# @return [true, false] if the key is registered
|
45
|
-
def registered?(key)
|
46
|
-
data.key?(key)
|
47
|
-
end
|
48
|
-
|
49
|
-
alias_method :key?, :registered?
|
50
|
-
alias_method :has_key?, :registered?
|
51
|
-
|
52
|
-
# Element assignment. Associates the value given by value with the
|
53
|
-
# key given by key.
|
54
|
-
#
|
55
|
-
# @param [Object] key
|
56
|
-
# @yield the object to store under the key
|
57
|
-
#
|
58
|
-
# @return [LazyRegister] self
|
59
|
-
def register(key, &block)
|
60
|
-
delay = Delay.new(executor: :immediate, &block)
|
61
|
-
update_data { |h| h.merge(key => delay) }
|
62
|
-
self
|
63
|
-
end
|
64
|
-
|
65
|
-
alias_method :add, :register
|
66
|
-
alias_method :store, :register
|
67
|
-
|
68
|
-
# Un-registers the object under key, realized or not.
|
69
|
-
#
|
70
|
-
# @param [Object] key
|
71
|
-
#
|
72
|
-
# @return [LazyRegister] self
|
73
|
-
def unregister(key)
|
74
|
-
update_data { |h| h.dup.tap { |j| j.delete(key) } }
|
75
|
-
self
|
76
|
-
end
|
77
|
-
|
78
|
-
alias_method :remove, :unregister
|
79
|
-
alias_method :delete, :unregister
|
80
|
-
end
|
81
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Concurrent
|
2
|
-
module Synchronization
|
3
|
-
|
4
|
-
module TruffleAttrVolatile
|
5
|
-
def self.included(base)
|
6
|
-
base.extend(ClassMethods)
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
def attr_volatile(*names)
|
11
|
-
# TODO may not always be available
|
12
|
-
attr_atomic(*names)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def full_memory_barrier
|
17
|
-
Truffle::System.full_memory_barrier
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# @!visibility private
|
22
|
-
# @!macro internal_implementation_note
|
23
|
-
class TruffleObject < AbstractObject
|
24
|
-
include TruffleAttrVolatile
|
25
|
-
|
26
|
-
def initialize
|
27
|
-
# nothing to do
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,30 +0,0 @@
|
|
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
|