concurrent-ruby 0.9.2-java → 1.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -1
  3. data/README.md +86 -120
  4. data/lib/concurrent.rb +14 -5
  5. data/lib/concurrent/agent.rb +587 -0
  6. data/lib/concurrent/array.rb +39 -0
  7. data/lib/concurrent/async.rb +296 -149
  8. data/lib/concurrent/atom.rb +135 -45
  9. data/lib/concurrent/atomic/abstract_thread_local_var.rb +38 -0
  10. data/lib/concurrent/atomic/atomic_boolean.rb +83 -118
  11. data/lib/concurrent/atomic/atomic_fixnum.rb +101 -163
  12. data/lib/concurrent/atomic/atomic_reference.rb +1 -8
  13. data/lib/concurrent/atomic/count_down_latch.rb +62 -103
  14. data/lib/concurrent/atomic/cyclic_barrier.rb +3 -1
  15. data/lib/concurrent/atomic/event.rb +1 -1
  16. data/lib/concurrent/atomic/java_count_down_latch.rb +39 -0
  17. data/lib/concurrent/atomic/java_thread_local_var.rb +50 -0
  18. data/lib/concurrent/atomic/mutex_atomic_boolean.rb +60 -0
  19. data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +91 -0
  20. data/lib/concurrent/atomic/mutex_count_down_latch.rb +43 -0
  21. data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
  22. data/lib/concurrent/atomic/read_write_lock.rb +5 -4
  23. data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
  24. data/lib/concurrent/atomic/ruby_thread_local_var.rb +172 -0
  25. data/lib/concurrent/atomic/semaphore.rb +84 -178
  26. data/lib/concurrent/atomic/thread_local_var.rb +65 -294
  27. data/lib/concurrent/atomic_reference/jruby+truffle.rb +1 -0
  28. data/lib/concurrent/atomic_reference/jruby.rb +1 -1
  29. data/lib/concurrent/atomic_reference/mutex_atomic.rb +14 -8
  30. data/lib/concurrent/atomic_reference/ruby.rb +1 -1
  31. data/lib/concurrent/atomics.rb +7 -37
  32. data/lib/concurrent/collection/copy_on_notify_observer_set.rb +7 -15
  33. data/lib/concurrent/collection/copy_on_write_observer_set.rb +7 -15
  34. data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
  35. data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +927 -0
  36. data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
  37. data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +144 -0
  38. data/lib/concurrent/collection/map/synchronized_map_backend.rb +86 -0
  39. data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
  40. data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
  41. data/lib/concurrent/concern/dereferenceable.rb +9 -24
  42. data/lib/concurrent/concern/logging.rb +1 -1
  43. data/lib/concurrent/concern/obligation.rb +11 -20
  44. data/lib/concurrent/concern/observable.rb +38 -13
  45. data/lib/concurrent/configuration.rb +23 -152
  46. data/lib/concurrent/constants.rb +8 -0
  47. data/lib/concurrent/delay.rb +14 -12
  48. data/lib/concurrent/exchanger.rb +339 -41
  49. data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
  50. data/lib/concurrent/executor/executor_service.rb +23 -359
  51. data/lib/concurrent/executor/immediate_executor.rb +3 -2
  52. data/lib/concurrent/executor/java_executor_service.rb +100 -0
  53. data/lib/concurrent/executor/java_single_thread_executor.rb +3 -3
  54. data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -4
  55. data/lib/concurrent/executor/ruby_executor_service.rb +78 -0
  56. data/lib/concurrent/executor/ruby_single_thread_executor.rb +10 -66
  57. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +25 -22
  58. data/lib/concurrent/executor/safe_task_executor.rb +6 -7
  59. data/lib/concurrent/executor/serial_executor_service.rb +34 -0
  60. data/lib/concurrent/executor/serialized_execution.rb +10 -33
  61. data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
  62. data/lib/concurrent/executor/simple_executor_service.rb +1 -10
  63. data/lib/concurrent/executor/single_thread_executor.rb +20 -10
  64. data/lib/concurrent/executor/timer_set.rb +8 -10
  65. data/lib/concurrent/executors.rb +12 -2
  66. data/lib/concurrent/future.rb +6 -4
  67. data/lib/concurrent/hash.rb +35 -0
  68. data/lib/concurrent/immutable_struct.rb +5 -1
  69. data/lib/concurrent/ivar.rb +12 -16
  70. data/lib/concurrent/lazy_register.rb +11 -8
  71. data/lib/concurrent/map.rb +180 -0
  72. data/lib/concurrent/maybe.rb +6 -3
  73. data/lib/concurrent/mutable_struct.rb +7 -6
  74. data/lib/concurrent/mvar.rb +26 -2
  75. data/lib/concurrent/{executor/executor.rb → options.rb} +5 -29
  76. data/lib/concurrent/promise.rb +7 -5
  77. data/lib/concurrent/scheduled_task.rb +13 -71
  78. data/lib/concurrent/settable_struct.rb +5 -4
  79. data/lib/concurrent/synchronization.rb +15 -3
  80. data/lib/concurrent/synchronization/abstract_lockable_object.rb +98 -0
  81. data/lib/concurrent/synchronization/abstract_object.rb +7 -146
  82. data/lib/concurrent/synchronization/abstract_struct.rb +2 -3
  83. data/lib/concurrent/synchronization/condition.rb +6 -4
  84. data/lib/concurrent/synchronization/jruby_lockable_object.rb +13 -0
  85. data/lib/concurrent/synchronization/jruby_object.rb +44 -0
  86. data/lib/concurrent/synchronization/lock.rb +3 -2
  87. data/lib/concurrent/synchronization/lockable_object.rb +72 -0
  88. data/lib/concurrent/synchronization/mri_lockable_object.rb +71 -0
  89. data/lib/concurrent/synchronization/mri_object.rb +43 -0
  90. data/lib/concurrent/synchronization/object.rb +140 -73
  91. data/lib/concurrent/synchronization/rbx_lockable_object.rb +65 -0
  92. data/lib/concurrent/synchronization/rbx_object.rb +30 -73
  93. data/lib/concurrent/synchronization/volatile.rb +34 -0
  94. data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
  95. data/lib/concurrent/thread_safe/util.rb +14 -0
  96. data/lib/concurrent/thread_safe/util/adder.rb +74 -0
  97. data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +30 -0
  98. data/lib/concurrent/thread_safe/util/cheap_lockable.rb +118 -0
  99. data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +38 -0
  100. data/lib/concurrent/thread_safe/util/striped64.rb +241 -0
  101. data/lib/concurrent/thread_safe/util/volatile.rb +75 -0
  102. data/lib/concurrent/thread_safe/util/xor_shift_random.rb +50 -0
  103. data/lib/concurrent/timer_task.rb +3 -4
  104. data/lib/concurrent/tuple.rb +86 -0
  105. data/lib/concurrent/tvar.rb +5 -1
  106. data/lib/concurrent/utility/at_exit.rb +1 -1
  107. data/lib/concurrent/utility/engine.rb +4 -0
  108. data/lib/concurrent/utility/monotonic_time.rb +3 -4
  109. data/lib/concurrent/utility/native_extension_loader.rb +50 -30
  110. data/lib/concurrent/version.rb +2 -2
  111. data/lib/concurrent_ruby_ext.jar +0 -0
  112. metadata +47 -12
  113. data/lib/concurrent/atomic/condition.rb +0 -78
  114. data/lib/concurrent/collection/priority_queue.rb +0 -360
  115. data/lib/concurrent/synchronization/java_object.rb +0 -34
  116. data/lib/concurrent/synchronization/monitor_object.rb +0 -27
  117. data/lib/concurrent/synchronization/mutex_object.rb +0 -43
  118. data/lib/concurrent/utilities.rb +0 -5
  119. data/lib/concurrent/utility/timeout.rb +0 -39
  120. data/lib/concurrent/utility/timer.rb +0 -26
  121. data/lib/concurrent_ruby.rb +0 -2
