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.
Files changed (161) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +115 -0
  3. data/Gemfile +42 -0
  4. data/{LICENSE.txt → LICENSE.md} +2 -0
  5. data/README.md +242 -105
  6. data/Rakefile +332 -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 +307 -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/concurrent-ruby.rb +1 -0
  23. data/lib/{concurrent.rb → concurrent-ruby/concurrent.rb} +24 -20
  24. data/lib/{concurrent → concurrent-ruby/concurrent}/agent.rb +7 -7
  25. data/lib/concurrent-ruby/concurrent/array.rb +66 -0
  26. data/lib/{concurrent → concurrent-ruby/concurrent}/async.rb +18 -4
  27. data/lib/{concurrent → concurrent-ruby/concurrent}/atom.rb +10 -10
  28. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/abstract_thread_local_var.rb +0 -0
  29. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_boolean.rb +26 -22
  30. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_fixnum.rb +27 -23
  31. data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +164 -0
  32. data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +204 -0
  33. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/count_down_latch.rb +7 -7
  34. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/cyclic_barrier.rb +1 -1
  35. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/event.rb +1 -1
  36. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_count_down_latch.rb +9 -6
  37. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_thread_local_var.rb +0 -0
  38. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_boolean.rb +2 -0
  39. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_fixnum.rb +0 -0
  40. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_count_down_latch.rb +1 -0
  41. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_semaphore.rb +0 -0
  42. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/read_write_lock.rb +2 -1
  43. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/reentrant_read_write_lock.rb +3 -1
  44. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/ruby_thread_local_var.rb +43 -33
  45. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/semaphore.rb +8 -8
  46. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/thread_local_var.rb +8 -8
  47. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/mutex_atomic.rb +3 -8
  48. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/numeric_cas_wrapper.rb +1 -1
  49. data/lib/concurrent-ruby/concurrent/atomics.rb +10 -0
  50. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_notify_observer_set.rb +0 -0
  51. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_write_observer_set.rb +0 -0
  52. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/java_non_concurrent_priority_queue.rb +0 -0
  53. data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +158 -0
  54. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/atomic_reference_map_backend.rb +3 -3
  55. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/mri_map_backend.rb +0 -0
  56. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/non_concurrent_map_backend.rb +1 -2
  57. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/synchronized_map_backend.rb +0 -0
  58. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/non_concurrent_priority_queue.rb +30 -30
  59. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/ruby_non_concurrent_priority_queue.rb +0 -0
  60. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/deprecation.rb +0 -0
  61. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/dereferenceable.rb +3 -3
  62. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/logging.rb +6 -1
  63. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/obligation.rb +0 -0
  64. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/observable.rb +7 -7
  65. data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
  66. data/lib/{concurrent → concurrent-ruby/concurrent}/configuration.rb +15 -15
  67. data/lib/{concurrent → concurrent-ruby/concurrent}/constants.rb +1 -1
  68. data/lib/{concurrent → concurrent-ruby/concurrent}/dataflow.rb +2 -1
  69. data/lib/{concurrent → concurrent-ruby/concurrent}/delay.rb +9 -7
  70. data/lib/{concurrent → concurrent-ruby/concurrent}/errors.rb +0 -0
  71. data/lib/{concurrent → concurrent-ruby/concurrent}/exchanger.rb +21 -25
  72. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/abstract_executor_service.rb +19 -25
  73. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/cached_thread_pool.rb +5 -5
  74. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/executor_service.rb +17 -17
  75. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/fixed_thread_pool.rb +27 -30
  76. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/immediate_executor.rb +0 -0
  77. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/indirect_immediate_executor.rb +0 -0
  78. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_executor_service.rb +19 -16
  79. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_single_thread_executor.rb +4 -3
  80. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_thread_pool_executor.rb +12 -8
  81. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_executor_service.rb +0 -2
  82. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_single_thread_executor.rb +0 -1
  83. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_thread_pool_executor.rb +9 -4
  84. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/safe_task_executor.rb +0 -0
  85. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serial_executor_service.rb +0 -0
  86. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution.rb +0 -0
  87. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution_delegator.rb +0 -0
  88. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/simple_executor_service.rb +1 -1
  89. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/single_thread_executor.rb +3 -2
  90. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/thread_pool_executor.rb +6 -6
  91. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/timer_set.rb +14 -17
  92. data/lib/{concurrent → concurrent-ruby/concurrent}/executors.rb +0 -0
  93. data/lib/{concurrent → concurrent-ruby/concurrent}/future.rb +4 -1
  94. data/lib/concurrent-ruby/concurrent/hash.rb +59 -0
  95. data/lib/{concurrent → concurrent-ruby/concurrent}/immutable_struct.rb +8 -0
  96. data/lib/{concurrent → concurrent-ruby/concurrent}/ivar.rb +5 -6
  97. data/lib/concurrent-ruby/concurrent/map.rb +337 -0
  98. data/lib/{concurrent → concurrent-ruby/concurrent}/maybe.rb +1 -1
  99. data/lib/{concurrent → concurrent-ruby/concurrent}/mutable_struct.rb +25 -14
  100. data/lib/{concurrent → concurrent-ruby/concurrent}/mvar.rb +2 -2
  101. data/lib/{concurrent → concurrent-ruby/concurrent}/options.rb +0 -0
  102. data/lib/{concurrent → concurrent-ruby/concurrent}/promise.rb +53 -21
  103. data/lib/concurrent-ruby/concurrent/promises.rb +2167 -0
  104. data/lib/concurrent-ruby/concurrent/re_include.rb +58 -0
  105. data/lib/{concurrent → concurrent-ruby/concurrent}/scheduled_task.rb +0 -0
  106. data/lib/concurrent-ruby/concurrent/set.rb +66 -0
  107. data/lib/{concurrent → concurrent-ruby/concurrent}/settable_struct.rb +11 -0
  108. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization.rb +4 -5
  109. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_lockable_object.rb +5 -5
  110. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_object.rb +0 -0
  111. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_struct.rb +18 -4
  112. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/condition.rb +2 -0
  113. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_lockable_object.rb +0 -0
  114. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_object.rb +1 -0
  115. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lock.rb +2 -0
  116. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lockable_object.rb +6 -6
  117. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mri_object.rb +1 -0
  118. data/lib/{concurrent/synchronization/mri_lockable_object.rb → concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb} +19 -14
  119. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/object.rb +53 -23
  120. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_lockable_object.rb +0 -0
  121. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_object.rb +1 -0
  122. data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +47 -0
  123. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/volatile.rb +11 -9
  124. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/synchronized_delegator.rb +0 -0
  125. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util.rb +0 -0
  126. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/adder.rb +0 -0
  127. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/cheap_lockable.rb +0 -0
  128. data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +63 -0
  129. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/power_of_two_tuple.rb +0 -0
  130. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/striped64.rb +9 -4
  131. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/volatile.rb +0 -0
  132. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/xor_shift_random.rb +0 -0
  133. data/lib/{concurrent → concurrent-ruby/concurrent}/timer_task.rb +5 -2
  134. data/lib/{concurrent → concurrent-ruby/concurrent}/tuple.rb +1 -1
  135. data/lib/{concurrent → concurrent-ruby/concurrent}/tvar.rb +2 -2
  136. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/engine.rb +4 -4
  137. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/monotonic_time.rb +3 -3
  138. data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +79 -0
  139. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_integer.rb +0 -0
  140. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/processor_counter.rb +5 -2
  141. data/lib/concurrent-ruby/concurrent/version.rb +3 -0
  142. metadata +146 -131
  143. data/lib/concurrent/array.rb +0 -39
  144. data/lib/concurrent/atomic/atomic_reference.rb +0 -51
  145. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +0 -8
  146. data/lib/concurrent/atomic_reference/direct_update.rb +0 -81
  147. data/lib/concurrent/atomic_reference/jruby+truffle.rb +0 -2
  148. data/lib/concurrent/atomic_reference/jruby.rb +0 -16
  149. data/lib/concurrent/atomic_reference/rbx.rb +0 -22
  150. data/lib/concurrent/atomic_reference/ruby.rb +0 -32
  151. data/lib/concurrent/atomics.rb +0 -53
  152. data/lib/concurrent/edge.rb +0 -26
  153. data/lib/concurrent/hash.rb +0 -36
  154. data/lib/concurrent/lazy_register.rb +0 -81
  155. data/lib/concurrent/map.rb +0 -240
  156. data/lib/concurrent/synchronization/truffle_lockable_object.rb +0 -9
  157. data/lib/concurrent/synchronization/truffle_object.rb +0 -31
  158. data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +0 -30
  159. data/lib/concurrent/utility/at_exit.rb +0 -97
  160. data/lib/concurrent/utility/native_extension_loader.rb +0 -73
  161. data/lib/concurrent/version.rb +0 -4
