concurrent-ruby 1.0.5 → 1.1.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +44 -0
  3. data/Gemfile +39 -0
  4. data/{LICENSE.txt → LICENSE.md} +2 -0
  5. data/README.md +203 -105
  6. data/Rakefile +279 -0
  7. data/ext/concurrent-ruby/ConcurrentRubyService.java +17 -0
  8. data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +175 -0
  9. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +248 -0
  10. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +93 -0
  11. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +113 -0
  12. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +159 -0
  13. data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +304 -0
  14. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +31 -0
  15. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +3863 -0
  16. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +203 -0
  17. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +342 -0
  18. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +3800 -0
  19. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +204 -0
  20. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +291 -0
  21. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +199 -0
  22. data/lib/concurrent-ruby.rb +1 -0
  23. data/lib/concurrent.rb +24 -20
  24. data/lib/concurrent/agent.rb +7 -7
  25. data/lib/concurrent/array.rb +59 -32
  26. data/lib/concurrent/async.rb +4 -4
  27. data/lib/concurrent/atom.rb +9 -9
  28. data/lib/concurrent/atomic/atomic_boolean.rb +24 -20
  29. data/lib/concurrent/atomic/atomic_fixnum.rb +27 -23
  30. data/lib/concurrent/atomic/atomic_markable_reference.rb +164 -0
  31. data/lib/concurrent/atomic/atomic_reference.rb +176 -33
  32. data/lib/concurrent/atomic/count_down_latch.rb +6 -6
  33. data/lib/concurrent/atomic/cyclic_barrier.rb +1 -1
  34. data/lib/concurrent/atomic/event.rb +1 -1
  35. data/lib/concurrent/atomic/java_count_down_latch.rb +6 -5
  36. data/lib/concurrent/atomic/mutex_count_down_latch.rb +1 -0
  37. data/lib/concurrent/atomic/read_write_lock.rb +2 -1
  38. data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
  39. data/lib/concurrent/atomic/semaphore.rb +8 -8
  40. data/lib/concurrent/atomic/thread_local_var.rb +7 -7
  41. data/lib/concurrent/atomic_reference/mutex_atomic.rb +3 -8
  42. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +1 -1
  43. data/lib/concurrent/atomics.rb +0 -43
  44. data/lib/concurrent/collection/lock_free_stack.rb +158 -0
  45. data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +3 -3
  46. data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +1 -2
  47. data/lib/concurrent/collection/non_concurrent_priority_queue.rb +29 -29
  48. data/lib/concurrent/concern/dereferenceable.rb +1 -1
  49. data/lib/concurrent/concern/logging.rb +6 -1
  50. data/lib/concurrent/concern/observable.rb +7 -7
  51. data/lib/concurrent/concurrent_ruby.jar +0 -0
  52. data/lib/concurrent/configuration.rb +1 -6
  53. data/lib/concurrent/constants.rb +1 -1
  54. data/lib/concurrent/dataflow.rb +2 -1
  55. data/lib/concurrent/delay.rb +9 -7
  56. data/lib/concurrent/exchanger.rb +13 -21
  57. data/lib/concurrent/executor/abstract_executor_service.rb +2 -2
  58. data/lib/concurrent/executor/cached_thread_pool.rb +1 -1
  59. data/lib/concurrent/executor/executor_service.rb +15 -15
  60. data/lib/concurrent/executor/fixed_thread_pool.rb +18 -18
  61. data/lib/concurrent/executor/java_thread_pool_executor.rb +10 -7
  62. data/lib/concurrent/executor/single_thread_executor.rb +2 -2
  63. data/lib/concurrent/executor/thread_pool_executor.rb +6 -6
  64. data/lib/concurrent/executor/timer_set.rb +1 -1
  65. data/lib/concurrent/future.rb +4 -1
  66. data/lib/concurrent/hash.rb +53 -30
  67. data/lib/concurrent/ivar.rb +5 -6
  68. data/lib/concurrent/map.rb +20 -25
  69. data/lib/concurrent/maybe.rb +1 -1
  70. data/lib/concurrent/mutable_struct.rb +15 -14
  71. data/lib/concurrent/mvar.rb +2 -2
  72. data/lib/concurrent/promise.rb +53 -21
  73. data/lib/concurrent/promises.rb +1936 -0
  74. data/lib/concurrent/re_include.rb +58 -0
  75. data/lib/concurrent/set.rb +66 -0
  76. data/lib/concurrent/settable_struct.rb +1 -0
  77. data/lib/concurrent/synchronization.rb +4 -5
  78. data/lib/concurrent/synchronization/abstract_lockable_object.rb +5 -5
  79. data/lib/concurrent/synchronization/abstract_struct.rb +6 -4
  80. data/lib/concurrent/synchronization/lockable_object.rb +6 -6
  81. data/lib/concurrent/synchronization/{mri_lockable_object.rb → mutex_lockable_object.rb} +19 -14
  82. data/lib/concurrent/synchronization/object.rb +8 -4
  83. data/lib/concurrent/synchronization/truffleruby_object.rb +46 -0
  84. data/lib/concurrent/synchronization/volatile.rb +11 -9
  85. data/lib/concurrent/thread_safe/util/data_structures.rb +55 -0
  86. data/lib/concurrent/thread_safe/util/striped64.rb +9 -4
  87. data/lib/concurrent/timer_task.rb +5 -2
  88. data/lib/concurrent/tuple.rb +1 -1
  89. data/lib/concurrent/tvar.rb +2 -2
  90. data/lib/concurrent/utility/at_exit.rb +1 -1
  91. data/lib/concurrent/utility/engine.rb +2 -2
  92. data/lib/concurrent/utility/monotonic_time.rb +3 -3
  93. data/lib/concurrent/utility/native_extension_loader.rb +31 -33
  94. data/lib/concurrent/utility/processor_counter.rb +0 -2
  95. data/lib/concurrent/version.rb +2 -2
  96. metadata +35 -21
  97. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +0 -8
  98. data/lib/concurrent/atomic_reference/direct_update.rb +0 -81
  99. data/lib/concurrent/atomic_reference/jruby+truffle.rb +0 -2
  100. data/lib/concurrent/atomic_reference/jruby.rb +0 -16
  101. data/lib/concurrent/atomic_reference/rbx.rb +0 -22
  102. data/lib/concurrent/atomic_reference/ruby.rb +0 -32
  103. data/lib/concurrent/edge.rb +0 -26
  104. data/lib/concurrent/lazy_register.rb +0 -81
  105. data/lib/concurrent/synchronization/truffle_lockable_object.rb +0 -9
  106. data/lib/concurrent/synchronization/truffle_object.rb +0 -31
  107. data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +0 -30