@@ -1,12 +1,13 @@
1
+ require 'concurrent/constants'
1
2
  require 'concurrent/errors'
3
+ require 'concurrent/configuration'
2
4
  require 'concurrent/ivar'
3
5
  require 'concurrent/collection/copy_on_notify_observer_set'
4
- require 'concurrent/executor/executor'
5
6
  require 'concurrent/utility/monotonic_time'
6
- require 'concurrent/concern/deprecation'
7
7
 
8
8
  module Concurrent
9
- include Concern::Deprecation
9
+
10
+ autoload :Options, 'concurrent/options'
10
11
 
11
12
  # `ScheduledTask` is a close relative of `Concurrent::Future` but with one
12
13
  # important difference: A `Future` is set to execute as soon as possible
@@ -161,24 +162,20 @@ module Concurrent
161
162
  #
162
163
  # @raise [ArgumentError] When no block is given
163
164
  # @raise [ArgumentError] When given a time that is in the past
164
- #
165
- # @!macro [attach] deprecated_scheduling_by_clock_time
166
- #
167
- # @note Scheduling is now based on a monotonic clock. This makes the timer much
168
- # more accurate, but only when scheduling based on a delay interval.
169
- # Scheduling a task based on a clock time is deprecated. It will still work
170
- # but will not be supported in the 1.0 release.
171
165
  def initialize(delay, opts = {}, &task)
