concurrent-ruby 1.1.8 → 1.1.9
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 +12 -0
- data/README.md +28 -4
- data/Rakefile +24 -19
- data/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +14 -0
- data/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb +11 -1
- data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
- data/lib/concurrent-ruby/concurrent/map.rb +13 -3
- data/lib/concurrent-ruby/concurrent/promise.rb +1 -0
- data/lib/concurrent-ruby/concurrent/set.rb +14 -6
- data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +12 -0
- data/lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb +6 -0
- data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +26 -1
- data/lib/concurrent-ruby/concurrent/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e26dce842bfb7973c28f13017d50c3e729a9261f48427920db279055c4d089b
|
4
|
+
data.tar.gz: 501e9d485d4683657b49cd5820ef0462ce91133ad163ba9e790f254892d1e533
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f894d3207ce129044970321fabe750cc4b9744a876f354dd791d045fb4ffed1d0a5a9a50dcb1ab0ca36df705b6b7578fe7eded26bcaa3dbeb0c7a12e655596c
|
7
|
+
data.tar.gz: 3cb4ccbbf13e2f73987eda48a32b444d7330c53a668ddef2fd4a73841caf18805d68cec45273a02de2c10087da4a4ce063c01b1bdccb96d4668b10cc4af79f88
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
## Current
|
2
2
|
|
3
|
+
## Release v1.1.9 (5 Jun 2021)
|
4
|
+
|
5
|
+
concurrent-ruby:
|
6
|
+
|
7
|
+
* (#866) Child promise state not set to :pending immediately after #execute when parent has completed
|
8
|
+
* (#905, #872) Fix RubyNonConcurrentPriorityQueue#delete method
|
9
|
+
* (2df0337d) Make sure locks are not shared on shared when objects are dup/cloned
|
10
|
+
* (#900, #906, #796, #847, #911) Fix Concurrent::Set tread-safety issues on CRuby
|
11
|
+
* (#907) Add new ConcurrentMap backend for TruffleRuby
|
12
|
+
|
3
13
|
## Release v1.1.8 (20 January 2021)
|
4
14
|
|
15
|
+
concurrent-ruby:
|
16
|
+
|
5
17
|
* (#885) Fix race condition in TVar for stale reads
|
6
18
|
* (#884) RubyThreadLocalVar: Do not iterate over hash which might conflict with new pair addition
|
7
19
|
|
data/README.md
CHANGED
@@ -353,19 +353,43 @@ and load the appropriate C extensions.
|
|
353
353
|
No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The
|
354
354
|
best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions.
|
355
355
|
|
356
|
+
## Building the gem
|
357
|
+
|
358
|
+
### Requirements
|
359
|
+
|
360
|
+
* Recent CRuby
|
361
|
+
* JRuby, `rbenv install jruby-9.2.17.0`
|
362
|
+
* Set env variable `CONCURRENT_JRUBY_HOME` to point to it, e.g. `/usr/local/opt/rbenv/versions/jruby-9.2.17.0`
|
363
|
+
* Install Docker, required for Windows builds
|
364
|
+
|
365
|
+
### Publishing the Gem
|
366
|
+
|
367
|
+
* Update`version.rb`
|
368
|
+
* Update the CHANGELOG
|
369
|
+
* Update the Yard documentation
|
370
|
+
- Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the
|
371
|
+
documentation.
|
372
|
+
- Run `bundle exec rake yard` to update the master documentation and signpost.
|
373
|
+
- Run `bundle exec rake yard:<new-version>` to add or update the documentation of the new version.
|
374
|
+
* Commit (and push) the changes.
|
375
|
+
* Use `be rake release` to release the gem. It consists
|
376
|
+
of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps. It will ask at the end before
|
377
|
+
publishing anything. Steps can also be executed individually.
|
378
|
+
|
356
379
|
## Maintainers
|
357
380
|
|
358
|
-
* [Petr Chalupa](https://github.com/pitr-ch)
|
359
|
-
* [
|
360
|
-
|
381
|
+
* [Petr Chalupa](https://github.com/pitr-ch) — Lead maintainer, point-of-contact.
|
382
|
+
* [Chris Seaton](https://github.com/chrisseaton) —
|
383
|
+
If Petr is not available Chris can help or poke Petr to pay attention where it is needed.
|
361
384
|
|
362
385
|
### Special Thanks to
|
363
386
|
|
387
|
+
* [Jerry D'Antonio](https://github.com/jdantonio) for creating the gem
|
364
388
|
* [Brian Durand](https://github.com/bdurand) for the `ref` gem
|
365
389
|
* [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems
|
366
390
|
* [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem
|
367
391
|
|
368
|
-
|
392
|
+
to the past maintainers
|
369
393
|
|
370
394
|
* [Michele Della Torre](https://github.com/mighe)
|
371
395
|
* [Paweł Obrok](https://github.com/obrok)
|
data/Rakefile
CHANGED
@@ -135,7 +135,7 @@ begin
|
|
135
135
|
task :update_readme do
|
136
136
|
Dir.chdir __dir__ do
|
137
137
|
content = File.read(File.join('README.md')).
|
138
|
-
|
138
|
+
gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_|
|
139
139
|
case $1
|
140
140
|
when 'LockFreeLinkedSet'
|
141
141
|
"{Concurrent::Edge::#{$1} #{$1}}"
|
@@ -165,9 +165,9 @@ begin
|
|
165
165
|
desc "* of #{name} into subdir #{name}"
|
166
166
|
YARD::Rake::YardocTask.new(name) do |yard|
|
167
167
|
yard.options.push(
|
168
|
-
|
169
|
-
|
170
|
-
|
168
|
+
'--output-dir', output_dir,
|
169
|
+
'--main', 'tmp/README.md',
|
170
|
+
*common_yard_options)
|
171
171
|
yard.files = ['./lib/concurrent-ruby/**/*.rb',
|
172
172
|
'./lib/concurrent-ruby-edge/**/*.rb',
|
173
173
|
'./ext/concurrent_ruby_ext/**/*.c',
|
@@ -189,9 +189,9 @@ begin
|
|
189
189
|
desc "* signpost for versions"
|
190
190
|
YARD::Rake::YardocTask.new(:signpost) do |yard|
|
191
191
|
yard.options.push(
|
192
|
-
|
193
|
-
|
194
|
-
|
192
|
+
'--output-dir', 'docs',
|
193
|
+
'--main', 'docs-source/signpost.md',
|
194
|
+
*common_yard_options)
|
195
195
|
yard.files = ['no-lib']
|
196
196
|
end
|
197
197
|
|
@@ -206,7 +206,7 @@ begin
|
|
206
206
|
sh 'diff -r docs/ docs-copy/' do |ok, res|
|
207
207
|
unless ok
|
208
208
|
begin
|
209
|
-
STDOUT.puts
|
209
|
+
STDOUT.puts "yard:#{name} is not properly generated and committed.", "Continue? (y/n)"
|
210
210
|
input = STDIN.gets.strip.downcase
|
211
211
|
end until %w(y n).include?(input)
|
212
212
|
exit 1 if input == 'n'
|
@@ -234,15 +234,13 @@ task :release => ['release:checks', 'release:build', 'release:test', 'release:pu
|
|
234
234
|
namespace :release do
|
235
235
|
# Depends on environment of @pitr-ch
|
236
236
|
|
237
|
-
mri_version = '2.6.5'
|
238
|
-
jruby_version = 'jruby-9.2.9.0'
|
239
|
-
|
240
237
|
task :checks => "yard:#{current_yard_version_name}:uptodate" do
|
241
238
|
Dir.chdir(__dir__) do
|
242
239
|
sh 'test -z "$(git status --porcelain)"' do |ok, res|
|
243
240
|
unless ok
|
244
241
|
begin
|
245
|
-
|
242
|
+
status = `git status --porcelain`
|
243
|
+
STDOUT.puts 'There are local changes that you might want to commit.', status, 'Continue? (y/n)'
|
246
244
|
input = STDIN.gets.strip.downcase
|
247
245
|
end until %w(y n).include?(input)
|
248
246
|
exit 1 if input == 'n'
|
@@ -250,10 +248,10 @@ namespace :release do
|
|
250
248
|
end
|
251
249
|
sh 'git fetch'
|
252
250
|
sh 'test $(git show-ref --verify --hash refs/heads/master) = ' +
|
253
|
-
|
251
|
+
'$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res|
|
254
252
|
unless ok
|
255
253
|
begin
|
256
|
-
STDOUT.puts '
|
254
|
+
STDOUT.puts 'Local master branch is not pushed to origin.', 'Continue? (y/n)'
|
257
255
|
input = STDIN.gets.strip.downcase
|
258
256
|
end until %w(y n).include?(input)
|
259
257
|
exit 1 if input == 'n'
|
@@ -270,6 +268,12 @@ namespace :release do
|
|
270
268
|
Dir.chdir(__dir__) do
|
271
269
|
old = ENV['RBENV_VERSION']
|
272
270
|
|
271
|
+
mri_version = `ruby -e 'puts RUBY_VERSION'`.chomp
|
272
|
+
jruby_version = File.basename(ENV['CONCURRENT_JRUBY_HOME'])
|
273
|
+
|
274
|
+
puts "Using following version:"
|
275
|
+
pp mri_version: mri_version, jruby_version: jruby_version
|
276
|
+
|
273
277
|
ENV['RBENV_VERSION'] = mri_version
|
274
278
|
sh 'rbenv version'
|
275
279
|
sh 'bundle exec rake spec:installed'
|
@@ -292,12 +296,12 @@ namespace :release do
|
|
292
296
|
|
293
297
|
task :ask do
|
294
298
|
begin
|
295
|
-
STDOUT.puts 'Do you want to publish anything? (y/n)'
|
299
|
+
STDOUT.puts 'Do you want to publish anything now? (y/n)'
|
296
300
|
input = STDIN.gets.strip.downcase
|
297
301
|
end until %w(y n).include?(input)
|
298
302
|
exit 1 if input == 'n'
|
299
303
|
begin
|
300
|
-
STDOUT.puts 'Do you want to publish edge
|
304
|
+
STDOUT.puts 'It will publish `concurrent-ruby`. Do you want to publish `concurrent-ruby-edge`? (y/n)'
|
301
305
|
input = STDIN.gets.strip.downcase
|
302
306
|
end until %w(y n).include?(input)
|
303
307
|
publish_edge = input == 'y'
|
@@ -326,9 +330,10 @@ namespace :release do
|
|
326
330
|
|
327
331
|
desc '** print post release steps'
|
328
332
|
task :post_steps do
|
329
|
-
|
330
|
-
puts 'Manually:
|
331
|
-
puts 'Manually:
|
333
|
+
# TODO: (petr 05-Jun-2021) automate and renew the process
|
334
|
+
# puts 'Manually: create a release on GitHub with relevant changelog part'
|
335
|
+
# puts 'Manually: send email same as release with relevant changelog part'
|
336
|
+
# puts 'Manually: tweet'
|
332
337
|
end
|
333
338
|
end
|
334
339
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Concurrent
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
module Collection
|
5
|
+
|
6
|
+
# @!visibility private
|
7
|
+
class TruffleRubyMapBackend < TruffleRuby::ConcurrentMap
|
8
|
+
def initialize(options = nil)
|
9
|
+
options ||= {}
|
10
|
+
super(initial_capacity: options[:initial_capacity], load_factor: options[:load_factor])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -30,7 +30,7 @@ module Concurrent
|
|
30
30
|
if @queue[k] == item
|
31
31
|
swap(k, @length)
|
32
32
|
@length -= 1
|
33
|
-
sink(k)
|
33
|
+
sink(k) || swim(k)
|
34
34
|
@queue.pop
|
35
35
|
else
|
36
36
|
k += 1
|
@@ -126,12 +126,17 @@ module Concurrent
|
|
126
126
|
#
|
127
127
|
# @!visibility private
|
128
128
|
def sink(k)
|
129
|
+
success = false
|
130
|
+
|
129
131
|
while (j = (2 * k)) <= @length do
|
130
132
|
j += 1 if j < @length && ! ordered?(j, j+1)
|
131
133
|
break if ordered?(k, j)
|
132
134
|
swap(k, j)
|
135
|
+
success = true
|
133
136
|
k = j
|
134
137
|
end
|
138
|
+
|
139
|
+
success
|
135
140
|
end
|
136
141
|
|
137
142
|
# Percolate up to maintain heap invariant.
|
@@ -140,10 +145,15 @@ module Concurrent
|
|
140
145
|
#
|
141
146
|
# @!visibility private
|
142
147
|
def swim(k)
|
148
|
+
success = false
|
149
|
+
|
143
150
|
while k > 1 && ! ordered?(k/2, k) do
|
144
151
|
swap(k, k/2)
|
145
152
|
k = k/2
|
153
|
+
success = true
|
146
154
|
end
|
155
|
+
|
156
|
+
success
|
147
157
|
end
|
148
158
|
end
|
149
159
|
end
|
Binary file
|
@@ -15,7 +15,10 @@ module Concurrent
|
|
15
15
|
when Concurrent.on_cruby?
|
16
16
|
require 'concurrent/collection/map/mri_map_backend'
|
17
17
|
MriMapBackend
|
18
|
-
when Concurrent.
|
18
|
+
when Concurrent.on_truffleruby? && defined?(::TruffleRuby::ConcurrentMap)
|
19
|
+
require 'concurrent/collection/map/truffleruby_map_backend'
|
20
|
+
TruffleRubyMapBackend
|
21
|
+
when Concurrent.on_truffleruby? || Concurrent.on_rbx?
|
19
22
|
require 'concurrent/collection/map/atomic_reference_map_backend'
|
20
23
|
AtomicReferenceMapBackend
|
21
24
|
else
|
@@ -114,7 +117,7 @@ module Concurrent
|
|
114
117
|
# @return [true, false] true if deleted
|
115
118
|
# @!macro map.atomic_method
|
116
119
|
|
117
|
-
|
120
|
+
#
|
118
121
|
def initialize(options = nil, &block)
|
119
122
|
if options.kind_of?(::Hash)
|
120
123
|
validate_options_hash!(options)
|
@@ -143,8 +146,15 @@ module Concurrent
|
|
143
146
|
end
|
144
147
|
end
|
145
148
|
|
149
|
+
# Set a value with key
|
150
|
+
# @param [Object] key
|
151
|
+
# @param [Object] value
|
152
|
+
# @return [Object] the new value
|
153
|
+
def []=(key, value)
|
154
|
+
super
|
155
|
+
end
|
156
|
+
|
146
157
|
alias_method :get, :[]
|
147
|
-
# TODO (pitr-ch 30-Oct-2018): doc
|
148
158
|
alias_method :put, :[]=
|
149
159
|
|
150
160
|
# Get a value with key, or default_value when key is absent,
|
@@ -19,13 +19,19 @@ module Concurrent
|
|
19
19
|
#
|
20
20
|
# @see http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html Ruby standard library `Set`
|
21
21
|
|
22
|
-
|
23
22
|
# @!macro internal_implementation_note
|
24
23
|
SetImplementation = case
|
25
24
|
when Concurrent.on_cruby?
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
25
|
+
# The CRuby implementation of Set is written in Ruby itself and is
|
26
|
+
# not thread safe for certain methods.
|
27
|
+
require 'monitor'
|
28
|
+
require 'concurrent/thread_safe/util/data_structures'
|
29
|
+
|
30
|
+
class CRubySet < ::Set
|
31
|
+
end
|
32
|
+
|
33
|
+
ThreadSafe::Util.make_synchronized_on_cruby CRubySet
|
34
|
+
CRubySet
|
29
35
|
|
30
36
|
when Concurrent.on_jruby?
|
31
37
|
require 'jruby/synchronized'
|
@@ -33,6 +39,7 @@ module Concurrent
|
|
33
39
|
class JRubySet < ::Set
|
34
40
|
include JRuby::Synchronized
|
35
41
|
end
|
42
|
+
|
36
43
|
JRubySet
|
37
44
|
|
38
45
|
when Concurrent.on_rbx?
|
@@ -41,7 +48,8 @@ module Concurrent
|
|
41
48
|
|
42
49
|
class RbxSet < ::Set
|
43
50
|
end
|
44
|
-
|
51
|
+
|
52
|
+
ThreadSafe::Util.make_synchronized_on_rbx RbxSet
|
45
53
|
RbxSet
|
46
54
|
|
47
55
|
when Concurrent.on_truffleruby?
|
@@ -50,7 +58,7 @@ module Concurrent
|
|
50
58
|
class TruffleRubySet < ::Set
|
51
59
|
end
|
52
60
|
|
53
|
-
ThreadSafe::Util.make_synchronized_on_truffleruby
|
61
|
+
ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubySet
|
54
62
|
TruffleRubySet
|
55
63
|
|
56
64
|
else
|
@@ -32,6 +32,12 @@ module Concurrent
|
|
32
32
|
@__Condition__ = ::ConditionVariable.new
|
33
33
|
end
|
34
34
|
|
35
|
+
def initialize_copy(other)
|
36
|
+
super
|
37
|
+
@__Lock__ = ::Mutex.new
|
38
|
+
@__Condition__ = ::ConditionVariable.new
|
39
|
+
end
|
40
|
+
|
35
41
|
protected
|
36
42
|
|
37
43
|
def synchronize
|
@@ -61,6 +67,12 @@ module Concurrent
|
|
61
67
|
@__Condition__ = @__Lock__.new_cond
|
62
68
|
end
|
63
69
|
|
70
|
+
def initialize_copy(other)
|
71
|
+
super
|
72
|
+
@__Lock__ = ::Monitor.new
|
73
|
+
@__Condition__ = @__Lock__.new_cond
|
74
|
+
end
|
75
|
+
|
64
76
|
protected
|
65
77
|
|
66
78
|
def synchronize # TODO may be a problem with lock.synchronize { lock.wait }
|
@@ -12,12 +12,37 @@ end
|
|
12
12
|
module Concurrent
|
13
13
|
module ThreadSafe
|
14
14
|
module Util
|
15
|
+
def self.make_synchronized_on_cruby(klass)
|
16
|
+
klass.class_eval do
|
17
|
+
def initialize(*args, &block)
|
18
|
+
@_monitor = Monitor.new
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize_copy(other)
|
23
|
+
# make sure a copy is not sharing a monitor with the original object!
|
24
|
+
@_monitor = Monitor.new
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
klass.superclass.instance_methods(false).each do |method|
|
30
|
+
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
31
|
+
def #{method}(*args)
|
32
|
+
monitor = @_monitor
|
33
|
+
monitor or raise("BUG: Internal monitor was not properly initialized. Please report this to the concurrent-ruby developers.")
|
34
|
+
monitor.synchronize { super }
|
35
|
+
end
|
36
|
+
RUBY
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
15
40
|
def self.make_synchronized_on_rbx(klass)
|
16
41
|
klass.class_eval do
|
17
42
|
private
|
18
43
|
|
19
44
|
def _mon_initialize
|
20
|
-
@_monitor
|
45
|
+
@_monitor ||= Monitor.new # avoid double initialisation
|
21
46
|
end
|
22
47
|
|
23
48
|
def self.new(*args)
|
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.9
|
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: 2021-
|
13
|
+
date: 2021-06-05 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.
|
@@ -79,6 +79,7 @@ files:
|
|
79
79
|
- lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb
|
80
80
|
- lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb
|
81
81
|
- lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb
|
82
|
+
- lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb
|
82
83
|
- lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb
|
83
84
|
- lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb
|
84
85
|
- lib/concurrent-ruby/concurrent/concern/deprecation.rb
|