@@ -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
+
@@ -91,6 +91,16 @@ module Concurrent
91
91
  raise NameError.new("no member '#{member}' in struct")
92
92
  end
93
93
 
94
+ private
95
+
96
+ # @!visibility private
97
+ def initialize_copy(original)
98
+ synchronize do
99
+ super(original)
100
+ ns_initialize_copy
101
+ end
102
+ end
103
+
94
104
  # @!macro struct_new
95
105
  def self.new(*args, &block)
96
106
  clazz_name = nil
@@ -107,6 +117,7 @@ module Concurrent
107
117
  synchronize do
108
118
  clazz = Synchronization::AbstractStruct.define_struct_class(SettableStruct, Synchronization::LockableObject, name, members, &block)
109
119
  members.each_with_index do |member, index|
120
+ clazz.send :remove_method, member if clazz.instance_methods.include? member
110
121
  clazz.send(:define_method, member) do
111
122
  synchronize { @values[index] }
112
123
  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
  #
@@ -115,9 +115,20 @@ module Concurrent
115
115
  self.class.new(*self.to_h.merge(other, &block).values)
116
116
  end
117
117
 
118
+ # @!visibility private
119
+ def ns_initialize_copy
120
+ @values = @values.map do |val|
121
+ begin
122
+ val.clone
123
+ rescue TypeError
124
+ val
125
+ end
126
+ end
127
+ end
128
+
118
129
  # @!visibility private
