concurrent-ruby 1.1.5
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 +7 -0
- data/CHANGELOG.md +478 -0
- data/Gemfile +41 -0
- data/LICENSE.md +23 -0
- data/README.md +381 -0
- data/Rakefile +327 -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.rb +1 -0
- data/lib/concurrent.rb +134 -0
- data/lib/concurrent/agent.rb +587 -0
- data/lib/concurrent/array.rb +66 -0
- data/lib/concurrent/async.rb +459 -0
- data/lib/concurrent/atom.rb +222 -0
- data/lib/concurrent/atomic/abstract_thread_local_var.rb +66 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +126 -0
- data/lib/concurrent/atomic/atomic_fixnum.rb +143 -0
- data/lib/concurrent/atomic/atomic_markable_reference.rb +164 -0
- data/lib/concurrent/atomic/atomic_reference.rb +204 -0
- data/lib/concurrent/atomic/count_down_latch.rb +100 -0
- data/lib/concurrent/atomic/cyclic_barrier.rb +128 -0
- data/lib/concurrent/atomic/event.rb +109 -0
- data/lib/concurrent/atomic/java_count_down_latch.rb +42 -0
- data/lib/concurrent/atomic/java_thread_local_var.rb +37 -0
- data/lib/concurrent/atomic/mutex_atomic_boolean.rb +62 -0
- data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +75 -0
- data/lib/concurrent/atomic/mutex_count_down_latch.rb +44 -0
- data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
- data/lib/concurrent/atomic/read_write_lock.rb +254 -0
- data/lib/concurrent/atomic/reentrant_read_write_lock.rb +379 -0
- data/lib/concurrent/atomic/ruby_thread_local_var.rb +161 -0
- data/lib/concurrent/atomic/semaphore.rb +145 -0
- data/lib/concurrent/atomic/thread_local_var.rb +104 -0
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +56 -0
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +28 -0
- data/lib/concurrent/atomics.rb +10 -0
- data/lib/concurrent/collection/copy_on_notify_observer_set.rb +107 -0
- data/lib/concurrent/collection/copy_on_write_observer_set.rb +111 -0
- data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
- data/lib/concurrent/collection/lock_free_stack.rb +158 -0
- data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +927 -0
- data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
- data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +140 -0
- data/lib/concurrent/collection/map/synchronized_map_backend.rb +82 -0
- data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
- data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
- data/lib/concurrent/concern/deprecation.rb +34 -0
- data/lib/concurrent/concern/dereferenceable.rb +73 -0
- data/lib/concurrent/concern/logging.rb +32 -0
- data/lib/concurrent/concern/obligation.rb +220 -0
- data/lib/concurrent/concern/observable.rb +110 -0
- data/lib/concurrent/concurrent_ruby.jar +0 -0
- data/lib/concurrent/configuration.rb +184 -0
- data/lib/concurrent/constants.rb +8 -0
- data/lib/concurrent/dataflow.rb +81 -0
- data/lib/concurrent/delay.rb +199 -0
- data/lib/concurrent/errors.rb +69 -0
- data/lib/concurrent/exchanger.rb +352 -0
- data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
- data/lib/concurrent/executor/cached_thread_pool.rb +62 -0
- data/lib/concurrent/executor/executor_service.rb +185 -0
- data/lib/concurrent/executor/fixed_thread_pool.rb +206 -0
- data/lib/concurrent/executor/immediate_executor.rb +66 -0
- data/lib/concurrent/executor/indirect_immediate_executor.rb +44 -0
- data/lib/concurrent/executor/java_executor_service.rb +91 -0
- data/lib/concurrent/executor/java_single_thread_executor.rb +29 -0
- data/lib/concurrent/executor/java_thread_pool_executor.rb +123 -0
- data/lib/concurrent/executor/ruby_executor_service.rb +78 -0
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +22 -0
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +362 -0
- data/lib/concurrent/executor/safe_task_executor.rb +35 -0
- data/lib/concurrent/executor/serial_executor_service.rb +34 -0
- data/lib/concurrent/executor/serialized_execution.rb +107 -0
- data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
- data/lib/concurrent/executor/simple_executor_service.rb +100 -0
- data/lib/concurrent/executor/single_thread_executor.rb +56 -0
- data/lib/concurrent/executor/thread_pool_executor.rb +87 -0
- data/lib/concurrent/executor/timer_set.rb +173 -0
- data/lib/concurrent/executors.rb +20 -0
- data/lib/concurrent/future.rb +141 -0
- data/lib/concurrent/hash.rb +59 -0
- data/lib/concurrent/immutable_struct.rb +93 -0
- data/lib/concurrent/ivar.rb +207 -0
- data/lib/concurrent/map.rb +337 -0
- data/lib/concurrent/maybe.rb +229 -0
- data/lib/concurrent/mutable_struct.rb +229 -0
- data/lib/concurrent/mvar.rb +242 -0
- data/lib/concurrent/options.rb +42 -0
- data/lib/concurrent/promise.rb +579 -0
- data/lib/concurrent/promises.rb +2167 -0
- data/lib/concurrent/re_include.rb +58 -0
- data/lib/concurrent/scheduled_task.rb +318 -0
- data/lib/concurrent/set.rb +66 -0
- data/lib/concurrent/settable_struct.rb +129 -0
- data/lib/concurrent/synchronization.rb +30 -0
- data/lib/concurrent/synchronization/abstract_lockable_object.rb +98 -0
- data/lib/concurrent/synchronization/abstract_object.rb +24 -0
- data/lib/concurrent/synchronization/abstract_struct.rb +160 -0
- data/lib/concurrent/synchronization/condition.rb +60 -0
- data/lib/concurrent/synchronization/jruby_lockable_object.rb +13 -0
- data/lib/concurrent/synchronization/jruby_object.rb +45 -0
- data/lib/concurrent/synchronization/lock.rb +36 -0
- data/lib/concurrent/synchronization/lockable_object.rb +74 -0
- data/lib/concurrent/synchronization/mri_object.rb +44 -0
- data/lib/concurrent/synchronization/mutex_lockable_object.rb +76 -0
- data/lib/concurrent/synchronization/object.rb +183 -0
- data/lib/concurrent/synchronization/rbx_lockable_object.rb +65 -0
- data/lib/concurrent/synchronization/rbx_object.rb +49 -0
- data/lib/concurrent/synchronization/truffleruby_object.rb +47 -0
- data/lib/concurrent/synchronization/volatile.rb +36 -0
- data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
- data/lib/concurrent/thread_safe/util.rb +16 -0
- data/lib/concurrent/thread_safe/util/adder.rb +74 -0
- data/lib/concurrent/thread_safe/util/cheap_lockable.rb +118 -0
- data/lib/concurrent/thread_safe/util/data_structures.rb +63 -0
- data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +38 -0
- data/lib/concurrent/thread_safe/util/striped64.rb +246 -0
- data/lib/concurrent/thread_safe/util/volatile.rb +75 -0
- data/lib/concurrent/thread_safe/util/xor_shift_random.rb +50 -0
- data/lib/concurrent/timer_task.rb +334 -0
- data/lib/concurrent/tuple.rb +86 -0
- data/lib/concurrent/tvar.rb +258 -0
- data/lib/concurrent/utility/at_exit.rb +97 -0
- data/lib/concurrent/utility/engine.rb +56 -0
- data/lib/concurrent/utility/monotonic_time.rb +58 -0
- data/lib/concurrent/utility/native_extension_loader.rb +79 -0
- data/lib/concurrent/utility/native_integer.rb +53 -0
- data/lib/concurrent/utility/processor_counter.rb +158 -0
- data/lib/concurrent/version.rb +3 -0
- metadata +193 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'concurrent/utility/engine'
|
2
|
+
|
3
|
+
require 'concurrent/synchronization/abstract_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'
|
9
|
+
require 'concurrent/synchronization/rbx_object'
|
10
|
+
require 'concurrent/synchronization/truffleruby_object'
|
11
|
+
require 'concurrent/synchronization/object'
|
12
|
+
require 'concurrent/synchronization/volatile'
|
13
|
+
|
14
|
+
require 'concurrent/synchronization/abstract_lockable_object'
|
15
|
+
require 'concurrent/synchronization/mutex_lockable_object'
|
16
|
+
require 'concurrent/synchronization/jruby_lockable_object'
|
17
|
+
require 'concurrent/synchronization/rbx_lockable_object'
|
18
|
+
|
19
|
+
require 'concurrent/synchronization/lockable_object'
|
20
|
+
|
21
|
+
require 'concurrent/synchronization/condition'
|
22
|
+
require 'concurrent/synchronization/lock'
|
23
|
+
|
24
|
+
module Concurrent
|
25
|
+
# {include:file:docs-source/synchronization.md}
|
26
|
+
# {include:file:docs-source/synchronization-notes.md}
|
27
|
+
module Synchronization
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
# @!visibility private
|
5
|
+
class AbstractLockableObject < Synchronization::Object
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
# @!macro 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 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 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 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 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
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
# @!visibility private
|
5
|
+
# @!macro internal_implementation_note
|
6
|
+
class AbstractObject
|
7
|
+
|
8
|
+
# @abstract has to be implemented based on Ruby runtime
|
9
|
+
def initialize
|
10
|
+
raise NotImplementedError
|
11
|
+
end
|
12
|
+
|
13
|
+
# @!visibility private
|
14
|
+
# @abstract
|
15
|
+
def full_memory_barrier
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.attr_volatile(*names)
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
# @!visibility private
|
5
|
+
# @!macro internal_implementation_note
|
6
|
+
module AbstractStruct
|
7
|
+
|
8
|
+
# @!visibility private
|
9
|
+
def initialize(*values)
|
10
|
+
super()
|
11
|
+
ns_initialize(*values)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @!macro struct_length
|
15
|
+
#
|
16
|
+
# Returns the number of struct members.
|
17
|
+
#
|
18
|
+
# @return [Fixnum] the number of struct members
|
19
|
+
def length
|
20
|
+
self.class::MEMBERS.length
|
21
|
+
end
|
22
|
+
alias_method :size, :length
|
23
|
+
|
24
|
+
# @!macro struct_members
|
25
|
+
#
|
26
|
+
# Returns the struct members as an array of symbols.
|
27
|
+
#
|
28
|
+
# @return [Array] the struct members as an array of symbols
|
29
|
+
def members
|
30
|
+
self.class::MEMBERS.dup
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
# @!macro struct_values
|
36
|
+
#
|
37
|
+
# @!visibility private
|
38
|
+
def ns_values
|
39
|
+
@values.dup
|
40
|
+
end
|
41
|
+
|
42
|
+
# @!macro struct_values_at
|
43
|
+
#
|
44
|
+
# @!visibility private
|
45
|
+
def ns_values_at(indexes)
|
46
|
+
@values.values_at(*indexes)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @!macro struct_to_h
|
50
|
+
#
|
51
|
+
# @!visibility private
|
52
|
+
def ns_to_h
|
53
|
+
length.times.reduce({}){|memo, i| memo[self.class::MEMBERS[i]] = @values[i]; memo}
|
54
|
+
end
|
55
|
+
|
56
|
+
# @!macro struct_get
|
57
|
+
#
|
58
|
+
# @!visibility private
|
59
|
+
def ns_get(member)
|
60
|
+
if member.is_a? Integer
|
61
|
+
if member >= @values.length
|
62
|
+
raise IndexError.new("offset #{member} too large for struct(size:#{@values.length})")
|
63
|
+
end
|
64
|
+
@values[member]
|
65
|
+
else
|
66
|
+
send(member)
|
67
|
+
end
|
68
|
+
rescue NoMethodError
|
69
|
+
raise NameError.new("no member '#{member}' in struct")
|
70
|
+
end
|
71
|
+
|
72
|
+
# @!macro struct_equality
|
73
|
+
#
|
74
|
+
# @!visibility private
|
75
|
+
def ns_equality(other)
|
76
|
+
self.class == other.class && self.values == other.values
|
77
|
+
end
|
78
|
+
|
79
|
+
# @!macro struct_each
|
80
|
+
#
|
81
|
+
# @!visibility private
|
82
|
+
def ns_each
|
83
|
+
values.each{|value| yield value }
|
84
|
+
end
|
85
|
+
|
86
|
+
# @!macro struct_each_pair
|
87
|
+
#
|
88
|
+
# @!visibility private
|
89
|
+
def ns_each_pair
|
90
|
+
@values.length.times do |index|
|
91
|
+
yield self.class::MEMBERS[index], @values[index]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# @!macro struct_select
|
96
|
+
#
|
97
|
+
# @!visibility private
|
98
|
+
def ns_select
|
99
|
+
values.select{|value| yield value }
|
100
|
+
end
|
101
|
+
|
102
|
+
# @!macro struct_inspect
|
103
|
+
#
|
104
|
+
# @!visibility private
|
105
|
+
def ns_inspect
|
106
|
+
struct = pr_underscore(self.class.ancestors[1])
|
107
|
+
clazz = ((self.class.to_s =~ /^#<Class:/) == 0) ? '' : " #{self.class}"
|
108
|
+
"#<#{struct}#{clazz} #{ns_to_h}>"
|
109
|
+
end
|
110
|
+
|
111
|
+
# @!macro struct_merge
|
112
|
+
#
|
113
|
+
# @!visibility private
|
114
|
+
def ns_merge(other, &block)
|
115
|
+
self.class.new(*self.to_h.merge(other, &block).values)
|
116
|
+
end
|
117
|
+
|
118
|
+
# @!visibility private
|
119
|
+
def pr_underscore(clazz)
|
120
|
+
word = clazz.to_s.dup # dup string to workaround JRuby 9.2.0.0 bug https://github.com/jruby/jruby/issues/5229
|
121
|
+
word.gsub!(/::/, '/')
|
122
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
123
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
124
|
+
word.tr!("-", "_")
|
125
|
+
word.downcase!
|
126
|
+
word
|
127
|
+
end
|
128
|
+
|
129
|
+
# @!visibility private
|
130
|
+
def self.define_struct_class(parent, base, name, members, &block)
|
131
|
+
clazz = Class.new(base || Object) do
|
132
|
+
include parent
|
133
|
+
self.const_set(:MEMBERS, members.collect{|member| member.to_s.to_sym}.freeze)
|
134
|
+
def ns_initialize(*values)
|
135
|
+
raise ArgumentError.new('struct size differs') if values.length > length
|
136
|
+
@values = values.fill(nil, values.length..length-1)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
unless name.nil?
|
140
|
+
begin
|
141
|
+
parent.send :remove_const, name if parent.const_defined?(name, false)
|
142
|
+
parent.const_set(name, clazz)
|
143
|
+
clazz
|
144
|
+
rescue NameError
|
145
|
+
raise NameError.new("identifier #{name} needs to be constant")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
members.each_with_index do |member, index|
|
149
|
+
clazz.send :remove_method, member if clazz.instance_methods.include? member
|
150
|
+
clazz.send(:define_method, member) do
|
151
|
+
@values[index]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
clazz.class_exec(&block) unless block.nil?
|
155
|
+
clazz.singleton_class.send :alias_method, :[], :new
|
156
|
+
clazz
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
# @!visibility private
|
5
|
+
# TODO (pitr-ch 04-Dec-2016): should be in edge
|
6
|
+
class Condition < LockableObject
|
7
|
+
safe_initialization!
|
8
|
+
|
9
|
+
# TODO (pitr 12-Sep-2015): locks two objects, improve
|
10
|
+
# TODO (pitr 26-Sep-2015): study
|
11
|
+
# http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/concurrent/locks/AbstractQueuedSynchronizer.java#AbstractQueuedSynchronizer.Node
|
12
|
+
|
13
|
+
singleton_class.send :alias_method, :private_new, :new
|
14
|
+
private_class_method :new
|
15
|
+
|
16
|
+
def initialize(lock)
|
17
|
+
super()
|
18
|
+
@Lock = lock
|
19
|
+
end
|
20
|
+
|
21
|
+
def wait(timeout = nil)
|
22
|
+
@Lock.synchronize { ns_wait(timeout) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def ns_wait(timeout = nil)
|
26
|
+
synchronize { super(timeout) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def wait_until(timeout = nil, &condition)
|
30
|
+
@Lock.synchronize { ns_wait_until(timeout, &condition) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def ns_wait_until(timeout = nil, &condition)
|
34
|
+
synchronize { super(timeout, &condition) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def signal
|
38
|
+
@Lock.synchronize { ns_signal }
|
39
|
+
end
|
40
|
+
|
41
|
+
def ns_signal
|
42
|
+
synchronize { super }
|
43
|
+
end
|
44
|
+
|
45
|
+
def broadcast
|
46
|
+
@Lock.synchronize { ns_broadcast }
|
47
|
+
end
|
48
|
+
|
49
|
+
def ns_broadcast
|
50
|
+
synchronize { super }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class LockableObject < LockableObjectImplementation
|
55
|
+
def new_condition
|
56
|
+
Condition.private_new(self)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
if Concurrent.on_jruby? && Concurrent.java_extensions_loaded?
|
5
|
+
|
6
|
+
# @!visibility private
|
7
|
+
# @!macro internal_implementation_note
|
8
|
+
class JRubyLockableObject < AbstractLockableObject
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
if Concurrent.on_jruby? && Concurrent.java_extensions_loaded?
|
5
|
+
|
6
|
+
# @!visibility private
|
7
|
+
module JRubyAttrVolatile
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def attr_volatile(*names)
|
14
|
+
names.each do |name|
|
15
|
+
|
16
|
+
ivar = :"@volatile_#{name}"
|
17
|
+
|
18
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
19
|
+
def #{name}
|
20
|
+
instance_variable_get_volatile(:#{ivar})
|
21
|
+
end
|
22
|
+
|
23
|
+
def #{name}=(value)
|
24
|
+
instance_variable_set_volatile(:#{ivar}, value)
|
25
|
+
end
|
26
|
+
RUBY
|
27
|
+
|
28
|
+
end
|
29
|
+
names.map { |n| [n, :"#{n}="] }.flatten
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @!visibility private
|
35
|
+
# @!macro internal_implementation_note
|
36
|
+
class JRubyObject < AbstractObject
|
37
|
+
include JRubyAttrVolatile
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
# nothing to do
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
# @!visibility private
|
5
|
+
# TODO (pitr-ch 04-Dec-2016): should be in edge
|
6
|
+
class Lock < LockableObject
|
7
|
+
# TODO use JavaReentrantLock on JRuby
|
8
|
+
|
9
|
+
public :synchronize
|
10
|
+
|
11
|
+
def wait(timeout = nil)
|
12
|
+
synchronize { ns_wait(timeout) }
|
13
|
+
end
|
14
|
+
|
15
|
+
public :ns_wait
|
16
|
+
|
17
|
+
def wait_until(timeout = nil, &condition)
|
18
|
+
synchronize { ns_wait_until(timeout, &condition) }
|
19
|
+
end
|
20
|
+
|
21
|
+
public :ns_wait_until
|
22
|
+
|
23
|
+
def signal
|
24
|
+
synchronize { ns_signal }
|
25
|
+
end
|
26
|
+
|
27
|
+
public :ns_signal
|
28
|
+
|
29
|
+
def broadcast
|
30
|
+
synchronize { ns_broadcast }
|
31
|
+
end
|
32
|
+
|
33
|
+
public :ns_broadcast
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|