172
166
  raise ArgumentError.new('no block given') unless block_given?
173
- super(IVar::NO_VALUE, opts, &nil)
167
+ raise ArgumentError.new('seconds must be greater than zero') if delay.to_f < 0.0
168
+
169
+ super(NULL, opts, &nil)
170
+
174
171
  synchronize do
175
- @delay = calculate_delay!(delay) # may raise exception
176
172
  ns_set_state(:unscheduled)
177
173
  @parent = opts.fetch(:timer_set, Concurrent.global_timer_set)
178
174
  @args = get_arguments_from(opts)
175
+ @delay = delay.to_f
179
176
  @task = task
180
177
  @time = nil
181
- @executor = Executor.executor_from_options(opts) || Concurrent.global_io_executor
178
+ @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor
182
179
  self.observers = Collection::CopyOnNotifyObserverSet.new
183
180
  end
184
181
  end
@@ -190,16 +187,6 @@ module Concurrent
190
187
  synchronize { @delay }
191
188
  end
192
189
 
193
- # The `delay` value given at instanciation.
194
- #
195
- # @return [Float] the initial delay.
196
- #
197
- # @deprecated use {#initial_delay} instead
198
- def delay
199
- deprecated_method 'delay', 'initial_delay'
200
- initial_delay
201
- end
202
-
203
190
  # The monotonic time at which the the task is scheduled to be executed.
204
191
  #
205
192
  # @return [Float] the schedule time or nil if `unscheduled`
@@ -228,16 +215,6 @@ module Concurrent
228
215
  synchronize { ns_check_state?(:processing) }
229
216
  end
230
217
 
231
- # In the task execution in progress?
232
- #
233
- # @return [Boolean] true if the task is in the given state else false
234
- #
235
- # @deprecated Use {#processing?} instead.
236
- def in_progress?
237
- deprecated_method 'in_progress?', 'processing?'
238
- processing?
239
- end
240
-
241
218
  # Cancel this task and prevent it from executing. A task can only be
242
219
  # cancelled if it is pending or unscheduled.
243
220
  #
@@ -253,17 +230,6 @@ module Concurrent
253
230
  end
254
231
  end
255
232
 
256
- # Cancel this task and prevent it from executing. A task can only be
257
- # cancelled if it is `:pending` or `:unscheduled`.
258
- #
259
- # @return [Boolean] true if successfully cancelled else false
260
- #
261
- # @deprecated Use {#cancel} instead.
262
- def stop
263
- deprecated_method 'stop', 'cancel'
264
- cancel
265
- end
266
-
267
233
  # Reschedule the task using the original delay and the current time.
268
234
  # A task can only be reset while it is `:pending`.
269
235
  #
@@ -281,7 +247,9 @@ module Concurrent
281
247
  #
282
248
  # @raise [ArgumentError] When given a time that is in the past
283
249
  def reschedule(delay)
284
- synchronize{ ns_reschedule(calculate_delay!(delay)) }
250
+ delay = delay.to_f
251
+ raise ArgumentError.new('seconds must be greater than zero') if delay < 0.0
252
+ synchronize{ ns_reschedule(delay) }
285
253
  end
286
254
 
287
255
  # Execute an `:unscheduled` `ScheduledTask`. Immediately sets the state to `:pending`
@@ -306,8 +274,6 @@ module Concurrent
306
274
  # @return [ScheduledTask] the newly created `ScheduledTask` in the `:pending` state
307
275
  #
308
276
  # @raise [ArgumentError] if no block is given
309
- #
310
- # @!macro deprecated_scheduling_by_clock_time
311
277
  def self.execute(delay, opts = {}, &task)
312
278
  new(delay, opts, &task).execute
313
279
  end
@@ -348,29 +314,5 @@ module Concurrent
348
314
  return false unless ns_check_state?(:pending)