119
130
  def pr_underscore(clazz)
120
- word = clazz.to_s
131
+ word = clazz.to_s.dup # dup string to workaround JRuby 9.2.0.0 bug https://github.com/jruby/jruby/issues/5229
121
132
  word.gsub!(/::/, '/')
122
133
  word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
123
134
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
@@ -138,18 +149,21 @@ module Concurrent
138
149
  end
139
150
  unless name.nil?
140
151
  begin
152
+ parent.send :remove_const, name if parent.const_defined?(name, false)
141
153
  parent.const_set(name, clazz)
142
- parent.const_get(name)
154
+ clazz
143
155
  rescue NameError
144
156
  raise NameError.new("identifier #{name} needs to be constant")
145
157
  end
146
158
  end
147
159
  members.each_with_index do |member, index|
160
+ clazz.send :remove_method, member if clazz.instance_methods.include? member
148
161
  clazz.send(:define_method, member) do
149
162
  @values[index]
150
163
  end
151
164
  end
152
165
  clazz.class_exec(&block) unless block.nil?
166
+ clazz.singleton_class.send :alias_method, :[], :new
153
167
  clazz
154
168
  end
155
169
  end
@@ -1,5 +1,7 @@
1
1
  module Concurrent
2
2
  module Synchronization
3
+
4
+ # @!visibility private
3
5
  # TODO (pitr-ch 04-Dec-2016): should be in edge
4
6
  class Condition < LockableObject
5
7
  safe_initialization!
@@ -3,6 +3,7 @@ module Concurrent
3
3
 
4
4
  if Concurrent.on_jruby? && Concurrent.java_extensions_loaded?
5
5
 
6
+ # @!visibility private
6
7
  module JRubyAttrVolatile
7
8
  def self.included(base)
8
9
  base.extend(ClassMethods)
@@ -1,5 +1,7 @@
1
1
  module Concurrent
2
2
  module Synchronization
3
+
4
+ # @!visibility private
3
5
  # TODO (pitr-ch 04-Dec-2016): should be in edge
4
6
  class Lock < LockableObject
5
7
  # TODO use JavaReentrantLock on JRuby
@@ -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,6 +1,7 @@
1
1
  module Concurrent
2
2
  module Synchronization
3
3
 
4
+ # @!visibility private
4
5
  module MriAttrVolatile
5
6
  def self.included(base)
6
7
  base.extend(ClassMethods)
@@ -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