concurrent-ruby 1.1.8 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/Gemfile +2 -8
- data/README.md +49 -28
- data/Rakefile +66 -81
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +0 -0
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +52 -22
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +10 -25
- data/lib/concurrent-ruby/concurrent/agent.rb +2 -1
- data/lib/concurrent-ruby/concurrent/array.rb +0 -10
- data/lib/concurrent-ruby/concurrent/async.rb +1 -0
- data/lib/concurrent-ruby/concurrent/atom.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +5 -4
- data/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +5 -4
- data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +3 -0
- data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +82 -151
- data/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomic/event.rb +3 -3
- data/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb +109 -0
- data/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +1 -0
- data/lib/concurrent-ruby/concurrent/atomic/locals.rb +189 -0
- data/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb +28 -0
- data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +11 -5
- data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +11 -5
- data/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +19 -3
- data/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +2 -1
- data/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +9 -9
- data/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +32 -14
- data/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +96 -89
- data/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb +37 -0
- data/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +15 -4
- data/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +1 -1
- data/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +1 -1
- data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +2 -0
- data/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +2 -2
- data/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +16 -8
- 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/concern/logging.rb +86 -2
- data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
- data/lib/concurrent-ruby/concurrent/configuration.rb +4 -87
- data/lib/concurrent-ruby/concurrent/delay.rb +2 -2
- data/lib/concurrent-ruby/concurrent/errors.rb +5 -0
- data/lib/concurrent-ruby/concurrent/exchanger.rb +1 -0
- data/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +17 -14
- data/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb +13 -3
- data/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +3 -3
- data/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb +4 -0
- data/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb +10 -4
- data/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb +26 -37
- data/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +6 -6
- data/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +1 -1
- data/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +4 -1
- data/lib/concurrent-ruby/concurrent/hash.rb +0 -9
- data/lib/concurrent-ruby/concurrent/immutable_struct.rb +1 -1
- data/lib/concurrent-ruby/concurrent/ivar.rb +2 -1
- data/lib/concurrent-ruby/concurrent/map.rb +43 -30
- data/lib/concurrent-ruby/concurrent/maybe.rb +1 -1
- data/lib/concurrent-ruby/concurrent/mutable_struct.rb +1 -1
- data/lib/concurrent-ruby/concurrent/mvar.rb +1 -1
- data/lib/concurrent-ruby/concurrent/promise.rb +2 -1
- data/lib/concurrent-ruby/concurrent/promises.rb +7 -6
- data/lib/concurrent-ruby/concurrent/re_include.rb +2 -0
- data/lib/concurrent-ruby/concurrent/scheduled_task.rb +30 -17
- data/lib/concurrent-ruby/concurrent/set.rb +12 -14
- data/lib/concurrent-ruby/concurrent/settable_struct.rb +2 -2
- data/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +5 -1
- data/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +1 -3
- data/lib/concurrent-ruby/concurrent/synchronization/condition.rb +2 -0
- data/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb +29 -0
- data/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +3 -1
- data/lib/concurrent-ruby/concurrent/synchronization/lock.rb +2 -0
- data/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +6 -5
- data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +18 -5
- data/lib/concurrent-ruby/concurrent/synchronization/object.rb +12 -44
- data/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb +36 -0
- data/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +77 -12
- data/lib/concurrent-ruby/concurrent/synchronization.rb +1 -18
- data/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +36 -39
- data/lib/concurrent-ruby/concurrent/thread_safe/util/cheap_lockable.rb +2 -39
- data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +16 -27
- data/lib/concurrent-ruby/concurrent/timer_task.rb +11 -33
- data/lib/concurrent-ruby/concurrent/tuple.rb +1 -5
- data/lib/concurrent-ruby/concurrent/tvar.rb +22 -61
- data/lib/concurrent-ruby/concurrent/utility/engine.rb +5 -16
- data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +7 -46
- data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +8 -10
- data/lib/concurrent-ruby/concurrent/utility/native_integer.rb +1 -0
- data/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +36 -89
- data/lib/concurrent-ruby/concurrent/version.rb +1 -1
- data/lib/concurrent-ruby/concurrent-ruby.rb +5 -1
- metadata +11 -12
- data/lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb +0 -66
- data/lib/concurrent-ruby/concurrent/atomic/java_thread_local_var.rb +0 -37
- data/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb +0 -181
- data/lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb +0 -45
- data/lib/concurrent-ruby/concurrent/synchronization/mri_object.rb +0 -44
- data/lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb +0 -65
- data/lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb +0 -49
- data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cad803df2c0fe187f3208dce2972feaa94daefcbd3749770abe3abfc0642fe9
|
4
|
+
data.tar.gz: 216b0196496fde70f53cc82b83cd593ec5267a53dcac9a312f254ae627f7761e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 605762fd9c26a5a783dcb834f9db5d818ba2b52431b382a7abd33aaddfcc0df8c5005abf0e1a7ebacf3aced9ebb61ee7080fd59050805422f4fc5593925ae935
|
7
|
+
data.tar.gz: ae916f03459f583497ab268aa82cc79d24dcddb2c51a86abf86313ad77faf975d10d22048ca03179c6583832fc0e25f3f3c1618de0668f9a2774486d7e15e41c
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,52 @@
|
|
1
1
|
## Current
|
2
2
|
|
3
|
+
## Release v1.2.2 (24 Feb 2023)
|
4
|
+
|
5
|
+
* (#993) Fix arguments passed to `Concurrent::Map`'s `default_proc`.
|
6
|
+
|
7
|
+
## Release v1.2.1 (24 Feb 2023)
|
8
|
+
|
9
|
+
* (#990) Add missing `require 'fiber'` for `FiberLocalVar`.
|
10
|
+
* (#989) Optimize `Concurrent::Map#[]` on CRuby by letting the backing Hash handle the `default_proc`.
|
11
|
+
|
12
|
+
## Release v1.2.0 (23 Jan 2023)
|
13
|
+
|
14
|
+
* (#962) Fix ReentrantReadWriteLock to use the same granularity for locals as for Mutex it uses.
|
15
|
+
* (#983) Add FiberLocalVar
|
16
|
+
* (#934) concurrent-ruby now supports requiring individual classes (public classes listed in the docs), e.g., `require 'concurrent/map'`
|
17
|
+
* (#976) Let `Promises.any_fulfilled_future` take an `Event`
|
18
|
+
* Improve documentation of various classes
|
19
|
+
* (#975) Set the Ruby compatibility version at 2.3
|
20
|
+
* (#972) Remove Rubinius-related code
|
21
|
+
|
22
|
+
## Release v1.1.10 (22 Mar 2022)
|
23
|
+
|
24
|
+
concurrent-ruby:
|
25
|
+
|
26
|
+
* (#951) Set the Ruby compatibility version at 2.2
|
27
|
+
* (#939, #933) The `caller_runs` fallback policy no longer blocks reads from the job queue by worker threads
|
28
|
+
* (#938, #761, #652) You can now explicitly `prune_pool` a thread pool (Sylvain Joyeux)
|
29
|
+
* (#937, #757, #670) We switched the Yahoo stock API for demos to Alpha Vantage (Gustavo Caso)
|
30
|
+
* (#932, #931) We changed how `SafeTaskExecutor` handles local jump errors (Aaron Jensen)
|
31
|
+
* (#927) You can use keyword arguments in your initialize when using `Async` (Matt Larraz)
|
32
|
+
* (#926, #639) We removed timeout from `TimerTask` because it wasn't sound, and now it's a no-op with a warning (Jacob Atzen)
|
33
|
+
* (#919) If you double-lock a re-entrant read-write lock, we promote to locked for writing (zp yuan)
|
34
|
+
* (#915) `monotonic_time` now accepts an optional unit parameter, as Ruby's `clock_gettime` (Jean Boussier)
|
35
|
+
|
36
|
+
## Release v1.1.9 (5 Jun 2021)
|
37
|
+
|
38
|
+
concurrent-ruby:
|
39
|
+
|
40
|
+
* (#866) Child promise state not set to :pending immediately after #execute when parent has completed
|
41
|
+
* (#905, #872) Fix RubyNonConcurrentPriorityQueue#delete method
|
42
|
+
* (2df0337d) Make sure locks are not shared on shared when objects are dup/cloned
|
43
|
+
* (#900, #906, #796, #847, #911) Fix Concurrent::Set tread-safety issues on CRuby
|
44
|
+
* (#907) Add new ConcurrentMap backend for TruffleRuby
|
45
|
+
|
3
46
|
## Release v1.1.8 (20 January 2021)
|
4
47
|
|
48
|
+
concurrent-ruby:
|
49
|
+
|
5
50
|
* (#885) Fix race condition in TVar for stale reads
|
6
51
|
* (#884) RubyThreadLocalVar: Do not iterate over hash which might conflict with new pair addition
|
7
52
|
|
data/Gemfile
CHANGED
@@ -2,7 +2,6 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
require File.join(File.dirname(__FILE__), 'lib/concurrent-ruby/concurrent/version')
|
4
4
|
require File.join(File.dirname(__FILE__ ), 'lib/concurrent-ruby-edge/concurrent/edge/version')
|
5
|
-
require File.join(File.dirname(__FILE__ ), 'lib/concurrent-ruby/concurrent/utility/engine')
|
6
5
|
|
7
6
|
no_path = ENV['NO_PATH']
|
8
7
|
options = no_path ? {} : { path: '.' }
|
@@ -12,7 +11,7 @@ gem 'concurrent-ruby-edge', Concurrent::EDGE_VERSION, options
|
|
12
11
|
gem 'concurrent-ruby-ext', Concurrent::VERSION, options.merge(platform: :mri)
|
13
12
|
|
14
13
|
group :development do
|
15
|
-
gem 'rake',
|
14
|
+
gem 'rake', '~> 13.0'
|
16
15
|
gem 'rake-compiler', '~> 1.0', '>= 1.0.7'
|
17
16
|
gem 'rake-compiler-dock', '~> 1.0'
|
18
17
|
gem 'pry', '~> 0.11', platforms: :mri
|
@@ -26,7 +25,7 @@ end
|
|
26
25
|
|
27
26
|
group :testing do
|
28
27
|
gem 'rspec', '~> 3.7'
|
29
|
-
gem 'timecop', '~> 0.
|
28
|
+
gem 'timecop', '~> 0.9'
|
30
29
|
gem 'sigdump', require: false
|
31
30
|
end
|
32
31
|
|
@@ -35,8 +34,3 @@ group :coverage, optional: !ENV['COVERAGE'] do
|
|
35
34
|
gem 'simplecov', '~> 0.16.0', require: false
|
36
35
|
gem 'coveralls', '~> 0.8.2', require: false
|
37
36
|
end
|
38
|
-
|
39
|
-
group :benchmarks, optional: true do
|
40
|
-
gem 'benchmark-ips', '~> 2.7'
|
41
|
-
gem 'bench9000'
|
42
|
-
end
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Concurrent Ruby
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby)
|
4
|
-
[![Build Status](https://travis-ci.org/ruby-concurrency/concurrent-ruby.svg?branch=master)](https://travis-ci.org/ruby-concurrency/concurrent-ruby)
|
5
|
-
[![Build status](https://ci.appveyor.com/api/projects/status/iq8aboyuu3etad4w?svg=true)](https://ci.appveyor.com/project/rubyconcurrency/concurrent-ruby)
|
6
4
|
[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
|
7
5
|
[![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby)
|
8
6
|
|
@@ -39,11 +37,13 @@ The design goals of this gem are:
|
|
39
37
|
appreciate your help. Would you like to contribute? Great! Have a look at
|
40
38
|
[issues with `looking-for-contributor` label](https://github.com/ruby-concurrency/concurrent-ruby/issues?q=is%3Aissue+is%3Aopen+label%3Alooking-for-contributor).** And if you pick something up let us know on the issue.
|
41
39
|
|
40
|
+
You can also get started by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to concurrent-ruby on CodeTriage](https://www.codetriage.com/ruby-concurrency/concurrent-ruby). [![Open Source Helpers](https://www.codetriage.com/ruby-concurrency/concurrent-ruby/badges/users.svg)](https://www.codetriage.com/ruby-concurrency/concurrent-ruby)
|
41
|
+
|
42
42
|
## Thread Safety
|
43
43
|
|
44
44
|
*Concurrent Ruby makes one of the strongest thread safety guarantees of any Ruby concurrency
|
45
|
-
library, providing consistent behavior and guarantees on all
|
46
|
-
(MRI/CRuby, JRuby,
|
45
|
+
library, providing consistent behavior and guarantees on all three main Ruby interpreters
|
46
|
+
(MRI/CRuby, JRuby, TruffleRuby).*
|
47
47
|
|
48
48
|
Every abstraction in this library is thread safe. Specific thread safety guarantees are documented
|
49
49
|
with each abstraction.
|
@@ -58,9 +58,9 @@ other Ruby library, many of which support the mantra of
|
|
58
58
|
Concurrent Ruby is also the only Ruby library which provides a full suite of thread safe and
|
59
59
|
immutable variable types and data structures.
|
60
60
|
|
61
|
-
We've also initiated discussion to document [memory model](docs-source/synchronization.md) of Ruby which
|
62
|
-
would provide consistent behaviour and guarantees on all
|
63
|
-
(MRI/CRuby, JRuby,
|
61
|
+
We've also initiated discussion to document the [memory model](docs-source/synchronization.md) of Ruby which
|
62
|
+
would provide consistent behaviour and guarantees on all three main Ruby interpreters
|
63
|
+
(MRI/CRuby, JRuby, TruffleRuby).
|
64
64
|
|
65
65
|
## Features & Documentation
|
66
66
|
|
@@ -259,16 +259,9 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
|
|
259
259
|
|
260
260
|
## Supported Ruby versions
|
261
261
|
|
262
|
-
* MRI 2.
|
263
|
-
* JRuby 9000
|
264
|
-
* TruffleRuby
|
265
|
-
* Any Ruby interpreter that is compliant with Ruby 2.0 or newer.
|
266
|
-
|
267
|
-
Actually we still support mri 1.9.3 and jruby 1.7.27 but we are looking at ways how to drop the support.
|
268
|
-
Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs is supported.
|
269
|
-
|
270
|
-
The legacy support for Rubinius is kept but it is no longer maintained, if you would like to help
|
271
|
-
please respond to [#739](https://github.com/ruby-concurrency/concurrent-ruby/issues/739).
|
262
|
+
* MRI 2.3 and above
|
263
|
+
* Latest JRuby 9000
|
264
|
+
* Latest TruffleRuby
|
272
265
|
|
273
266
|
## Usage
|
274
267
|
|
@@ -278,7 +271,12 @@ Everything within this gem can be loaded simply by requiring it:
|
|
278
271
|
require 'concurrent'
|
279
272
|
```
|
280
273
|
|
281
|
-
|
274
|
+
You can also require a specific abstraction [part of the public documentation](https://ruby-concurrency.github.io/concurrent-ruby/master/index.html) since concurrent-ruby 1.2.0, for example:
|
275
|
+
```ruby
|
276
|
+
require 'concurrent/map'
|
277
|
+
require 'concurrent/atomic/atomic_reference'
|
278
|
+
require 'concurrent/executor/fixed_thread_pool'
|
279
|
+
```
|
282
280
|
|
283
281
|
To use the tools in the Edge gem it must be required separately:
|
284
282
|
|
@@ -353,23 +351,46 @@ and load the appropriate C extensions.
|
|
353
351
|
No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The
|
354
352
|
best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions.
|
355
353
|
|
354
|
+
## Building the gem
|
355
|
+
|
356
|
+
### Requirements
|
357
|
+
|
358
|
+
* Recent CRuby
|
359
|
+
* JRuby, `rbenv install jruby-9.2.17.0`
|
360
|
+
* Set env variable `CONCURRENT_JRUBY_HOME` to point to it, e.g. `/usr/local/opt/rbenv/versions/jruby-9.2.17.0`
|
361
|
+
* Install Docker, required for Windows builds
|
362
|
+
|
363
|
+
### Publishing the Gem
|
364
|
+
|
365
|
+
* Update `version.rb`
|
366
|
+
* Update the CHANGELOG
|
367
|
+
* Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the documentation.
|
368
|
+
* Commit (and push) the changes.
|
369
|
+
* Use `bundle exec rake release` to release the gem.
|
370
|
+
It consists of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps.
|
371
|
+
It will ask at the end before publishing anything. Steps can also be executed individually.
|
372
|
+
|
356
373
|
## Maintainers
|
357
374
|
|
358
|
-
*
|
359
|
-
*
|
360
|
-
*
|
375
|
+
* [Benoit Daloze](https://github.com/eregon)
|
376
|
+
* [Matthew Draper](https://github.com/matthewd)
|
377
|
+
* [Rafael França](https://github.com/rafaelfranca)
|
378
|
+
* [Samuel Williams](https://github.com/ioquatix)
|
361
379
|
|
362
380
|
### Special Thanks to
|
363
381
|
|
364
|
-
*
|
365
|
-
*
|
366
|
-
*
|
382
|
+
* [Jerry D'Antonio](https://github.com/jdantonio) for creating the gem
|
383
|
+
* [Brian Durand](https://github.com/bdurand) for the `ref` gem
|
384
|
+
* [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems
|
385
|
+
* [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem
|
367
386
|
|
368
|
-
|
387
|
+
to the past maintainers
|
369
388
|
|
370
|
-
*
|
371
|
-
*
|
372
|
-
*
|
389
|
+
* [Chris Seaton](https://github.com/chrisseaton)
|
390
|
+
* [Petr Chalupa](https://github.com/pitr-ch)
|
391
|
+
* [Michele Della Torre](https://github.com/mighe)
|
392
|
+
* [Paweł Obrok](https://github.com/obrok)
|
393
|
+
* [Lucas Allan](https://github.com/lucasallan)
|
373
394
|
|
374
395
|
and to [Ruby Association](https://www.ruby.or.jp/en/) for sponsoring a project
|
375
396
|
["Enhancing Ruby’s concurrency tooling"](https://www.ruby.or.jp/en/news/20181106) in 2018.
|
data/Rakefile
CHANGED
@@ -2,15 +2,6 @@ require_relative 'lib/concurrent-ruby/concurrent/version'
|
|
2
2
|
require_relative 'lib/concurrent-ruby-edge/concurrent/edge/version'
|
3
3
|
require_relative 'lib/concurrent-ruby/concurrent/utility/engine'
|
4
4
|
|
5
|
-
if Concurrent.ruby_version :<, 2, 0, 0
|
6
|
-
# @!visibility private
|
7
|
-
module Kernel
|
8
|
-
def __dir__
|
9
|
-
File.dirname __FILE__
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
5
|
core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec')
|
15
6
|
ext_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec')
|
16
7
|
edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.gemspec')
|
@@ -24,7 +15,7 @@ Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext|
|
|
24
15
|
ext.lib_dir = 'lib/concurrent-ruby/concurrent'
|
25
16
|
end
|
26
17
|
|
27
|
-
unless Concurrent.on_jruby?
|
18
|
+
unless Concurrent.on_jruby? || Concurrent.on_truffleruby?
|
28
19
|
require 'rake/extensiontask'
|
29
20
|
|
30
21
|
Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext|
|
@@ -43,14 +34,20 @@ namespace :repackage do
|
|
43
34
|
task :all do
|
44
35
|
Dir.chdir(__dir__) do
|
45
36
|
# store gems in vendor cache for docker
|
46
|
-
|
37
|
+
Bundler.with_original_env do
|
38
|
+
sh 'bundle package'
|
39
|
+
end
|
47
40
|
|
48
41
|
# build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem
|
49
42
|
Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke
|
50
43
|
|
51
44
|
# build all gem files
|
52
45
|
%w[x86-mingw32 x64-mingw32].each do |plat|
|
53
|
-
RakeCompilerDock.sh
|
46
|
+
RakeCompilerDock.sh(
|
47
|
+
"bundle install --local && bundle exec rake native:#{plat} gem --trace",
|
48
|
+
platform: plat,
|
49
|
+
options: ['--privileged'], # otherwise the directory in the image is empty
|
50
|
+
runas: false)
|
54
51
|
end
|
55
52
|
end
|
56
53
|
end
|
@@ -63,7 +60,10 @@ Gem::PackageTask.new(core_gemspec) {} if core_gemspec
|
|
63
60
|
Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && !Concurrent.on_jruby?
|
64
61
|
Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec
|
65
62
|
|
66
|
-
CLEAN.include(
|
63
|
+
CLEAN.include(
|
64
|
+
'lib/concurrent-ruby/concurrent/concurrent_ruby_ext.*',
|
65
|
+
'lib/concurrent-ruby/concurrent/2.*',
|
66
|
+
'lib/concurrent-ruby/concurrent/*.jar')
|
67
67
|
|
68
68
|
begin
|
69
69
|
require 'rspec'
|
@@ -77,20 +77,21 @@ begin
|
|
77
77
|
options = %w[ --color
|
78
78
|
--backtrace
|
79
79
|
--order defined
|
80
|
-
--format documentation
|
81
|
-
--tag ~notravis ]
|
80
|
+
--format documentation ]
|
82
81
|
t.rspec_opts = [*options].join(' ')
|
83
82
|
end
|
84
83
|
|
85
84
|
desc '* test packaged and installed gems instead of local files'
|
86
85
|
task :installed do
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
86
|
+
Bundler.with_original_env do
|
87
|
+
Dir.chdir(__dir__) do
|
88
|
+
sh "gem install pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
|
89
|
+
sh "gem install pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if Concurrent.on_cruby?
|
90
|
+
sh "gem install pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem"
|
91
|
+
ENV['NO_PATH'] = 'true'
|
92
|
+
sh 'bundle update'
|
93
|
+
sh 'bundle exec rake spec:ci'
|
94
|
+
end
|
94
95
|
end
|
95
96
|
end
|
96
97
|
end
|
@@ -98,6 +99,19 @@ begin
|
|
98
99
|
desc 'executed in CI'
|
99
100
|
task :ci => [:compile, 'spec:ci']
|
100
101
|
|
102
|
+
desc 'run each spec file in a separate process to help find missing requires'
|
103
|
+
task 'spec:isolated' do
|
104
|
+
glob = "#{ENV['DIR'] || 'spec'}/**/*_spec.rb"
|
105
|
+
from = ENV['FROM']
|
106
|
+
env = { 'ISOLATED' => 'true' }
|
107
|
+
Dir[glob].each do |spec|
|
108
|
+
next if from and from != spec
|
109
|
+
from = nil if from == spec
|
110
|
+
|
111
|
+
sh env, 'rspec', spec
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
101
115
|
task :default => [:clobber, :compile, :spec]
|
102
116
|
rescue LoadError => e
|
103
117
|
puts 'RSpec is not installed, skipping test task definitions: ' + e.message
|
@@ -135,7 +149,7 @@ begin
|
|
135
149
|
task :update_readme do
|
136
150
|
Dir.chdir __dir__ do
|
137
151
|
content = File.read(File.join('README.md')).
|
138
|
-
|
152
|
+
gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_|
|
139
153
|
case $1
|
140
154
|
when 'LockFreeLinkedSet'
|
141
155
|
"{Concurrent::Edge::#{$1} #{$1}}"
|
@@ -165,9 +179,9 @@ begin
|
|
165
179
|
desc "* of #{name} into subdir #{name}"
|
166
180
|
YARD::Rake::YardocTask.new(name) do |yard|
|
167
181
|
yard.options.push(
|
168
|
-
|
169
|
-
|
170
|
-
|
182
|
+
'--output-dir', output_dir,
|
183
|
+
'--main', 'tmp/README.md',
|
184
|
+
*common_yard_options)
|
171
185
|
yard.files = ['./lib/concurrent-ruby/**/*.rb',
|
172
186
|
'./lib/concurrent-ruby-edge/**/*.rb',
|
173
187
|
'./ext/concurrent_ruby_ext/**/*.c',
|
@@ -189,39 +203,11 @@ begin
|
|
189
203
|
desc "* signpost for versions"
|
190
204
|
YARD::Rake::YardocTask.new(:signpost) do |yard|
|
191
205
|
yard.options.push(
|
192
|
-
|
193
|
-
|
194
|
-
|
206
|
+
'--output-dir', 'docs',
|
207
|
+
'--main', 'docs-source/signpost.md',
|
208
|
+
*common_yard_options)
|
195
209
|
yard.files = ['no-lib']
|
196
210
|
end
|
197
|
-
|
198
|
-
define_uptodate_task = -> name do
|
199
|
-
namespace name do
|
200
|
-
desc "** ensure that #{name} generated documentation is matching the source code"
|
201
|
-
task :uptodate do
|
202
|
-
Dir.chdir(__dir__) do
|
203
|
-
begin
|
204
|
-
FileUtils.cp_r 'docs', 'docs-copy', verbose: true
|
205
|
-
Rake::Task["yard:#{name}"].invoke
|
206
|
-
sh 'diff -r docs/ docs-copy/' do |ok, res|
|
207
|
-
unless ok
|
208
|
-
begin
|
209
|
-
STDOUT.puts 'Command failed. Continue? (y/n)'
|
210
|
-
input = STDIN.gets.strip.downcase
|
211
|
-
end until %w(y n).include?(input)
|
212
|
-
exit 1 if input == 'n'
|
213
|
-
end
|
214
|
-
end
|
215
|
-
ensure
|
216
|
-
FileUtils.rm_rf 'docs-copy', verbose: true
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
define_uptodate_task.call current_yard_version_name
|
224
|
-
define_uptodate_task.call 'master'
|
225
211
|
end
|
226
212
|
|
227
213
|
rescue LoadError => e
|
@@ -234,15 +220,13 @@ task :release => ['release:checks', 'release:build', 'release:test', 'release:pu
|
|
234
220
|
namespace :release do
|
235
221
|
# Depends on environment of @pitr-ch
|
236
222
|
|
237
|
-
|
238
|
-
jruby_version = 'jruby-9.2.9.0'
|
239
|
-
|
240
|
-
task :checks => "yard:#{current_yard_version_name}:uptodate" do
|
223
|
+
task :checks do
|
241
224
|
Dir.chdir(__dir__) do
|
242
225
|
sh 'test -z "$(git status --porcelain)"' do |ok, res|
|
243
226
|
unless ok
|
244
227
|
begin
|
245
|
-
|
228
|
+
status = `git status --porcelain`
|
229
|
+
STDOUT.puts 'There are local changes that you might want to commit.', status, 'Continue? (y/n)'
|
246
230
|
input = STDIN.gets.strip.downcase
|
247
231
|
end until %w(y n).include?(input)
|
248
232
|
exit 1 if input == 'n'
|
@@ -250,10 +234,10 @@ namespace :release do
|
|
250
234
|
end
|
251
235
|
sh 'git fetch'
|
252
236
|
sh 'test $(git show-ref --verify --hash refs/heads/master) = ' +
|
253
|
-
|
237
|
+
'$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res|
|
254
238
|
unless ok
|
255
239
|
begin
|
256
|
-
STDOUT.puts '
|
240
|
+
STDOUT.puts 'Local master branch is not pushed to origin.', 'Continue? (y/n)'
|
257
241
|
input = STDIN.gets.strip.downcase
|
258
242
|
end until %w(y n).include?(input)
|
259
243
|
exit 1 if input == 'n'
|
@@ -268,19 +252,18 @@ namespace :release do
|
|
268
252
|
desc '* test actual installed gems instead of cloned repository on MRI and JRuby'
|
269
253
|
task :test do
|
270
254
|
Dir.chdir(__dir__) do
|
271
|
-
|
255
|
+
puts "Testing with the installed gem"
|
272
256
|
|
273
|
-
|
274
|
-
|
275
|
-
|
257
|
+
Bundler.with_original_env do
|
258
|
+
sh 'ruby -v'
|
259
|
+
sh 'bundle exec rake spec:installed'
|
276
260
|
|
277
|
-
|
278
|
-
|
279
|
-
|
261
|
+
env = { "PATH" => "#{ENV['CONCURRENT_JRUBY_HOME']}/bin:#{ENV['PATH']}" }
|
262
|
+
sh env, 'ruby -v'
|
263
|
+
sh env, 'bundle exec rake spec:installed'
|
264
|
+
end
|
280
265
|
|
281
266
|
puts 'Windows build is untested'
|
282
|
-
|
283
|
-
ENV['RBENV_VERSION'] = old
|
284
267
|
end
|
285
268
|
end
|
286
269
|
|
@@ -288,16 +271,17 @@ namespace :release do
|
|
288
271
|
task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps']
|
289
272
|
|
290
273
|
namespace :publish do
|
274
|
+
publish_base = true
|
291
275
|
publish_edge = false
|
292
276
|
|
293
277
|
task :ask do
|
294
278
|
begin
|
295
|
-
STDOUT.puts 'Do you want to publish anything? (y/n)'
|
279
|
+
STDOUT.puts 'Do you want to publish anything now? (y/n)'
|
296
280
|
input = STDIN.gets.strip.downcase
|
297
281
|
end until %w(y n).include?(input)
|
298
282
|
exit 1 if input == 'n'
|
299
283
|
begin
|
300
|
-
STDOUT.puts 'Do you want to publish edge
|
284
|
+
STDOUT.puts 'It will publish `concurrent-ruby`. Do you want to publish `concurrent-ruby-edge`? (y/n)'
|
301
285
|
input = STDIN.gets.strip.downcase
|
302
286
|
end until %w(y n).include?(input)
|
303
287
|
publish_edge = input == 'y'
|
@@ -306,8 +290,8 @@ namespace :release do
|
|
306
290
|
desc '** tag HEAD with current version and push to github'
|
307
291
|
task :tag => :ask do
|
308
292
|
Dir.chdir(__dir__) do
|
309
|
-
sh "git tag v#{Concurrent::VERSION}"
|
310
|
-
sh "git push origin v#{Concurrent::VERSION}"
|
293
|
+
sh "git tag v#{Concurrent::VERSION}" if publish_base
|
294
|
+
sh "git push origin v#{Concurrent::VERSION}" if publish_base
|
311
295
|
sh "git tag edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
|
312
296
|
sh "git push origin edge-v#{Concurrent::EDGE_VERSION}" if publish_edge
|
313
297
|
end
|
@@ -316,16 +300,17 @@ namespace :release do
|
|
316
300
|
desc '** push all *.gem files to rubygems'
|
317
301
|
task :rubygems => :ask do
|
318
302
|
Dir.chdir(__dir__) do
|
319
|
-
sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
|
303
|
+
sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem" if publish_base
|
320
304
|
sh "gem push pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem" if publish_edge
|
321
|
-
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem"
|
322
|
-
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem"
|
323
|
-
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem"
|
305
|
+
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}.gem" if publish_base
|
306
|
+
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x64-mingw32.gem" if publish_base
|
307
|
+
sh "gem push pkg/concurrent-ruby-ext-#{Concurrent::VERSION}-x86-mingw32.gem" if publish_base
|
324
308
|
end
|
325
309
|
end
|
326
310
|
|
327
311
|
desc '** print post release steps'
|
328
312
|
task :post_steps do
|
313
|
+
# TODO: (petr 05-Jun-2021) automate and renew the process
|
329
314
|
puts 'Manually: create a release on GitHub with relevant changelog part'
|
330
315
|
puts 'Manually: send email same as release with relevant changelog part'
|
331
316
|
puts 'Manually: tweet'
|
File without changes
|
@@ -10,6 +10,7 @@ import org.jruby.RubyNumeric;
|
|
10
10
|
import org.jruby.RubyObject;
|
11
11
|
import org.jruby.anno.JRubyClass;
|
12
12
|
import org.jruby.anno.JRubyMethod;
|
13
|
+
import org.jruby.runtime.Block;
|
13
14
|
import org.jruby.runtime.ObjectAllocator;
|
14
15
|
import org.jruby.runtime.ThreadContext;
|
15
16
|
import org.jruby.runtime.builtin.IRubyObject;
|
@@ -45,9 +46,13 @@ public class JavaSemaphoreLibrary {
|
|
45
46
|
}
|
46
47
|
|
47
48
|
@JRubyMethod
|
48
|
-
public IRubyObject acquire(ThreadContext context,
|
49
|
-
this.
|
50
|
-
|
49
|
+
public IRubyObject acquire(ThreadContext context, final Block block) throws InterruptedException {
|
50
|
+
return this.acquire(context, 1, block);
|
51
|
+
}
|
52
|
+
|
53
|
+
@JRubyMethod
|
54
|
+
public IRubyObject acquire(ThreadContext context, IRubyObject permits, final Block block) throws InterruptedException {
|
55
|
+
return this.acquire(context, rubyFixnumToPositiveInt(permits, "permits"), block);
|
51
56
|
}
|
52
57
|
|
53
58
|
@JRubyMethod(name = "available_permits")
|
@@ -60,30 +65,32 @@ public class JavaSemaphoreLibrary {
|
|
60
65
|
return getRuntime().newFixnum(this.semaphore.drainPermits());
|
61
66
|
}
|
62
67
|
|
63
|
-
@JRubyMethod
|
64
|
-
public IRubyObject acquire(ThreadContext context) throws InterruptedException {
|
65
|
-
this.semaphore.acquire(1);
|
66
|
-
return context.nil;
|
67
|
-
}
|
68
|
-
|
69
68
|
@JRubyMethod(name = "try_acquire")
|
70
|
-
public IRubyObject tryAcquire(ThreadContext context) throws InterruptedException {
|
71
|
-
|
69
|
+
public IRubyObject tryAcquire(ThreadContext context, final Block block) throws InterruptedException {
|
70
|
+
int permitsInt = 1;
|
71
|
+
boolean acquired = semaphore.tryAcquire(permitsInt);
|
72
|
+
|
73
|
+
return triedAcquire(context, permitsInt, acquired, block);
|
72
74
|
}
|
73
75
|
|
74
76
|
@JRubyMethod(name = "try_acquire")
|
75
|
-
public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits) throws InterruptedException {
|
76
|
-
|
77
|
+
public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, final Block block) throws InterruptedException {
|
78
|
+
int permitsInt = rubyFixnumToPositiveInt(permits, "permits");
|
79
|
+
boolean acquired = semaphore.tryAcquire(permitsInt);
|
80
|
+
|
81
|
+
return triedAcquire(context, permitsInt, acquired, block);
|
77
82
|
}
|
78
83
|
|
79
84
|
@JRubyMethod(name = "try_acquire")
|
80
|
-
public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, IRubyObject timeout) throws InterruptedException {
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
85
|
+
public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, IRubyObject timeout, final Block block) throws InterruptedException {
|
86
|
+
int permitsInt = rubyFixnumToPositiveInt(permits, "permits");
|
87
|
+
boolean acquired = semaphore.tryAcquire(
|
88
|
+
permitsInt,
|
89
|
+
rubyNumericToLong(timeout, "timeout"),
|
90
|
+
java.util.concurrent.TimeUnit.SECONDS
|
91
|
+
);
|
92
|
+
|
93
|
+
return triedAcquire(context, permitsInt, acquired, block);
|
87
94
|
}
|
88
95
|
|
89
96
|
@JRubyMethod
|
@@ -93,8 +100,8 @@ public class JavaSemaphoreLibrary {
|
|
93
100
|
}
|
94
101
|
|
95
102
|
@JRubyMethod
|
96
|
-
public IRubyObject release(ThreadContext context, IRubyObject
|
97
|
-
this.semaphore.release(rubyFixnumToPositiveInt(
|
103
|
+
public IRubyObject release(ThreadContext context, IRubyObject permits) {
|
104
|
+
this.semaphore.release(rubyFixnumToPositiveInt(permits, "permits"));
|
98
105
|
return getRuntime().newBoolean(true);
|
99
106
|
}
|
100
107
|
|
@@ -104,6 +111,29 @@ public class JavaSemaphoreLibrary {
|
|
104
111
|
return context.nil;
|
105
112
|
}
|
106
113
|
|
114
|
+
private IRubyObject acquire(ThreadContext context, int permits, final Block block) throws InterruptedException {
|
115
|
+
this.semaphore.acquire(permits);
|
116
|
+
|
117
|
+
if (!block.isGiven()) return context.nil;
|
118
|
+
|
119
|
+
try {
|
120
|
+
return block.yieldSpecific(context);
|
121
|
+
} finally {
|
122
|
+
this.semaphore.release(permits);
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
private IRubyObject triedAcquire(ThreadContext context, int permits, boolean acquired, final Block block) {
|
127
|
+
if (!block.isGiven()) return getRuntime().newBoolean(acquired);
|
128
|
+
if (!acquired) return context.nil;
|
129
|
+
|
130
|
+
try {
|
131
|
+
return block.yieldSpecific(context);
|
132
|
+
} finally {
|
133
|
+
this.semaphore.release(permits);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
107
137
|
private int rubyFixnumInt(IRubyObject value, String paramName) {
|
108
138
|
if (value instanceof RubyFixnum) {
|
109
139
|
RubyFixnum fixNum = (RubyFixnum) value;
|