349
315
  @parent.send(:remove_task, self) && ns_schedule(delay)
350
316
  end
351
-
352
- # Calculate the actual delay in seconds based on the given delay.
353
- #
354
- # @param [Float] delay the number of seconds to wait for before executing the task
355
- #
356
- # @return [Float] the number of seconds to delay
357
- #
358
- # @raise [ArgumentError] if the intended execution time is not in the future
359
- # @raise [ArgumentError] if no block is given
360
- #
361
- # @!macro deprecated_scheduling_by_clock_time
362
- #
363
- # @!visibility private
364
- def calculate_delay!(delay)
365
- if delay.is_a?(Time)
366
- deprecated 'Use an interval not a clock time; schedule is now based on a monotonic clock'
367
- now = Time.now
368
- raise ArgumentError.new('schedule time must be in the future') if delay <= now
369
- delay.to_f - now.to_f
370
- else
371
- raise ArgumentError.new('seconds must be greater than zero') if delay.to_f < 0.0
372
- delay.to_f
373
- end
374
- end
375
317
  end
376
318
  end
@@ -74,8 +74,9 @@ module Concurrent
74
74
  # @raise [Concurrent::ImmutabilityError] if the given member has already been set
75
75
  def []=(member, value)
76
76
  if member.is_a? Integer
77
- if member >= @values.length
78
- raise IndexError.new("offset #{member} too large for struct(size:#{@values.length})")
77
+ length = synchronize { @values.length }
78
+ if member >= length
79
+ raise IndexError.new("offset #{member} too large for struct(size:#{length})")
79
80
  end
80
81
  synchronize do
81
82
  unless @values[member].nil?
@@ -101,10 +102,10 @@ module Concurrent
101
102
  FACTORY.define_struct(clazz_name, args, &block)
102
103
  end
103
104
 
104
- FACTORY = Class.new(Synchronization::Object) do
105
+ FACTORY = Class.new(Synchronization::LockableObject) do
105
106
  def define_struct(name, members, &block)
106
107
  synchronize do
107
- clazz = Synchronization::AbstractStruct.define_struct_class(SettableStruct, Synchronization::Object, name, members, &block)
108
+ clazz = Synchronization::AbstractStruct.define_struct_class(SettableStruct, Synchronization::LockableObject, name, members, &block)
108
109
  members.each_with_index do |member, index|
109
110
  clazz.send(:define_method, member) do
110
111
  synchronize { @values[index] }
@@ -1,16 +1,28 @@
1
1
  require 'concurrent/utility/engine'
2
+
2
3
  require 'concurrent/synchronization/abstract_object'
3
- require 'concurrent/synchronization/java_object'
4
- require 'concurrent/synchronization/mutex_object'
5
- require 'concurrent/synchronization/monitor_object'
4
+ require 'concurrent/utility/native_extension_loader' # load native parts first
5
+ Concurrent.load_native_extensions
6
+
7
+ require 'concurrent/synchronization/mri_object'
8
+ require 'concurrent/synchronization/jruby_object'
6
9
  require 'concurrent/synchronization/rbx_object'
7
10
  require 'concurrent/synchronization/object'
11
+ require 'concurrent/synchronization/volatile'
12
+
13
+ require 'concurrent/synchronization/abstract_lockable_object'
14
+ require 'concurrent/synchronization/mri_lockable_object'
15
+ require 'concurrent/synchronization/jruby_lockable_object'
16
+ require 'concurrent/synchronization/rbx_lockable_object'
17
+
18
+ require 'concurrent/synchronization/lockable_object'
8
19
 
9
20
  require 'concurrent/synchronization/condition'
10
21
  require 'concurrent/synchronization/lock'
11
22
 
12
23
  module Concurrent
13
24
  # {include:file:doc/synchronization.md}
25
+ # {include:file:doc/synchronization-notes.md}
14
26
  module Synchronization
15
27
  end
16
28
  end