@@ -0,0 +1,58 @@
1
+ module Concurrent
2
+
3
+ # Methods form module A included to a module B, which is already included into class C,
4
+ # will not be visible in the C class. If this module is extended to B then A's methods
5
+ # are correctly made visible to C.
6
+ #
7
+ # @example
8
+ # module A
9
+ # def a
10
+ # :a
11
+ # end
12
+ # end
13
+ #
14
+ # module B1
15
+ # end
16
+ #
17
+ # class C1
18
+ # include B1
19
+ # end
20
+ #
21
+ # module B2
22
+ # extend Concurrent::ReInclude
23
+ # end
24
+ #
25
+ # class C2
26
+ # include B2
27
+ # end
28
+ #
29
+ # B1.send :include, A
30
+ # B2.send :include, A
31
+ #
32
+ # C1.new.respond_to? :a # => false
33
+ # C2.new.respond_to? :a # => true
34
+ module ReInclude
35
+ # @!visibility private
36
+ def included(base)
37
+ (@re_include_to_bases ||= []) << [:include, base]
38
+ super(base)
39
+ end
40
+
41
+ # @!visibility private
42
+ def extended(base)
43
+ (@re_include_to_bases ||= []) << [:extend, base]
44
+ super(base)
45
+ end
46
+
47
+ # @!visibility private
48
+ def include(*modules)
49
+ result = super(*modules)
50
+ modules.reverse.each do |module_being_included|
51
+ (@re_include_to_bases ||= []).each do |method, mod|
52
+ mod.send method, module_being_included
53
+ end
54
+ end
55
+ result
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,66 @@
1
+ require 'concurrent/utility/engine'
2
+ require 'concurrent/thread_safe/util'
3
+ require 'set'
4
+
5
+ module Concurrent
6
+
7
+ # @!macro concurrent_set
8
+ #
9
+ # A thread-safe subclass of Set. This version locks against the object
10
+ # itself for every method call, ensuring only one thread can be reading
11
+ # or writing at a time. This includes iteration methods like `#each`.
12
+ #
13
+ # @note `a += b` is **not** a **thread-safe** operation on
14
+ # `Concurrent::Set`. It reads Set `a`, then it creates new `Concurrent::Set`
15
+ # which is union of `a` and `b`, then it writes the union to `a`.
16
+ # The read and write are independent operations they do not form a single atomic
17
+ # operation therefore when two `+=` operations are executed concurrently updates
18
+ # may be lost. Use `#merge` instead.
19
+ #
20
+ # @see http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html Ruby standard library `Set`
21
+
22
+
23
+ # @!macro internal_implementation_note
24
+ SetImplementation = case
25
+ when Concurrent.on_cruby?
26
+ # Because MRI never runs code in parallel, the existing
27
+ # non-thread-safe structures should usually work fine.
28
+ ::Set
29
+
30
+ when Concurrent.on_jruby?
31
+ require 'jruby/synchronized'
32
+
33
+ class JRubySet < ::Set
34
+ include JRuby::Synchronized
35
+ end
36
+ JRubySet
37
+
38
+ when Concurrent.on_rbx?
39
+ require 'monitor'
40
+ require 'concurrent/thread_safe/util/data_structures'
41
+
42
+ class RbxSet < ::Set
43
+ end
44
+ ThreadSafe::Util.make_synchronized_on_rbx Concurrent::RbxSet
45
+ RbxSet
46
+
47
+ when Concurrent.on_truffleruby?
48
+ require 'concurrent/thread_safe/util/data_structures'
49
+
50
+ class TruffleRubySet < ::Set
51
+ end
52
+
53
+ ThreadSafe::Util.make_synchronized_on_truffleruby Concurrent::TruffleRubySet
54
+ TruffleRubySet
55
+
56
+ else
57
+ warn 'Possibly unsupported Ruby implementation'
58
+ ::Set
59
+ end
60
+ private_constant :SetImplementation
61
+
62
+ # @!macro concurrent_set
63
+ class Set < SetImplementation
64
+ end
65
+ end
66
+
@@ -107,6 +107,7 @@ module Concurrent
107
107
  synchronize do
