concurrent-ruby 1.1.4 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile +9 -7
- data/README.md +34 -2
- data/Rakefile +33 -52
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +9 -8
- data/lib/concurrent/array.rb +3 -3
- data/lib/concurrent/async.rb +14 -0
- data/lib/concurrent/atomic/atomic_fixnum.rb +2 -2
- data/lib/concurrent/collection/lock_free_stack.rb +1 -1
- data/lib/concurrent/concurrent_ruby.jar +0 -0
- data/lib/concurrent/executor/timer_set.rb +13 -15
- data/lib/concurrent/hash.rb +3 -3
- data/lib/concurrent/promises.rb +348 -117
- data/lib/concurrent/synchronization/abstract_struct.rb +1 -0
- data/lib/concurrent/synchronization/condition.rb +2 -0
- data/lib/concurrent/synchronization/jruby_object.rb +1 -0
- data/lib/concurrent/synchronization/lock.rb +2 -0
- data/lib/concurrent/synchronization/mri_object.rb +1 -0
- data/lib/concurrent/synchronization/object.rb +46 -20
- data/lib/concurrent/synchronization/rbx_object.rb +1 -0
- data/lib/concurrent/synchronization/truffleruby_object.rb +1 -0
- data/lib/concurrent/version.rb +1 -2
- metadata +5 -4
@@ -27,15 +27,15 @@ module Concurrent
|
|
27
27
|
|
28
28
|
# @!method self.attr_volatile(*names)
|
29
29
|
# Creates methods for reading and writing (as `attr_accessor` does) to a instance variable with
|
30
|
-
# volatile (Java) semantic. The instance variable should be accessed
|
30
|
+
# volatile (Java) semantic. The instance variable should be accessed only through generated methods.
|
31
31
|
#
|
32
|
-
# @param [Array<Symbol>] names of the instance variables to be volatile
|
33
|
-
# @return [Array<Symbol>] names of defined method names
|
32
|
+
# @param [::Array<Symbol>] names of the instance variables to be volatile
|
33
|
+
# @return [::Array<Symbol>] names of defined method names
|
34
34
|
|
35
35
|
# Has to be called by children.
|
36
36
|
def initialize
|
37
37
|
super
|
38
|
-
|
38
|
+
__initialize_atomic_fields__
|
39
39
|
end
|
40
40
|
|
41
41
|
# By calling this method on a class, it and all its children are marked to be constructed safely. Meaning that
|
@@ -49,10 +49,12 @@ module Concurrent
|
|
49
49
|
# @AFinalValue = 'value' # published safely, does not have to be synchronized
|
50
50
|
# end
|
51
51
|
# end
|
52
|
+
# @return [true]
|
52
53
|
def self.safe_initialization!
|
53
54
|
# define only once, and not again in children
|
54
55
|
return if safe_initialization?
|
55
56
|
|
57
|
+
# @!visibility private
|
56
58
|
def self.new(*args, &block)
|
57
59
|
object = super(*args, &block)
|
58
60
|
ensure
|
@@ -70,6 +72,8 @@ module Concurrent
|
|
70
72
|
|
71
73
|
# For testing purposes, quite slow. Injects assert code to new method which will raise if class instance contains
|
72
74
|
# any instance variables with CamelCase names and isn't {.safe_initialization?}.
|
75
|
+
# @raise when offend found
|
76
|
+
# @return [true]
|
73
77
|
def self.ensure_safe_initialization_when_final_fields_are_present
|
74
78
|
Object.class_eval do
|
75
79
|
def self.new(*args, &block)
|
@@ -81,6 +85,7 @@ module Concurrent
|
|
81
85
|
end
|
82
86
|
end
|
83
87
|
end
|
88
|
+
true
|
84
89
|
end
|
85
90
|
|
86
91
|
# Creates methods for reading and writing to a instance variable with
|
@@ -89,13 +94,30 @@ module Concurrent
|
|
89
94
|
# This method generates following methods: `value`, `value=(new_value) #=> new_value`,
|
90
95
|
# `swap_value(new_value) #=> old_value`,
|
91
96
|
# `compare_and_set_value(expected, value) #=> true || false`, `update_value(&block)`.
|
92
|
-
# @param [Array<Symbol>] names of the instance variables to be volatile with CAS.
|
93
|
-
# @return [Array<Symbol>] names of defined method names.
|
97
|
+
# @param [::Array<Symbol>] names of the instance variables to be volatile with CAS.
|
98
|
+
# @return [::Array<Symbol>] names of defined method names.
|
99
|
+
# @!macro attr_atomic
|
100
|
+
# @!method $1
|
101
|
+
# @return [Object] The $1.
|
102
|
+
# @!method $1=(new_$1)
|
103
|
+
# Set the $1.
|
104
|
+
# @return [Object] new_$1.
|
105
|
+
# @!method swap_$1(new_$1)
|
106
|
+
# Set the $1 to new_$1 and return the old $1.
|
107
|
+
# @return [Object] old $1
|
108
|
+
# @!method compare_and_set_$1(expected_$1, new_$1)
|
109
|
+
# Sets the $1 to new_$1 if the current $1 is expected_$1
|
110
|
+
# @return [true, false]
|
111
|
+
# @!method update_$1(&block)
|
112
|
+
# Updates the $1 using the block.
|
113
|
+
# @yield [Object] Calculate a new $1 using given (old) $1
|
114
|
+
# @yieldparam [Object] old $1
|
115
|
+
# @return [Object] new $1
|
94
116
|
def self.attr_atomic(*names)
|
95
|
-
@
|
96
|
-
@
|
117
|
+
@__atomic_fields__ ||= []
|
118
|
+
@__atomic_fields__ += names
|
97
119
|
safe_initialization!
|
98
|
-
|
120
|
+
define_initialize_atomic_fields
|
99
121
|
|
100
122
|
names.each do |name|
|
101
123
|
ivar = :"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }}"
|
@@ -124,32 +146,36 @@ module Concurrent
|
|
124
146
|
names.flat_map { |n| [n, :"#{n}=", :"swap_#{n}", :"compare_and_set_#{n}", :"update_#{n}"] }
|
125
147
|
end
|
126
148
|
|
127
|
-
# @param [true,false] inherited should inherited volatile with CAS fields be returned?
|
128
|
-
# @return [Array<Symbol>] Returns defined volatile with CAS fields on this class.
|
129
|
-
def self.
|
130
|
-
@
|
131
|
-
((superclass.
|
132
|
-
|
149
|
+
# @param [true, false] inherited should inherited volatile with CAS fields be returned?
|
150
|
+
# @return [::Array<Symbol>] Returns defined volatile with CAS fields on this class.
|
151
|
+
def self.atomic_attributes(inherited = true)
|
152
|
+
@__atomic_fields__ ||= []
|
153
|
+
((superclass.atomic_attributes if superclass.respond_to?(:atomic_attributes) && inherited) || []) + @__atomic_fields__
|
154
|
+
end
|
155
|
+
|
156
|
+
# @return [true, false] is the attribute with name atomic?
|
157
|
+
def self.atomic_attribute?(name)
|
158
|
+
atomic_attributes.include? name
|
133
159
|
end
|
134
160
|
|
135
161
|
private
|
136
162
|
|
137
|
-
def self.
|
138
|
-
assignments = @
|
163
|
+
def self.define_initialize_atomic_fields
|
164
|
+
assignments = @__atomic_fields__.map do |name|
|
139
165
|
"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }} = Concurrent::AtomicReference.new(nil)"
|
140
166
|
end.join("\n")
|
141
167
|
|
142
168
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
143
|
-
def
|
169
|
+
def __initialize_atomic_fields__
|
144
170
|
super
|
145
171
|
#{assignments}
|
146
172
|
end
|
147
173
|
RUBY
|
148
174
|
end
|
149
175
|
|
150
|
-
private_class_method :
|
176
|
+
private_class_method :define_initialize_atomic_fields
|
151
177
|
|
152
|
-
def
|
178
|
+
def __initialize_atomic_fields__
|
153
179
|
end
|
154
180
|
|
155
181
|
end
|
data/lib/concurrent/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concurrent-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2019-03-11 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: |
|
16
16
|
Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
|
@@ -167,7 +167,8 @@ files:
|
|
167
167
|
homepage: http://www.concurrent-ruby.com
|
168
168
|
licenses:
|
169
169
|
- MIT
|
170
|
-
metadata:
|
170
|
+
metadata:
|
171
|
+
source_code_uri: https://github.com/ruby-concurrency/concurrent-ruby
|
171
172
|
post_install_message:
|
172
173
|
rdoc_options: []
|
173
174
|
require_paths:
|
@@ -184,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
185
|
version: '0'
|
185
186
|
requirements: []
|
186
187
|
rubyforge_project:
|
187
|
-
rubygems_version: 2.7.
|
188
|
+
rubygems_version: 2.7.8
|
188
189
|
signing_key:
|
189
190
|
specification_version: 4
|
190
191
|
summary: Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell,
|