@@ -0,0 +1,98 @@
1
+ module Concurrent
2
+ module Synchronization
3
+
4
+ # @!visibility private
5
+ class AbstractLockableObject < Object
6
+
7
+ protected
8
+
9
+ # @!macro [attach] synchronization_object_method_synchronize
10
+ #
11
+ # @yield runs the block synchronized against this object,
12
+ # equivalent of java's `synchronize(this) {}`
13
+ # @note can by made public in descendants if required by `public :synchronize`
14
+ def synchronize
15
+ raise NotImplementedError
16
+ end
17
+
18
+ # @!macro [attach] synchronization_object_method_ns_wait_until
19
+ #
20
+ # Wait until condition is met or timeout passes,
21
+ # protects against spurious wake-ups.
22
+ # @param [Numeric, nil] timeout in seconds, `nil` means no timeout
23
+ # @yield condition to be met
24
+ # @yieldreturn [true, false]
25
+ # @return [true, false] if condition met
26
+ # @note only to be used inside synchronized block
27
+ # @note to provide direct access to this method in a descendant add method
28
+ # ```
29
+ # def wait_until(timeout = nil, &condition)
30
+ # synchronize { ns_wait_until(timeout, &condition) }
31
+ # end
32
+ # ```
33
+ def ns_wait_until(timeout = nil, &condition)
34
+ if timeout
35
+ wait_until = Concurrent.monotonic_time + timeout
36
+ loop do
37
+ now = Concurrent.monotonic_time
38
+ condition_result = condition.call
39
+ return condition_result if now >= wait_until || condition_result
40
+ ns_wait wait_until - now
41
+ end
42
+ else
43
+ ns_wait timeout until condition.call
44
+ true
45
+ end
46
+ end
47
+
48
+ # @!macro [attach] synchronization_object_method_ns_wait
49
+ #
50
+ # Wait until another thread calls #signal or #broadcast,
51
+ # spurious wake-ups can happen.
52
+ #
53
+ # @param [Numeric, nil] timeout in seconds, `nil` means no timeout
54
+ # @return [self]
55
+ # @note only to be used inside synchronized block
56
+ # @note to provide direct access to this method in a descendant add method
57
+ # ```
58
+ # def wait(timeout = nil)
59
+ # synchronize { ns_wait(timeout) }
60
+ # end
61
+ # ```
62
+ def ns_wait(timeout = nil)
63
+ raise NotImplementedError
64
+ end
65
+
66
+ # @!macro [attach] synchronization_object_method_ns_signal
67
+ #
68
+ # Signal one waiting thread.
69
+ # @return [self]
70
+ # @note only to be used inside synchronized block
71
+ # @note to provide direct access to this method in a descendant add method
72
+ # ```
73
+ # def signal
74
+ # synchronize { ns_signal }
75
+ # end
76
+ # ```
77
+ def ns_signal
78
+ raise NotImplementedError
79
+ end
80
+
81
+ # @!macro [attach] synchronization_object_method_ns_broadcast
82
+ #
83
+ # Broadcast to all waiting threads.
84
+ # @return [self]
85
+ # @note only to be used inside synchronized block
86
+ # @note to provide direct access to this method in a descendant add method
87
+ # ```
88
+ # def broadcast
89
+ # synchronize { ns_broadcast }
90
+ # end
91
+ # ```
92
+ def ns_broadcast
93
+ raise NotImplementedError
94
+ end
95
+
96
+ end
97
+ end
98
+ end
@@ -1,162 +1,23 @@
1
1
  module Concurrent
2
2
  module Synchronization
3
3
 
4
- # @!macro synchronization_object
5
4
  # @!visibility private
5
+ # @!macro internal_implementation_note
6
6
  class AbstractObject
7
7
 
8
- # @!macro [attach] synchronization_object_method_initialize
9
- #
10
- # @abstract for helper ivar initialization if needed,
11
- # otherwise it can be left empty. It has to call ns_initialize.
12
- def initialize(*args, &block)
8
+ # @abstract has to be implemented based on Ruby runtime
9
+ def initialize
13
10
  raise NotImplementedError
14
11
  end
15
12
 