108
108
  clazz = Synchronization::AbstractStruct.define_struct_class(SettableStruct, Synchronization::LockableObject, name, members, &block)
109
109
  members.each_with_index do |member, index|
110
+ clazz.send :remove_method, member if clazz.instance_methods.include? member
110
111
  clazz.send(:define_method, member) do
111
112
  synchronize { @values[index] }
112
113
  end
@@ -7,15 +7,14 @@ Concurrent.load_native_extensions
7
7
  require 'concurrent/synchronization/mri_object'
8
8
  require 'concurrent/synchronization/jruby_object'
9
9
  require 'concurrent/synchronization/rbx_object'
10
- require 'concurrent/synchronization/truffle_object'
10
+ require 'concurrent/synchronization/truffleruby_object'
11
11
  require 'concurrent/synchronization/object'
12
12
  require 'concurrent/synchronization/volatile'
13
13
 
14
14
  require 'concurrent/synchronization/abstract_lockable_object'
15
- require 'concurrent/synchronization/mri_lockable_object'
15
+ require 'concurrent/synchronization/mutex_lockable_object'
16
16
  require 'concurrent/synchronization/jruby_lockable_object'
17
17
  require 'concurrent/synchronization/rbx_lockable_object'
18
- require 'concurrent/synchronization/truffle_lockable_object'
19
18
 
20
19
  require 'concurrent/synchronization/lockable_object'
21
20
 
@@ -23,8 +22,8 @@ require 'concurrent/synchronization/condition'
23
22
  require 'concurrent/synchronization/lock'
24
23
 
25
24
  module Concurrent
26
- # {include:file:doc/synchronization.md}
27
- # {include:file:doc/synchronization-notes.md}
25
+ # {include:file:docs-source/synchronization.md}
26
+ # {include:file:docs-source/synchronization-notes.md}
28
27
  module Synchronization
29
28
  end
30
29
  end
@@ -6,7 +6,7 @@ module Concurrent
6
6
 
7
7
  protected
8
8
 
9
- # @!macro [attach] synchronization_object_method_synchronize
9
+ # @!macro synchronization_object_method_synchronize
10
10
  #
11
11
  # @yield runs the block synchronized against this object,
12
12
  # equivalent of java's `synchronize(this) {}`
@@ -15,7 +15,7 @@ module Concurrent
15
15
  raise NotImplementedError
16
16
  end
17
17
 
18
- # @!macro [attach] synchronization_object_method_ns_wait_until
18
+ # @!macro synchronization_object_method_ns_wait_until
19
19
  #
20
20
  # Wait until condition is met or timeout passes,
21
21
  # protects against spurious wake-ups.
@@ -45,7 +45,7 @@ module Concurrent
45
45
  end
46
46
  end
47
47
 
48
- # @!macro [attach] synchronization_object_method_ns_wait
48
+ # @!macro synchronization_object_method_ns_wait
49
49
  #
50
50
  # Wait until another thread calls #signal or #broadcast,
51
51
  # spurious wake-ups can happen.
