concurrent-ruby 1.0.5 → 1.1.6
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 +115 -0
- data/Gemfile +42 -0
- data/{LICENSE.txt → LICENSE.md} +2 -0
- data/README.md +242 -105
- data/Rakefile +332 -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 +307 -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/concurrent-ruby.rb +1 -0
- data/lib/{concurrent.rb → concurrent-ruby/concurrent.rb} +24 -20
- data/lib/{concurrent → concurrent-ruby/concurrent}/agent.rb +7 -7
- data/lib/concurrent-ruby/concurrent/array.rb +66 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/async.rb +18 -4
- data/lib/{concurrent → concurrent-ruby/concurrent}/atom.rb +10 -10
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/abstract_thread_local_var.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_boolean.rb +26 -22
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_fixnum.rb +27 -23
- data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +164 -0
- data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +204 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/count_down_latch.rb +7 -7
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/cyclic_barrier.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/event.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_count_down_latch.rb +9 -6
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_thread_local_var.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_boolean.rb +2 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_fixnum.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_count_down_latch.rb +1 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_semaphore.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/read_write_lock.rb +2 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/reentrant_read_write_lock.rb +3 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/ruby_thread_local_var.rb +43 -33
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/semaphore.rb +8 -8
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/thread_local_var.rb +8 -8
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/mutex_atomic.rb +3 -8
- data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/numeric_cas_wrapper.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomics.rb +10 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_notify_observer_set.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_write_observer_set.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/java_non_concurrent_priority_queue.rb +0 -0
- data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +158 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/atomic_reference_map_backend.rb +3 -3
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/mri_map_backend.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/non_concurrent_map_backend.rb +1 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/synchronized_map_backend.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/non_concurrent_priority_queue.rb +30 -30
- data/lib/{concurrent → concurrent-ruby/concurrent}/collection/ruby_non_concurrent_priority_queue.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/concern/deprecation.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/concern/dereferenceable.rb +3 -3
- data/lib/{concurrent → concurrent-ruby/concurrent}/concern/logging.rb +6 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/concern/obligation.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/concern/observable.rb +7 -7
- data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/configuration.rb +15 -15
- data/lib/{concurrent → concurrent-ruby/concurrent}/constants.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/dataflow.rb +2 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/delay.rb +9 -7
- data/lib/{concurrent → concurrent-ruby/concurrent}/errors.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/exchanger.rb +21 -25
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/abstract_executor_service.rb +19 -25
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/cached_thread_pool.rb +5 -5
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/executor_service.rb +17 -17
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/fixed_thread_pool.rb +27 -30
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/immediate_executor.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/indirect_immediate_executor.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_executor_service.rb +19 -16
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_single_thread_executor.rb +4 -3
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_thread_pool_executor.rb +12 -8
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_executor_service.rb +0 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_single_thread_executor.rb +0 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_thread_pool_executor.rb +9 -4
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/safe_task_executor.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serial_executor_service.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution_delegator.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/simple_executor_service.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/single_thread_executor.rb +3 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/thread_pool_executor.rb +6 -6
- data/lib/{concurrent → concurrent-ruby/concurrent}/executor/timer_set.rb +14 -17
- data/lib/{concurrent → concurrent-ruby/concurrent}/executors.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/future.rb +4 -1
- data/lib/concurrent-ruby/concurrent/hash.rb +59 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/immutable_struct.rb +8 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/ivar.rb +5 -6
- data/lib/concurrent-ruby/concurrent/map.rb +337 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/maybe.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/mutable_struct.rb +25 -14
- data/lib/{concurrent → concurrent-ruby/concurrent}/mvar.rb +2 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/options.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/promise.rb +53 -21
- data/lib/concurrent-ruby/concurrent/promises.rb +2167 -0
- data/lib/concurrent-ruby/concurrent/re_include.rb +58 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/scheduled_task.rb +0 -0
- data/lib/concurrent-ruby/concurrent/set.rb +66 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/settable_struct.rb +11 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization.rb +4 -5
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_lockable_object.rb +5 -5
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_object.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_struct.rb +18 -4
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/condition.rb +2 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_lockable_object.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_object.rb +1 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lock.rb +2 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lockable_object.rb +6 -6
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mri_object.rb +1 -0
- data/lib/{concurrent/synchronization/mri_lockable_object.rb → concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb} +19 -14
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/object.rb +53 -23
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_lockable_object.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_object.rb +1 -0
- data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +47 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/volatile.rb +11 -9
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/synchronized_delegator.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/adder.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/cheap_lockable.rb +0 -0
- data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +63 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/power_of_two_tuple.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/striped64.rb +9 -4
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/volatile.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/xor_shift_random.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/timer_task.rb +5 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/tuple.rb +1 -1
- data/lib/{concurrent → concurrent-ruby/concurrent}/tvar.rb +2 -2
- data/lib/{concurrent → concurrent-ruby/concurrent}/utility/engine.rb +4 -4
- data/lib/{concurrent → concurrent-ruby/concurrent}/utility/monotonic_time.rb +3 -3
- data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +79 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_integer.rb +0 -0
- data/lib/{concurrent → concurrent-ruby/concurrent}/utility/processor_counter.rb +5 -2
- data/lib/concurrent-ruby/concurrent/version.rb +3 -0
- metadata +146 -131
- data/lib/concurrent/array.rb +0 -39
- data/lib/concurrent/atomic/atomic_reference.rb +0 -51
- 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/atomics.rb +0 -53
- data/lib/concurrent/edge.rb +0 -26
- data/lib/concurrent/hash.rb +0 -36
- data/lib/concurrent/lazy_register.rb +0 -81
- data/lib/concurrent/map.rb +0 -240
- data/lib/concurrent/synchronization/truffle_lockable_object.rb +0 -9
- data/lib/concurrent/synchronization/truffle_object.rb +0 -31
- data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +0 -30
- data/lib/concurrent/utility/at_exit.rb +0 -97
- data/lib/concurrent/utility/native_extension_loader.rb +0 -73
- data/lib/concurrent/version.rb +0 -4
@@ -10,9 +10,10 @@ module Concurrent
|
|
10
10
|
JRubyObject
|
11
11
|
when Concurrent.on_rbx?
|
12
12
|
RbxObject
|
13
|
-
when Concurrent.
|
14
|
-
|
13
|
+
when Concurrent.on_truffleruby?
|
14
|
+
TruffleRubyObject
|
15
15
|
else
|
16
|
+
warn 'Possibly unsupported Ruby implementation'
|
16
17
|
MriObject
|
17
18
|
end
|
18
19
|
private_constant :ObjectImplementation
|
@@ -26,15 +27,15 @@ module Concurrent
|
|
26
27
|
|
27
28
|
# @!method self.attr_volatile(*names)
|
28
29
|
# Creates methods for reading and writing (as `attr_accessor` does) to a instance variable with
|
29
|
-
# volatile (Java) semantic. The instance variable should be accessed
|
30
|
+
# volatile (Java) semantic. The instance variable should be accessed only through generated methods.
|
30
31
|
#
|
31
|
-
# @param [Array<Symbol>] names of the instance variables to be volatile
|
32
|
-
# @return [Array<Symbol>] names of defined method names
|
32
|
+
# @param [::Array<Symbol>] names of the instance variables to be volatile
|
33
|
+
# @return [::Array<Symbol>] names of defined method names
|
33
34
|
|
34
35
|
# Has to be called by children.
|
35
36
|
def initialize
|
36
37
|
super
|
37
|
-
|
38
|
+
__initialize_atomic_fields__
|
38
39
|
end
|
39
40
|
|
40
41
|
# By calling this method on a class, it and all its children are marked to be constructed safely. Meaning that
|
@@ -48,10 +49,12 @@ module Concurrent
|
|
48
49
|
# @AFinalValue = 'value' # published safely, does not have to be synchronized
|
49
50
|
# end
|
50
51
|
# end
|
52
|
+
# @return [true]
|
51
53
|
def self.safe_initialization!
|
52
54
|
# define only once, and not again in children
|
53
55
|
return if safe_initialization?
|
54
56
|
|
57
|
+
# @!visibility private
|
55
58
|
def self.new(*args, &block)
|
56
59
|
object = super(*args, &block)
|
57
60
|
ensure
|
@@ -69,6 +72,8 @@ module Concurrent
|
|
69
72
|
|
70
73
|
# For testing purposes, quite slow. Injects assert code to new method which will raise if class instance contains
|
71
74
|
# any instance variables with CamelCase names and isn't {.safe_initialization?}.
|
75
|
+
# @raise when offend found
|
76
|
+
# @return [true]
|
72
77
|
def self.ensure_safe_initialization_when_final_fields_are_present
|
73
78
|
Object.class_eval do
|
74
79
|
def self.new(*args, &block)
|
@@ -80,6 +85,7 @@ module Concurrent
|
|
80
85
|
end
|
81
86
|
end
|
82
87
|
end
|
88
|
+
true
|
83
89
|
end
|
84
90
|
|
85
91
|
# Creates methods for reading and writing to a instance variable with
|
@@ -88,13 +94,30 @@ module Concurrent
|
|
88
94
|
# This method generates following methods: `value`, `value=(new_value) #=> new_value`,
|
89
95
|
# `swap_value(new_value) #=> old_value`,
|
90
96
|
# `compare_and_set_value(expected, value) #=> true || false`, `update_value(&block)`.
|
91
|
-
# @param [Array<Symbol>] names of the instance variables to be volatile with CAS.
|
92
|
-
# @return [Array<Symbol>] names of defined method names.
|
97
|
+
# @param [::Array<Symbol>] names of the instance variables to be volatile with CAS.
|
98
|
+
# @return [::Array<Symbol>] names of defined method names.
|
99
|
+
# @!macro attr_atomic
|
100
|
+
# @!method $1
|
101
|
+
# @return [Object] The $1.
|
102
|
+
# @!method $1=(new_$1)
|
103
|
+
# Set the $1.
|
104
|
+
# @return [Object] new_$1.
|
105
|
+
# @!method swap_$1(new_$1)
|
106
|
+
# Set the $1 to new_$1 and return the old $1.
|
107
|
+
# @return [Object] old $1
|
108
|
+
# @!method compare_and_set_$1(expected_$1, new_$1)
|
109
|
+
# Sets the $1 to new_$1 if the current $1 is expected_$1
|
110
|
+
# @return [true, false]
|
111
|
+
# @!method update_$1(&block)
|
112
|
+
# Updates the $1 using the block.
|
113
|
+
# @yield [Object] Calculate a new $1 using given (old) $1
|
114
|
+
# @yieldparam [Object] old $1
|
115
|
+
# @return [Object] new $1
|
93
116
|
def self.attr_atomic(*names)
|
94
|
-
@
|
95
|
-
@
|
117
|
+
@__atomic_fields__ ||= []
|
118
|
+
@__atomic_fields__ += names
|
96
119
|
safe_initialization!
|
97
|
-
|
120
|
+
define_initialize_atomic_fields
|
98
121
|
|
99
122
|
names.each do |name|
|
100
123
|
ivar = :"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }}"
|
@@ -123,29 +146,36 @@ module Concurrent
|
|
123
146
|
names.flat_map { |n| [n, :"#{n}=", :"swap_#{n}", :"compare_and_set_#{n}", :"update_#{n}"] }
|
124
147
|
end
|
125
148
|
|
126
|
-
# @param [true,false] inherited should inherited volatile with CAS fields be returned?
|
127
|
-
# @return [Array<Symbol>] Returns defined volatile with CAS fields on this class.
|
128
|
-
def self.
|
129
|
-
@
|
130
|
-
((superclass.
|
131
|
-
|
149
|
+
# @param [true, false] inherited should inherited volatile with CAS fields be returned?
|
150
|
+
# @return [::Array<Symbol>] Returns defined volatile with CAS fields on this class.
|
151
|
+
def self.atomic_attributes(inherited = true)
|
152
|
+
@__atomic_fields__ ||= []
|
153
|
+
((superclass.atomic_attributes if superclass.respond_to?(:atomic_attributes) && inherited) || []) + @__atomic_fields__
|
154
|
+
end
|
155
|
+
|
156
|
+
# @return [true, false] is the attribute with name atomic?
|
157
|
+
def self.atomic_attribute?(name)
|
158
|
+
atomic_attributes.include? name
|
132
159
|
end
|
133
160
|
|
134
161
|
private
|
135
162
|
|
136
|
-
def self.
|
137
|
-
assignments = @
|
138
|
-
|
139
|
-
|
163
|
+
def self.define_initialize_atomic_fields
|
164
|
+
assignments = @__atomic_fields__.map do |name|
|
165
|
+
"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }} = Concurrent::AtomicReference.new(nil)"
|
166
|
+
end.join("\n")
|
167
|
+
|
168
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
169
|
+
def __initialize_atomic_fields__
|
140
170
|
super
|
141
171
|
#{assignments}
|
142
172
|
end
|
143
173
|
RUBY
|
144
174
|
end
|
145
175
|
|
146
|
-
private_class_method :
|
176
|
+
private_class_method :define_initialize_atomic_fields
|
147
177
|
|
148
|
-
def
|
178
|
+
def __initialize_atomic_fields__
|
149
179
|
end
|
150
180
|
|
151
181
|
end
|
File without changes
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
# @!visibility private
|
5
|
+
module TruffleRubyAttrVolatile
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def attr_volatile(*names)
|
12
|
+
names.each do |name|
|
13
|
+
ivar = :"@volatile_#{name}"
|
14
|
+
|
15
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
16
|
+
def #{name}
|
17
|
+
full_memory_barrier
|
18
|
+
#{ivar}
|
19
|
+
end
|
20
|
+
|
21
|
+
def #{name}=(value)
|
22
|
+
#{ivar} = value
|
23
|
+
full_memory_barrier
|
24
|
+
end
|
25
|
+
RUBY
|
26
|
+
end
|
27
|
+
|
28
|
+
names.map { |n| [n, :"#{n}="] }.flatten
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def full_memory_barrier
|
33
|
+
TruffleRuby.full_memory_barrier
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @!visibility private
|
38
|
+
# @!macro internal_implementation_note
|
39
|
+
class TruffleRubyObject < AbstractObject
|
40
|
+
include TruffleRubyAttrVolatile
|
41
|
+
|
42
|
+
def initialize
|
43
|
+
# nothing to do
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -21,14 +21,16 @@ module Concurrent
|
|
21
21
|
# => 2
|
22
22
|
|
23
23
|
Volatile = case
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
when Concurrent.on_cruby?
|
25
|
+
MriAttrVolatile
|
26
|
+
when Concurrent.on_jruby?
|
27
|
+
JRubyAttrVolatile
|
28
|
+
when Concurrent.on_rbx?
|
29
|
+
RbxAttrVolatile
|
30
|
+
when Concurrent.on_truffleruby?
|
31
|
+
TruffleRubyAttrVolatile
|
32
|
+
else
|
33
|
+
MriAttrVolatile
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'concurrent/thread_safe/util'
|
2
|
+
|
3
|
+
# Shim for TruffleRuby.synchronized
|
4
|
+
if Concurrent.on_truffleruby? && !TruffleRuby.respond_to?(:synchronized)
|
5
|
+
module TruffleRuby
|
6
|
+
def self.synchronized(object, &block)
|
7
|
+
Truffle::System.synchronized(object, &block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Concurrent
|
13
|
+
module ThreadSafe
|
14
|
+
module Util
|
15
|
+
def self.make_synchronized_on_rbx(klass)
|
16
|
+
klass.class_eval do
|
17
|
+
private
|
18
|
+
|
19
|
+
def _mon_initialize
|
20
|
+
@_monitor = Monitor.new unless @_monitor # avoid double initialisation
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.new(*args)
|
24
|
+
obj = super(*args)
|
25
|
+
obj.send(:_mon_initialize)
|
26
|
+
obj
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
klass.superclass.instance_methods(false).each do |method|
|
31
|
+
case method
|
32
|
+
when :new_range, :new_reserved
|
33
|
+
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
34
|
+
def #{method}(*args)
|
35
|
+
obj = super
|
36
|
+
obj.send(:_mon_initialize)
|
37
|
+
obj
|
38
|
+
end
|
39
|
+
RUBY
|
40
|
+
else
|
41
|
+
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
42
|
+
def #{method}(*args)
|
43
|
+
monitor = @_monitor
|
44
|
+
monitor or raise("BUG: Internal monitor was not properly initialized. Please report this to the concurrent-ruby developers.")
|
45
|
+
monitor.synchronize { super }
|
46
|
+
end
|
47
|
+
RUBY
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.make_synchronized_on_truffleruby(klass)
|
53
|
+
klass.superclass.instance_methods(false).each do |method|
|
54
|
+
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
55
|
+
def #{method}(*args, &block)
|
56
|
+
TruffleRuby.synchronized(self) { super(*args, &block) }
|
57
|
+
end
|
58
|
+
RUBY
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
File without changes
|
@@ -86,15 +86,20 @@ module Concurrent
|
|
86
86
|
# @!visibility private
|
87
87
|
class Cell < Concurrent::AtomicReference
|
88
88
|
|
89
|
-
# TODO: this only adds padding after the :value slot, need to find a way to add padding before the slot
|
90
|
-
# @!visibility private
|
91
|
-
attr_reader *(12.times.collect{ |i| "padding_#{i}".to_sym })
|
92
|
-
|
93
89
|
alias_method :cas, :compare_and_set
|
94
90
|
|
95
91
|
def cas_computed
|
96
92
|
cas(current_value = value, yield(current_value))
|
97
93
|
end
|
94
|
+
|
95
|
+
# @!visibility private
|
96
|
+
def self.padding
|
97
|
+
# TODO: this only adds padding after the :value slot, need to find a way to add padding before the slot
|
98
|
+
# TODO (pitr-ch 28-Jul-2018): the padding instance vars may not be created
|
99
|
+
# hide from yardoc in a method
|
100
|
+
attr_reader *(12.times.collect{ |i| "padding_#{i}".to_sym })
|
101
|
+
end
|
102
|
+
padding
|
98
103
|
end
|
99
104
|
|
100
105
|
extend Volatile
|
File without changes
|
File without changes
|
@@ -126,6 +126,7 @@ module Concurrent
|
|
126
126
|
# task = Concurrent::TimerTask.new(execution_interval: 1, timeout_interval: 1){ 42 }
|
127
127
|
# task.add_observer(TaskObserver.new)
|
128
128
|
# task.execute
|
129
|
+
# sleep 4
|
129
130
|
#
|
130
131
|
# #=> (2013-10-13 19:08:58 -0400) Execution successfully returned 42
|
131
132
|
# #=> (2013-10-13 19:08:59 -0400) Execution successfully returned 42
|
@@ -164,7 +165,7 @@ module Concurrent
|
|
164
165
|
|
165
166
|
# Create a new TimerTask with the given task and configuration.
|
166
167
|
#
|
167
|
-
# @!macro
|
168
|
+
# @!macro timer_task_initialize
|
168
169
|
# @param [Hash] opts the options defining task execution.
|
169
170
|
# @option opts [Integer] :execution_interval number of seconds between
|
170
171
|
# task executions (default: EXECUTION_INTERVAL)
|
@@ -189,6 +190,7 @@ module Concurrent
|
|
189
190
|
def initialize(opts = {}, &task)
|
190
191
|
raise ArgumentError.new('no block given') unless block_given?
|
191
192
|
super
|
193
|
+
set_deref_options opts
|
192
194
|
end
|
193
195
|
|
194
196
|
# Is the executor running?
|
@@ -280,6 +282,7 @@ module Concurrent
|
|
280
282
|
@run_now = opts[:now] || opts[:run_now]
|
281
283
|
@executor = Concurrent::SafeTaskExecutor.new(task)
|
282
284
|
@running = Concurrent::AtomicBoolean.new(false)
|
285
|
+
@value = nil
|
283
286
|
|
284
287
|
self.observers = Collection::CopyOnNotifyObserverSet.new
|
285
288
|
end
|
@@ -305,7 +308,7 @@ module Concurrent
|
|
305
308
|
# @!visibility private
|
306
309
|
def execute_task(completion)
|
307
310
|
return nil unless @running.true?
|
308
|
-
ScheduledTask.execute(
|
311
|
+
ScheduledTask.execute(timeout_interval, args: [completion], &method(:timeout_task))
|
309
312
|
_success, value, reason = @executor.execute(self)
|
310
313
|
if completion.try?
|
311
314
|
self.value = value
|
@@ -24,7 +24,7 @@ module Concurrent
|
|
24
24
|
attr_reader :size
|
25
25
|
|
26
26
|
# @!visibility private
|
27
|
-
Tuple = defined?(Rubinius::Tuple) ? Rubinius::Tuple : Array
|
27
|
+
Tuple = defined?(Rubinius::Tuple) ? Rubinius::Tuple : ::Array
|
28
28
|
private_constant :Tuple
|
29
29
|
|
30
30
|
# Create a new tuple of the given size.
|
@@ -8,7 +8,7 @@ module Concurrent
|
|
8
8
|
#
|
9
9
|
# @!macro thread_safe_variable_comparison
|
10
10
|
#
|
11
|
-
# {include:file:
|
11
|
+
# {include:file:docs-source/tvar.md}
|
12
12
|
class TVar < Synchronization::Object
|
13
13
|
safe_initialization!
|
14
14
|
|
@@ -162,7 +162,7 @@ module Concurrent
|
|
162
162
|
|
163
163
|
class Transaction
|
164
164
|
|
165
|
-
ABORTED = Object.new
|
165
|
+
ABORTED = ::Object.new
|
166
166
|
|
167
167
|
ReadLogEntry = Struct.new(:tvar, :version)
|
168
168
|
|
@@ -8,7 +8,7 @@ module Concurrent
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def on_jruby_9000?
|
11
|
-
on_jruby? && ruby_version(:>=, 9, 0, 0
|
11
|
+
on_jruby? && ruby_version(JRUBY_VERSION, :>=, 9, 0, 0)
|
12
12
|
end
|
13
13
|
|
14
14
|
def on_cruby?
|
@@ -19,8 +19,8 @@ module Concurrent
|
|
19
19
|
ruby_engine == 'rbx'
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
ruby_engine == '
|
22
|
+
def on_truffleruby?
|
23
|
+
ruby_engine == 'truffleruby'
|
24
24
|
end
|
25
25
|
|
26
26
|
def on_windows?
|
@@ -39,7 +39,7 @@ module Concurrent
|
|
39
39
|
defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
40
40
|
end
|
41
41
|
|
42
|
-
def ruby_version(comparison, major, minor, patch
|
42
|
+
def ruby_version(version = RUBY_VERSION, comparison, major, minor, patch)
|
43
43
|
result = (version.split('.').map(&:to_i) <=> [major, minor, patch])
|
44
44
|
comparisons = { :== => [0],
|
45
45
|
:>= => [1, 0],
|
@@ -42,12 +42,12 @@ module Concurrent
|
|
42
42
|
GLOBAL_MONOTONIC_CLOCK = class_definition.new
|
43
43
|
private_constant :GLOBAL_MONOTONIC_CLOCK
|
44
44
|
|
45
|
-
# @!macro
|
45
|
+
# @!macro monotonic_get_time
|
46
46
|
#
|
47
47
|
# Returns the current time a tracked by the application monotonic clock.
|
48
48
|
#
|
49
|
-
# @return [Float] The current monotonic time
|
50
|
-
#
|
49
|
+
# @return [Float] The current monotonic time since some unspecified
|
50
|
+
# starting point
|
51
51
|
#
|
52
52
|
# @!macro monotonic_clock_warning
|
53
53
|
def monotonic_time
|