concurrent-ruby 0.8.0.pre2-java → 0.9.0-java
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 +4 -4
- data/CHANGELOG.md +114 -3
- data/README.md +111 -55
- data/lib/concurrent.rb +90 -14
- data/lib/concurrent/async.rb +143 -51
- data/lib/concurrent/atom.rb +131 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +57 -107
- data/lib/concurrent/atomic/atomic_fixnum.rb +73 -101
- data/lib/concurrent/atomic/atomic_reference.rb +49 -0
- data/lib/concurrent/atomic/condition.rb +23 -12
- data/lib/concurrent/atomic/count_down_latch.rb +23 -21
- data/lib/concurrent/atomic/cyclic_barrier.rb +47 -47
- data/lib/concurrent/atomic/event.rb +33 -42
- data/lib/concurrent/atomic/read_write_lock.rb +252 -0
- data/lib/concurrent/atomic/semaphore.rb +64 -89
- data/lib/concurrent/atomic/thread_local_var.rb +130 -58
- data/lib/concurrent/atomic/thread_local_var/weak_key_map.rb +236 -0
- data/lib/concurrent/atomic_reference/direct_update.rb +34 -3
- data/lib/concurrent/atomic_reference/jruby.rb +6 -3
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +17 -39
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +3 -0
- data/lib/concurrent/atomic_reference/rbx.rb +4 -1
- data/lib/concurrent/atomic_reference/ruby.rb +6 -3
- data/lib/concurrent/atomics.rb +74 -4
- data/lib/concurrent/collection/copy_on_notify_observer_set.rb +115 -0
- data/lib/concurrent/collection/copy_on_write_observer_set.rb +119 -0
- data/lib/concurrent/collection/priority_queue.rb +300 -245
- data/lib/concurrent/concern/deprecation.rb +34 -0
- data/lib/concurrent/concern/dereferenceable.rb +88 -0
- data/lib/concurrent/concern/logging.rb +27 -0
- data/lib/concurrent/concern/obligation.rb +228 -0
- data/lib/concurrent/concern/observable.rb +85 -0
- data/lib/concurrent/configuration.rb +234 -109
- data/lib/concurrent/dataflow.rb +2 -3
- data/lib/concurrent/delay.rb +141 -50
- data/lib/concurrent/edge.rb +30 -0
- data/lib/concurrent/errors.rb +19 -7
- data/lib/concurrent/exchanger.rb +25 -1
- data/lib/concurrent/executor/cached_thread_pool.rb +51 -33
- data/lib/concurrent/executor/executor.rb +46 -299
- data/lib/concurrent/executor/executor_service.rb +521 -0
- data/lib/concurrent/executor/fixed_thread_pool.rb +196 -23
- data/lib/concurrent/executor/immediate_executor.rb +9 -9
- data/lib/concurrent/executor/indirect_immediate_executor.rb +4 -3
- data/lib/concurrent/executor/java_single_thread_executor.rb +17 -16
- data/lib/concurrent/executor/java_thread_pool_executor.rb +55 -102
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +14 -16
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +250 -166
- data/lib/concurrent/executor/safe_task_executor.rb +5 -4
- data/lib/concurrent/executor/serialized_execution.rb +22 -18
- data/lib/concurrent/executor/{per_thread_executor.rb → simple_executor_service.rb} +29 -20
- data/lib/concurrent/executor/single_thread_executor.rb +32 -21
- data/lib/concurrent/executor/thread_pool_executor.rb +73 -60
- data/lib/concurrent/executor/timer_set.rb +96 -84
- data/lib/concurrent/executors.rb +1 -1
- data/lib/concurrent/future.rb +71 -38
- data/lib/concurrent/immutable_struct.rb +89 -0
- data/lib/concurrent/ivar.rb +152 -60
- data/lib/concurrent/lazy_register.rb +40 -20
- data/lib/concurrent/maybe.rb +226 -0
- data/lib/concurrent/mutable_struct.rb +227 -0
- data/lib/concurrent/mvar.rb +44 -43
- data/lib/concurrent/promise.rb +229 -136
- data/lib/concurrent/scheduled_task.rb +341 -43
- data/lib/concurrent/settable_struct.rb +127 -0
- data/lib/concurrent/synchronization.rb +17 -0
- data/lib/concurrent/synchronization/abstract_object.rb +163 -0
- data/lib/concurrent/synchronization/abstract_struct.rb +158 -0
- data/lib/concurrent/synchronization/condition.rb +53 -0
- data/lib/concurrent/synchronization/java_object.rb +34 -0
- data/lib/concurrent/synchronization/lock.rb +32 -0
- data/lib/concurrent/synchronization/monitor_object.rb +26 -0
- data/lib/concurrent/synchronization/mutex_object.rb +43 -0
- data/lib/concurrent/synchronization/object.rb +78 -0
- data/lib/concurrent/synchronization/rbx_object.rb +75 -0
- data/lib/concurrent/timer_task.rb +92 -103
- data/lib/concurrent/tvar.rb +42 -38
- data/lib/concurrent/utilities.rb +3 -1
- data/lib/concurrent/utility/at_exit.rb +97 -0
- data/lib/concurrent/utility/engine.rb +44 -0
- data/lib/concurrent/utility/monotonic_time.rb +59 -0
- data/lib/concurrent/utility/native_extension_loader.rb +56 -0
- data/lib/concurrent/utility/processor_counter.rb +156 -0
- data/lib/concurrent/utility/timeout.rb +18 -14
- data/lib/concurrent/utility/timer.rb +11 -6
- data/lib/concurrent/version.rb +2 -1
- data/lib/concurrent_ruby.rb +1 -0
- data/lib/concurrent_ruby_ext.jar +0 -0
- metadata +46 -66
- data/lib/concurrent/actor.rb +0 -103
- data/lib/concurrent/actor/behaviour.rb +0 -70
- data/lib/concurrent/actor/behaviour/abstract.rb +0 -48
- data/lib/concurrent/actor/behaviour/awaits.rb +0 -21
- data/lib/concurrent/actor/behaviour/buffer.rb +0 -54
- data/lib/concurrent/actor/behaviour/errors_on_unknown_message.rb +0 -12
- data/lib/concurrent/actor/behaviour/executes_context.rb +0 -18
- data/lib/concurrent/actor/behaviour/linking.rb +0 -45
- data/lib/concurrent/actor/behaviour/pausing.rb +0 -77
- data/lib/concurrent/actor/behaviour/removes_child.rb +0 -16
- data/lib/concurrent/actor/behaviour/sets_results.rb +0 -36
- data/lib/concurrent/actor/behaviour/supervised.rb +0 -59
- data/lib/concurrent/actor/behaviour/supervising.rb +0 -34
- data/lib/concurrent/actor/behaviour/terminates_children.rb +0 -13
- data/lib/concurrent/actor/behaviour/termination.rb +0 -54
- data/lib/concurrent/actor/context.rb +0 -154
- data/lib/concurrent/actor/core.rb +0 -217
- data/lib/concurrent/actor/default_dead_letter_handler.rb +0 -9
- data/lib/concurrent/actor/envelope.rb +0 -41
- data/lib/concurrent/actor/errors.rb +0 -27
- data/lib/concurrent/actor/internal_delegations.rb +0 -49
- data/lib/concurrent/actor/public_delegations.rb +0 -40
- data/lib/concurrent/actor/reference.rb +0 -81
- data/lib/concurrent/actor/root.rb +0 -37
- data/lib/concurrent/actor/type_check.rb +0 -48
- data/lib/concurrent/actor/utils.rb +0 -10
- data/lib/concurrent/actor/utils/ad_hoc.rb +0 -21
- data/lib/concurrent/actor/utils/balancer.rb +0 -42
- data/lib/concurrent/actor/utils/broadcast.rb +0 -52
- data/lib/concurrent/actor/utils/pool.rb +0 -59
- data/lib/concurrent/actress.rb +0 -3
- data/lib/concurrent/agent.rb +0 -209
- data/lib/concurrent/atomic.rb +0 -92
- data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +0 -118
- data/lib/concurrent/atomic/copy_on_write_observer_set.rb +0 -117
- data/lib/concurrent/atomic/synchronization.rb +0 -51
- data/lib/concurrent/channel/buffered_channel.rb +0 -85
- data/lib/concurrent/channel/channel.rb +0 -41
- data/lib/concurrent/channel/unbuffered_channel.rb +0 -35
- data/lib/concurrent/channel/waitable_list.rb +0 -40
- data/lib/concurrent/channels.rb +0 -5
- data/lib/concurrent/collection/blocking_ring_buffer.rb +0 -71
- data/lib/concurrent/collection/ring_buffer.rb +0 -59
- data/lib/concurrent/collections.rb +0 -3
- data/lib/concurrent/dereferenceable.rb +0 -108
- data/lib/concurrent/executor/java_cached_thread_pool.rb +0 -32
- data/lib/concurrent/executor/java_fixed_thread_pool.rb +0 -31
- data/lib/concurrent/executor/ruby_cached_thread_pool.rb +0 -29
- data/lib/concurrent/executor/ruby_fixed_thread_pool.rb +0 -32
- data/lib/concurrent/executor/ruby_thread_pool_worker.rb +0 -73
- data/lib/concurrent/logging.rb +0 -20
- data/lib/concurrent/obligation.rb +0 -171
- data/lib/concurrent/observable.rb +0 -73
- data/lib/concurrent/options_parser.rb +0 -48
- data/lib/concurrent/utility/processor_count.rb +0 -152
- data/lib/extension_helper.rb +0 -37
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'concurrent/utility/engine'
|
2
|
+
require 'concurrent/synchronization/abstract_object'
|
3
|
+
require 'concurrent/synchronization/java_object'
|
4
|
+
require 'concurrent/synchronization/mutex_object'
|
5
|
+
require 'concurrent/synchronization/monitor_object'
|
6
|
+
require 'concurrent/synchronization/rbx_object'
|
7
|
+
require 'concurrent/synchronization/object'
|
8
|
+
|
9
|
+
require 'concurrent/synchronization/condition'
|
10
|
+
require 'concurrent/synchronization/lock'
|
11
|
+
|
12
|
+
module Concurrent
|
13
|
+
# {include:file:doc/synchronization.md}
|
14
|
+
module Synchronization
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
|
4
|
+
# @!macro synchronization_object
|
5
|
+
# @!visibility private
|
6
|
+
class AbstractObject
|
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)
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
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)
|
92
|
+
raise NotImplementedError
|
93
|
+
end
|
94
|
+
|
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
|
+
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
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,158 @@
|
|
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
|
+
ensure_ivar_visibility!
|
13
|
+
end
|
14
|
+
|
15
|
+
# @!macro [attach] struct_length
|
16
|
+
#
|
17
|
+
# Returns the number of struct members.
|
18
|
+
#
|
19
|
+
# @return [Fixnum] the number of struct members
|
20
|
+
def length
|
21
|
+
self.class::MEMBERS.length
|
22
|
+
end
|
23
|
+
alias_method :size, :length
|
24
|
+
|
25
|
+
# @!macro [attach] struct_members
|
26
|
+
#
|
27
|
+
# Returns the struct members as an array of symbols.
|
28
|
+
#
|
29
|
+
# @return [Array] the struct members as an array of symbols
|
30
|
+
def members
|
31
|
+
self.class::MEMBERS.dup
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
# @!macro struct_values
|
37
|
+
#
|
38
|
+
# @!visibility private
|
39
|
+
def ns_values
|
40
|
+
@values.dup
|
41
|
+
end
|
42
|
+
|
43
|
+
# @!macro struct_values_at
|
44
|
+
#
|
45
|
+
# @!visibility private
|
46
|
+
def ns_values_at(indexes)
|
47
|
+
@values.values_at(*indexes)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @!macro struct_to_h
|
51
|
+
#
|
52
|
+
# @!visibility private
|
53
|
+
def ns_to_h
|
54
|
+
length.times.reduce({}){|memo, i| memo[self.class::MEMBERS[i]] = @values[i]; memo}
|
55
|
+
end
|
56
|
+
|
57
|
+
# @!macro struct_get
|
58
|
+
#
|
59
|
+
# @!visibility private
|
60
|
+
def ns_get(member)
|
61
|
+
if member.is_a? Integer
|
62
|
+
if member >= @values.length
|
63
|
+
raise IndexError.new("offset #{member} too large for struct(size:#{@values.length})")
|
64
|
+
end
|
65
|
+
@values[member]
|
66
|
+
else
|
67
|
+
send(member)
|
68
|
+
end
|
69
|
+
rescue NoMethodError
|
70
|
+
raise NameError.new("no member '#{member}' in struct")
|
71
|
+
end
|
72
|
+
|
73
|
+
# @!macro struct_equality
|
74
|
+
#
|
75
|
+
# @!visibility private
|
76
|
+
def ns_equality(other)
|
77
|
+
self.class == other.class && self.values == other.values
|
78
|
+
end
|
79
|
+
|
80
|
+
# @!macro struct_each
|
81
|
+
#
|
82
|
+
# @!visibility private
|
83
|
+
def ns_each
|
84
|
+
values.each{|value| yield value }
|
85
|
+
end
|
86
|
+
|
87
|
+
# @!macro struct_each_pair
|
88
|
+
#
|
89
|
+
# @!visibility private
|
90
|
+
def ns_each_pair
|
91
|
+
@values.length.times do |index|
|
92
|
+
yield self.class::MEMBERS[index], @values[index]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# @!macro struct_select
|
97
|
+
#
|
98
|
+
# @!visibility private
|
99
|
+
def ns_select
|
100
|
+
values.select{|value| yield value }
|
101
|
+
end
|
102
|
+
|
103
|
+
# @!macro struct_inspect
|
104
|
+
#
|
105
|
+
# @!visibility private
|
106
|
+
def ns_inspect
|
107
|
+
struct = pr_underscore(self.class.ancestors[1])
|
108
|
+
clazz = ((self.class.to_s =~ /^#<Class:/) == 0) ? '' : " #{self.class}"
|
109
|
+
"#<#{struct}#{clazz} #{ns_to_h}>"
|
110
|
+
end
|
111
|
+
|
112
|
+
# @!macro struct_merge
|
113
|
+
#
|
114
|
+
# @!visibility private
|
115
|
+
def ns_merge(other, &block)
|
116
|
+
self.class.new(*self.to_h.merge(other, &block).values)
|
117
|
+
end
|
118
|
+
|
119
|
+
# @!visibility private
|
120
|
+
def pr_underscore(clazz)
|
121
|
+
word = clazz.to_s
|
122
|
+
word.gsub!(/::/, '/')
|
123
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
124
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
125
|
+
word.tr!("-", "_")
|
126
|
+
word.downcase!
|
127
|
+
word
|
128
|
+
end
|
129
|
+
|
130
|
+
# @!visibility private
|
131
|
+
def self.define_struct_class(parent, base, name, members, &block)
|
132
|
+
clazz = Class.new(base || Object) do
|
133
|
+
include parent
|
134
|
+
self.const_set(:MEMBERS, members.collect{|member| member.to_s.to_sym}.freeze)
|
135
|
+
def ns_initialize(*values)
|
136
|
+
raise ArgumentError.new('struct size differs') if values.length > length
|
137
|
+
@values = values.fill(nil, values.length..length-1)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
unless name.nil?
|
141
|
+
begin
|
142
|
+
parent.const_set(name, clazz)
|
143
|
+
parent.const_get(name)
|
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(:define_method, member) do
|
150
|
+
@values[index]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
clazz.class_exec(&block) unless block.nil?
|
154
|
+
clazz
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
class Condition < Object
|
4
|
+
|
5
|
+
singleton_class.send :alias_method, :private_new, :new
|
6
|
+
private_class_method :new
|
7
|
+
|
8
|
+
def initialize(lock)
|
9
|
+
@Lock = lock
|
10
|
+
ensure_ivar_visibility!
|
11
|
+
super()
|
12
|
+
end
|
13
|
+
|
14
|
+
def wait(timeout = nil)
|
15
|
+
@Lock.synchronize { ns_wait(timeout) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def ns_wait(timeout = nil)
|
19
|
+
synchronize { super(timeout) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def wait_until(timeout = nil, &condition)
|
23
|
+
@Lock.synchronize { ns_wait_until(timeout, &condition) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def ns_wait_until(timeout = nil, &condition)
|
27
|
+
synchronize { super(timeout, &condition) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def signal
|
31
|
+
@Lock.synchronize { ns_signal }
|
32
|
+
end
|
33
|
+
|
34
|
+
def ns_signal
|
35
|
+
synchronize { super }
|
36
|
+
end
|
37
|
+
|
38
|
+
def broadcast
|
39
|
+
@Lock.synchronize { ns_broadcast }
|
40
|
+
end
|
41
|
+
|
42
|
+
def ns_broadcast
|
43
|
+
synchronize { super }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Object < Implementation
|
48
|
+
def new_condition
|
49
|
+
Condition.private_new(self)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'concurrent/utility/native_extension_loader' # load native part first
|
2
|
+
|
3
|
+
module Concurrent
|
4
|
+
module Synchronization
|
5
|
+
|
6
|
+
if Concurrent.on_jruby?
|
7
|
+
|
8
|
+
# @!visibility private
|
9
|
+
# @!macro internal_implementation_note
|
10
|
+
class JavaObject < AbstractObject
|
11
|
+
|
12
|
+
def self.attr_volatile(*names)
|
13
|
+
names.each do |name|
|
14
|
+
|
15
|
+
ivar = :"@volatile_#{name}"
|
16
|
+
|
17
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
18
|
+
def #{name}
|
19
|
+
instance_variable_get_volatile(:#{ivar})
|
20
|
+
end
|
21
|
+
|
22
|
+
def #{name}=(value)
|
23
|
+
instance_variable_set_volatile(:#{ivar}, value)
|
24
|
+
end
|
25
|
+
RUBY
|
26
|
+
|
27
|
+
end
|
28
|
+
names.map { |n| [n, :"#{n}="] }.flatten
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Concurrent
|
2
|
+
module Synchronization
|
3
|
+
class Lock < Object
|
4
|
+
|
5
|
+
public :synchronize
|
6
|
+
|
7
|
+
def wait(timeout = nil)
|
8
|
+
synchronize { ns_wait(timeout) }
|
9
|
+
end
|
10
|
+
|
11
|
+
public :ns_wait
|
12
|
+
|
13
|
+
def wait_until(timeout = nil, &condition)
|
14
|
+
synchronize { ns_wait_until(timeout, &condition) }
|
15
|
+
end
|
16
|
+
|
17
|
+
public :ns_wait_until
|
18
|
+
|
19
|
+
def signal
|
20
|
+
synchronize { ns_signal }
|
21
|
+
end
|
22
|
+
|
23
|
+
public :ns_signal
|
24
|
+
|
25
|
+
def broadcast
|
26
|
+
synchronize { ns_broadcast }
|
27
|
+
end
|
28
|
+
|
29
|
+
public :ns_broadcast
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|