16
- protected
17
-
18
- # @!macro [attach] synchronization_object_method_synchronize
19
- #
20
- # @yield runs the block synchronized against this object,
21
- # equivalent of java's `synchronize(this) {}`
22
- # @note can by made public in descendants if required by `public :synchronize`
23
- def synchronize
24
- raise NotImplementedError
25
- end
26
-
27
- # @!macro [attach] synchronization_object_method_ns_initialize
28
- #
29
- # initialization of the object called inside synchronize block
30
- # @note has to be called manually when required in children of this class
31
- # @example
32
- # class Child < Concurrent::Synchornization::Object
33
- # def initialize(*args, &block)
34
- # super(&nil)
35
- # synchronize { ns_initialize(*args, &block) }
36
- # end
37
- #
38
- # def ns_initialize(*args, &block)
39
- # @args = args
40
- # end
41
- # end
42
- def ns_initialize(*args, &block)
43
- end
44
-
45
- # @!macro [attach] synchronization_object_method_ns_wait_until
46
- #
47
- # Wait until condition is met or timeout passes,
48
- # protects against spurious wake-ups.
49
- # @param [Numeric, nil] timeout in seconds, `nil` means no timeout
50
- # @yield condition to be met
51
- # @yieldreturn [true, false]
52
- # @return [true, false] if condition met
53
- # @note only to be used inside synchronized block
54
- # @note to provide direct access to this method in a descendant add method
55
- # ```
56
- # def wait_until(timeout = nil, &condition)
57
- # synchronize { ns_wait_until(timeout, &condition) }
58
- # end
59
- # ```
60
- def ns_wait_until(timeout = nil, &condition)
61
- if timeout
62
- wait_until = Concurrent.monotonic_time + timeout
63
- loop do
64
- now = Concurrent.monotonic_time
65
- condition_result = condition.call
66
- # 0.001 correction to avoid error when `wait_until - now` is smaller than 0.0005 and rounded to 0
67
- # when passed to java #wait(long timeout)
68
- return condition_result if (now + 0.001) >= wait_until || condition_result
69
- ns_wait wait_until - now
70
- end
71
- else
72
- ns_wait timeout until condition.call
73
- true
74
- end
75
- end
76
-
77
- # @!macro [attach] synchronization_object_method_ns_wait
78
- #
79
- # Wait until another thread calls #signal or #broadcast,
80
- # spurious wake-ups can happen.
81
- #
82
- # @param [Numeric, nil] timeout in seconds, `nil` means no timeout
83
- # @return [self]
84
- # @note only to be used inside synchronized block
85
- # @note to provide direct access to this method in a descendant add method
86
- # ```
87
- # def wait(timeout = nil)
88
- # synchronize { ns_wait(timeout) }
89
- # end
90
- # ```
91
- def ns_wait(timeout = nil)
13
+ # @!visibility private
14
+ # @abstract
15
+ def full_memory_barrier
92
16
  raise NotImplementedError
93
17
  end
94
18
 
95
- # @!macro [attach] synchronization_object_method_ns_signal
96
- #
97
- # Signal one waiting thread.
98
- # @return [self]
99
- # @note only to be used inside synchronized block
100
- # @note to provide direct access to this method in a descendant add method
101
- # ```
102
- # def signal
103
- # synchronize { ns_signal }
104
- # end
105
- # ```
106
- def ns_signal
107
- raise NotImplementedError
108
- end
109
-
110
- # @!macro [attach] synchronization_object_method_ns_broadcast
111
- #
112
- # Broadcast to all waiting threads.
113
- # @return [self]
114
- # @note only to be used inside synchronized block
115
- # @note to provide direct access to this method in a descendant add method
116
- # ```
117
- # def broadcast
118
- # synchronize { ns_broadcast }
119
- # end
120
- # ```
121
- def ns_broadcast
122
- raise NotImplementedError
123
- end
124
-
125
- # @!macro [attach] synchronization_object_method_ensure_ivar_visibility
126
- #
127
- # Allows to construct immutable objects where all fields are visible after initialization, not requiring
128
- # further synchronization on access.
129
- # @example
130
- # class AClass
131
- # attr_reader :val
132
- # def initialize(val)
133
- # @val = val # final value, after assignment it's not changed (just convention, not enforced)
134
- # ensure_ivar_visibility!
135
- # # now it can be shared as Java's final field
136
- # end
137
- # end
138
- def ensure_ivar_visibility!
139
- raise NotImplementedError
140
- end
141
-
142
- # @!macro [attach] synchronization_object_method_self_attr_volatile
143
- #
144
- # creates methods for reading and writing to a instance variable with volatile (Java semantic) instance variable
145
- # return [Array<Symbol>] names of defined method names
146
19
  def self.attr_volatile(*names)
147
- names.each do |name|
148
- ivar = :"@volatile_#{name}"
149
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
150
- def #{name}
151
- #{ivar}
152
- end
153
-
154
- def #{name}=(value)
155
- #{ivar} = value
156
- end
157
- RUBY
158
- end
159
- names.map { |n| [n, :"#{n}="] }.flatten
20
+ raise NotImplementedError
160
21
  end
161
22
  end
162
23
  end