@@ -63,7 +63,7 @@ module Concurrent
63
63
  raise NotImplementedError
64
64
  end
65
65
 
66
- # @!macro [attach] synchronization_object_method_ns_signal
66
+ # @!macro synchronization_object_method_ns_signal
67
67
  #
68
68
  # Signal one waiting thread.
69
69
  # @return [self]
@@ -78,7 +78,7 @@ module Concurrent
78
78
  raise NotImplementedError
79
79
  end
80
80
 
81
- # @!macro [attach] synchronization_object_method_ns_broadcast
81
+ # @!macro synchronization_object_method_ns_broadcast
82
82
  #
83
83
  # Broadcast to all waiting threads.
84
84
  # @return [self]
@@ -11,7 +11,7 @@ module Concurrent
11
11
  ns_initialize(*values)
12
12
  end
13
13
 
14
- # @!macro [attach] struct_length
14
+ # @!macro struct_length
15
15
  #
16
16
  # Returns the number of struct members.
17
17
  #
@@ -21,7 +21,7 @@ module Concurrent
21
21
  end
22
22
  alias_method :size, :length
23
23
 
24
- # @!macro [attach] struct_members
24
+ # @!macro struct_members
25
25
  #
26
26
  # Returns the struct members as an array of symbols.
27
27
  #
@@ -117,7 +117,7 @@ module Concurrent
117
117
 
118
118
  # @!visibility private
119
119
  def pr_underscore(clazz)
120
- word = clazz.to_s
120
+ word = clazz.to_s.dup # dup string to workaround JRuby 9.2.0.0 bug https://github.com/jruby/jruby/issues/5229
121
121
  word.gsub!(/::/, '/')
122
122
  word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
123
123
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
@@ -138,13 +138,15 @@ module Concurrent
138
138
  end
139
139
  unless name.nil?
140
140
  begin
141
+ parent.send :remove_const, name if parent.const_defined? name
141
142
  parent.const_set(name, clazz)
142
- parent.const_get(name)
143
+ clazz
143
144
  rescue NameError
144
145
  raise NameError.new("identifier #{name} needs to be constant")
145
146
  end
146
147
  end
147
148
  members.each_with_index do |member, index|
149
+ clazz.send :remove_method, member if clazz.instance_methods.include? member
148
150
  clazz.send(:define_method, member) do
149
151
  @values[index]
150
152
  end
@@ -5,18 +5,18 @@ module Concurrent
5
5
  # @!macro internal_implementation_note
6
6
  LockableObjectImplementation = case
7
7
  when Concurrent.on_cruby? && Concurrent.ruby_version(:<=, 1, 9, 3)
8
- MriMonitorLockableObject
8
+ MonitorLockableObject
9
9
  when Concurrent.on_cruby? && Concurrent.ruby_version(:>, 1, 9, 3)
10
- MriMutexLockableObject
10
+ MutexLockableObject
11
11
  when Concurrent.on_jruby?
12
12
  JRubyLockableObject
13
13
  when Concurrent.on_rbx?
14
14
  RbxLockableObject
15
- when Concurrent.on_truffle?
16
- MriMutexLockableObject
15
+ when Concurrent.on_truffleruby?
16
+ MutexLockableObject
17
17
  else
18
18
  warn 'Possibly unsupported Ruby implementation'
19
- MriMonitorLockableObject
19
+ MonitorLockableObject
20
20
  end
21
21
  private_constant :LockableObjectImplementation
22
22
 
@@ -31,7 +31,7 @@ module Concurrent
31
31
  # `Thread#sleep` and `Thread#wakeup` will work as expected but mixing `Synchronization::Object#wait` and
32
32
  # `Thread#wakeup` will not work on all platforms.
33
33
  #
34
- # @see {Event} implementation as an example of this class use
34
+ # @see Event implementation as an example of this class use
35
35
  #
36
36
  # @example simple
37
37
  # class AnClass < Synchronization::Object
@@ -1,18 +1,19 @@
1
1
  module Concurrent
2
+ # noinspection RubyInstanceVariableNamingConvention
2
3
  module Synchronization
3
4
 
4
5
  # @!visibility private
5
6
  # @!macro internal_implementation_note
6
- class MriLockableObject < AbstractLockableObject
7
+ module ConditionSignalling
7
8
  protected
8
9
 
9
10
  def ns_signal
10
- @__condition__.signal
11
+ @__Condition__.signal
11
12
  self
12
13
  end
13
14
 
14
15
  def ns_broadcast
15
- @__condition__.broadcast
16
+ @__Condition__.broadcast
16
17
  self
17
18
  end
18
19
  end
@@ -20,50 +21,54 @@ module Concurrent
20
21
 
21
22
  # @!visibility private
22
23
  # @!macro internal_implementation_note
23
- class MriMutexLockableObject < MriLockableObject
24
+ class MutexLockableObject < AbstractLockableObject
25
+ include ConditionSignalling
26
+
24
27
  safe_initialization!
25
28
 
26
29
  def initialize(*defaults)
27
30
  super(*defaults)
28
- @__lock__ = ::Mutex.new
29
- @__condition__ = ::ConditionVariable.new
31
+ @__Lock__ = ::Mutex.new
32
+ @__Condition__ = ::ConditionVariable.new
30
33
  end
31
34
 
32
35
  protected
33
36
 
34
37
  def synchronize
35
- if @__lock__.owned?
38
+ if @__Lock__.owned?
36
39
  yield
37
40
  else
38
- @__lock__.synchronize { yield }
41
+ @__Lock__.synchronize { yield }
39
42
  end
40
43
  end
41
44
 
42
45
  def ns_wait(timeout = nil)
43
- @__condition__.wait @__lock__, timeout
46
+ @__Condition__.wait @__Lock__, timeout
44
47
  self
45
48
  end
46
49
  end
47
50
 
48
51
  # @!visibility private
49
52
  # @!macro internal_implementation_note
50
- class MriMonitorLockableObject < MriLockableObject
53
+ class MonitorLockableObject < AbstractLockableObject
54
+ include ConditionSignalling
55
+
51
56
  safe_initialization!
52
57
 
53
58
  def initialize(*defaults)
54
59
  super(*defaults)
55
- @__lock__ = ::Monitor.new
56
- @__condition__ = @__lock__.new_cond
60
+ @__Lock__ = ::Monitor.new
61
+ @__Condition__ = @__Lock__.new_cond
57
62
  end
58
63
 
59
64
  protected
60
65
 
61
66
  def synchronize # TODO may be a problem with lock.synchronize { lock.wait }
62
- @__lock__.synchronize { yield }
67
+ @__Lock__.synchronize { yield }
63
68
  end
64
69
 
65
70
  def ns_wait(timeout = nil)
66
- @__condition__.wait timeout
71
+ @__Condition__.wait timeout
67
72
  self
68
73
  end
69
74
  end
@@ -10,9 +10,10 @@ module Concurrent
10
10
  JRubyObject
11
11
  when Concurrent.on_rbx?
12
12
  RbxObject
13
- when Concurrent.on_truffle?
14
- TruffleObject
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
@@ -134,8 +135,11 @@ module Concurrent
134
135
  private
135
136
 
136
137
  def self.define_initialize_volatile_with_cas
137
- assignments = @volatile_cas_fields.map { |name| "@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }} = AtomicReference.new(nil)" }.join("\n")
138
- class_eval <<-RUBY
138
+ assignments = @volatile_cas_fields.map do |name|
139
+ "@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }} = Concurrent::AtomicReference.new(nil)"
140
+ end.join("\n")
141
+
142
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
139
143
  def initialize_volatile_with_cas
140
144
  super
141
145
  #{assignments}
@@ -0,0 +1,46 @@
1
+ module Concurrent
2
+ module Synchronization
3
+
4
+ module TruffleRubyAttrVolatile
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def attr_volatile(*names)
11
+ names.each do |name|
12
+ ivar = :"@volatile_#{name}"
13
+
14
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
15
+ def #{name}
16
+ full_memory_barrier
17
+ #{ivar}
18
+ end
19
+
20
+ def #{name}=(value)
21
+ #{ivar} = value
22
+ full_memory_barrier
23
+ end
24
+ RUBY
25
+ end
26
+
27
+ names.map { |n| [n, :"#{n}="] }.flatten
28
+ end
29
+ end
30
+
31
+ def full_memory_barrier
32
+ TruffleRuby.full_memory_barrier
33
+ end
34
+ end
35
+
36
+ # @!visibility private
37
+ # @!macro internal_implementation_note
38
+ class TruffleRubyObject < AbstractObject
39
+ include TruffleRubyAttrVolatile
40
+
41
+ def initialize
42
+ # nothing to do
43
+ end
44
+ end
45
+ end
46
+ end
@@ -21,14 +21,16 @@ module Concurrent
21
21
  # => 2
22
22
 
23
23
  Volatile = case
24
- when Concurrent.on_cruby?
25
- MriAttrVolatile
26
- when Concurrent.on_jruby?
27
- JRubyAttrVolatile
28
- when Concurrent.on_rbx? || Concurrent.on_truffle?
29
- RbxAttrVolatile
30
- else
31
- MriAttrVolatile
32
- end
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