concurrent-ruby 1.1.5 → 1.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +65 -1
  3. data/Gemfile +6 -10
  4. data/{LICENSE.md → LICENSE.txt} +18 -20
  5. data/README.md +46 -23
  6. data/Rakefile +46 -44
  7. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +0 -0
  8. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +52 -22
  9. data/lib/{concurrent → concurrent-ruby/concurrent}/agent.rb +0 -0
  10. data/lib/{concurrent → concurrent-ruby/concurrent}/array.rb +6 -6
  11. data/lib/{concurrent → concurrent-ruby/concurrent}/async.rb +10 -20
  12. data/lib/{concurrent → concurrent-ruby/concurrent}/atom.rb +1 -1
  13. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/abstract_thread_local_var.rb +0 -0
  14. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_boolean.rb +2 -2
  15. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_fixnum.rb +0 -0
  16. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_markable_reference.rb +0 -0
  17. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/atomic_reference.rb +1 -0
  18. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/count_down_latch.rb +1 -1
  19. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/cyclic_barrier.rb +0 -0
  20. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/event.rb +2 -2
  21. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_count_down_latch.rb +0 -0
  22. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/java_thread_local_var.rb +0 -0
  23. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_boolean.rb +0 -0
  24. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_atomic_fixnum.rb +0 -0
  25. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_count_down_latch.rb +0 -0
  26. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/mutex_semaphore.rb +18 -2
  27. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/read_write_lock.rb +0 -0
  28. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/reentrant_read_write_lock.rb +4 -6
  29. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/ruby_thread_local_var.rb +60 -40
  30. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/semaphore.rb +26 -5
  31. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic/thread_local_var.rb +1 -1
  32. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/mutex_atomic.rb +0 -0
  33. data/lib/{concurrent → concurrent-ruby/concurrent}/atomic_reference/numeric_cas_wrapper.rb +0 -0
  34. data/lib/{concurrent → concurrent-ruby/concurrent}/atomics.rb +0 -0
  35. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_notify_observer_set.rb +0 -0
  36. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/copy_on_write_observer_set.rb +0 -0
  37. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/java_non_concurrent_priority_queue.rb +0 -0
  38. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/lock_free_stack.rb +0 -0
  39. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/atomic_reference_map_backend.rb +0 -0
  40. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/mri_map_backend.rb +1 -1
  41. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/non_concurrent_map_backend.rb +0 -0
  42. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/map/synchronized_map_backend.rb +0 -0
  43. data/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +14 -0
  44. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/non_concurrent_priority_queue.rb +1 -1
  45. data/lib/{concurrent → concurrent-ruby/concurrent}/collection/ruby_non_concurrent_priority_queue.rb +11 -1
  46. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/deprecation.rb +0 -0
  47. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/dereferenceable.rb +2 -2
  48. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/logging.rb +0 -0
  49. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/obligation.rb +0 -0
  50. data/lib/{concurrent → concurrent-ruby/concurrent}/concern/observable.rb +0 -0
  51. data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
  52. data/lib/{concurrent → concurrent-ruby/concurrent}/configuration.rb +13 -9
  53. data/lib/{concurrent → concurrent-ruby/concurrent}/constants.rb +0 -0
  54. data/lib/{concurrent → concurrent-ruby/concurrent}/dataflow.rb +0 -0
  55. data/lib/{concurrent → concurrent-ruby/concurrent}/delay.rb +0 -0
  56. data/lib/{concurrent → concurrent-ruby/concurrent}/errors.rb +0 -0
  57. data/lib/{concurrent → concurrent-ruby/concurrent}/exchanger.rb +0 -0
  58. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/abstract_executor_service.rb +33 -36
  59. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/cached_thread_pool.rb +4 -4
  60. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/executor_service.rb +2 -2
  61. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/fixed_thread_pool.rb +29 -15
  62. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/immediate_executor.rb +0 -0
  63. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/indirect_immediate_executor.rb +0 -0
  64. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_executor_service.rb +19 -7
  65. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_single_thread_executor.rb +4 -3
  66. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/java_thread_pool_executor.rb +19 -2
  67. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_executor_service.rb +10 -6
  68. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_single_thread_executor.rb +0 -1
  69. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/ruby_thread_pool_executor.rb +46 -42
  70. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/safe_task_executor.rb +5 -5
  71. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serial_executor_service.rb +0 -0
  72. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution.rb +0 -0
  73. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/serialized_execution_delegator.rb +0 -0
  74. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/simple_executor_service.rb +1 -1
  75. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/single_thread_executor.rb +1 -0
  76. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/thread_pool_executor.rb +2 -1
  77. data/lib/{concurrent → concurrent-ruby/concurrent}/executor/timer_set.rb +0 -1
  78. data/lib/{concurrent → concurrent-ruby/concurrent}/executors.rb +0 -0
  79. data/lib/{concurrent → concurrent-ruby/concurrent}/future.rb +0 -0
  80. data/lib/{concurrent → concurrent-ruby/concurrent}/hash.rb +1 -1
  81. data/lib/{concurrent → concurrent-ruby/concurrent}/immutable_struct.rb +9 -1
  82. data/lib/{concurrent → concurrent-ruby/concurrent}/ivar.rb +0 -0
  83. data/lib/{concurrent → concurrent-ruby/concurrent}/map.rb +14 -5
  84. data/lib/{concurrent → concurrent-ruby/concurrent}/maybe.rb +0 -0
  85. data/lib/{concurrent → concurrent-ruby/concurrent}/mutable_struct.rb +12 -2
  86. data/lib/{concurrent → concurrent-ruby/concurrent}/mvar.rb +0 -0
  87. data/lib/{concurrent → concurrent-ruby/concurrent}/options.rb +0 -0
  88. data/lib/{concurrent → concurrent-ruby/concurrent}/promise.rb +1 -0
  89. data/lib/{concurrent → concurrent-ruby/concurrent}/promises.rb +0 -0
  90. data/lib/{concurrent → concurrent-ruby/concurrent}/re_include.rb +0 -0
  91. data/lib/{concurrent → concurrent-ruby/concurrent}/scheduled_task.rb +29 -16
  92. data/lib/{concurrent → concurrent-ruby/concurrent}/set.rb +19 -11
  93. data/lib/{concurrent → concurrent-ruby/concurrent}/settable_struct.rb +11 -1
  94. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_lockable_object.rb +0 -0
  95. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_object.rb +0 -0
  96. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/abstract_struct.rb +11 -0
  97. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/condition.rb +0 -0
  98. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_lockable_object.rb +0 -0
  99. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/jruby_object.rb +0 -0
  100. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lock.rb +0 -0
  101. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/lockable_object.rb +3 -5
  102. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mri_object.rb +0 -0
  103. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/mutex_lockable_object.rb +12 -0
  104. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/object.rb +0 -0
  105. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_lockable_object.rb +6 -0
  106. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/rbx_object.rb +0 -0
  107. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/truffleruby_object.rb +0 -0
  108. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization/volatile.rb +0 -0
  109. data/lib/{concurrent → concurrent-ruby/concurrent}/synchronization.rb +0 -0
  110. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/synchronized_delegator.rb +0 -0
  111. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/adder.rb +0 -0
  112. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/cheap_lockable.rb +0 -0
  113. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/data_structures.rb +26 -1
  114. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/power_of_two_tuple.rb +0 -0
  115. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/striped64.rb +1 -1
  116. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/volatile.rb +0 -0
  117. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util/xor_shift_random.rb +0 -0
  118. data/lib/{concurrent → concurrent-ruby/concurrent}/thread_safe/util.rb +0 -0
  119. data/lib/{concurrent → concurrent-ruby/concurrent}/timer_task.rb +11 -34
  120. data/lib/{concurrent → concurrent-ruby/concurrent}/tuple.rb +0 -0
  121. data/lib/{concurrent → concurrent-ruby/concurrent}/tvar.rb +19 -56
  122. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/engine.rb +0 -0
  123. data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +90 -0
  124. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_extension_loader.rb +0 -0
  125. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/native_integer.rb +0 -0
  126. data/lib/{concurrent → concurrent-ruby/concurrent}/utility/processor_counter.rb +5 -33
  127. data/lib/concurrent-ruby/concurrent/version.rb +3 -0
  128. data/lib/concurrent-ruby/concurrent-ruby.rb +5 -0
  129. data/lib/{concurrent.rb → concurrent-ruby/concurrent.rb} +0 -0
  130. metadata +132 -132
  131. data/lib/concurrent/concurrent_ruby.jar +0 -0
  132. data/lib/concurrent/utility/at_exit.rb +0 -97
  133. data/lib/concurrent/utility/monotonic_time.rb +0 -58
  134. data/lib/concurrent/version.rb +0 -3
  135. data/lib/concurrent-ruby.rb +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96f32c31090c8a0547e4ee452739bdc993aad1256e2c89cb9a46d7f7e7b5762a
4
- data.tar.gz: 307d26bde3add56b7e2b37fb0b016c7726a3ba0755dcfec8202fb0760e4ac485
3
+ metadata.gz: e2508d8671dc3f93a6d41204a69a2444669688ac1e9e7790104162ac5180579e
4
+ data.tar.gz: 5eba3636194c783d376ed010bd3d6ec8796fe409870e07a84c6b0b0ea2704b41
5
5
  SHA512:
6
- metadata.gz: b8cff93c6ef396aebbe5cf69734d9a91f0351e24b5c1846ae105b055254f972cd9d6bb99b90ce10d387627ed43c4e21db9ce47d1587e10278e80e33a53f8d4c4
7
- data.tar.gz: f367f097759eedb8e18b0117543176c9f30ab29552888fcedab0baaea355cee3d100d2559dd16cf54483778545097f8b3340bebe44b0e3ab2a51c1af3830f5e1
6
+ metadata.gz: 4c1cbc5311e939aecda5e291bb579a690807de5240bb2fb30600a9d1d9de8c353558de7d6e3e0dff871fcca364bd7caa76b304428e0fdaba323cbe04be300056
7
+ data.tar.gz: 863635cad877062864813b9ba72685b3afdadabf258a62b36f8d7093a5be9c7115d64aade01c9a98b9e68ef86dff2698e5e0cef7766b9c4dfc740e0e76eccf0c
data/CHANGELOG.md CHANGED
@@ -1,6 +1,70 @@
1
1
  ## Current
2
2
 
3
- ## Release v1.1.5, edge v0.5.0 (10 mar 2019)
3
+ ## Release v1.1.10
4
+
5
+ concurrent-ruby:
6
+
7
+ * (#951) Set the Ruby compatibility version at 2.2
8
+ * (#939, #933) The `caller_runs` fallback policy no longer blocks reads from the job queue by worker threads
9
+ * (#938, #761, #652) You can now explicitly `prune_pool` a thread pool (Sylvain Joyeux)
10
+ * (#937, #757, #670) We switched the Yahoo stock API for demos to Alpha Vantage (Gustavo Caso)
11
+ * (#932, #931) We changed how `SafeTaskExecutor` handles local jump errors (Aaron Jensen)
12
+ * (#927) You can use keyword arguments in your initialize when using `Async` (Matt Larraz)
13
+ * (#926, #639) We removed timeout from `TimerTask` because it wasn't sound, and now it's a no-op with a warning (Jacob Atzen)
14
+ * (#919) If you double-lock a re-entrant read-write lock, we promote to locked for writing (zp yuan)
15
+ * (#915) `monotonic_time` now accepts an optional unit parameter, as Ruby's `clock_gettime` (Jean Boussier)
16
+
17
+ ## Release v1.1.9 (5 Jun 2021)
18
+
19
+ concurrent-ruby:
20
+
21
+ * (#866) Child promise state not set to :pending immediately after #execute when parent has completed
22
+ * (#905, #872) Fix RubyNonConcurrentPriorityQueue#delete method
23
+ * (2df0337d) Make sure locks are not shared on shared when objects are dup/cloned
24
+ * (#900, #906, #796, #847, #911) Fix Concurrent::Set tread-safety issues on CRuby
25
+ * (#907) Add new ConcurrentMap backend for TruffleRuby
26
+
27
+ ## Release v1.1.8 (20 January 2021)
28
+
29
+ concurrent-ruby:
30
+
31
+ * (#885) Fix race condition in TVar for stale reads
32
+ * (#884) RubyThreadLocalVar: Do not iterate over hash which might conflict with new pair addition
33
+
34
+ ## Release v1.1.7 (6 August 2020)
35
+
36
+ concurrent-ruby:
37
+
38
+ * (#879) Consider falsy value on `Concurrent::Map#compute_if_absent` for fast non-blocking path
39
+ * (#876) Reset Async queue on forking, makes Async fork-safe
40
+ * (#856) Avoid running problematic code in RubyThreadLocalVar on MRI that occasionally results in segfault
41
+ * (#853) Introduce ThreadPoolExecutor without a Queue
42
+
43
+ ## Release v1.1.6, edge v0.6.0 (10 Feb 2020)
44
+
45
+ concurrent-ruby:
46
+
47
+ * (#841) Concurrent.disable_at_exit_handlers! is no longer needed and was deprecated.
48
+ * (#841) AbstractExecutorService#auto_terminate= was deprecated and has no effect.
49
+ Set :auto_terminate option instead when executor is initialized.
50
+
51
+ ## Release v1.1.6.pre1, edge v0.6.0.pre1 (26 Jan 2020)
52
+
53
+ concurrent-ruby:
54
+
55
+ * (#828) Allow to name executors, the name is also used to name their threads
56
+ * (#838) Implement #dup and #clone for structs
57
+ * (#821) Safer finalizers for thread local variables
58
+ * Documentation fixes
59
+ * (#814) Use Ruby's Etc.nprocessors if available
60
+ * (#812) Fix directory structure not to mess with packaging tools
61
+ * (#840) Fix termination of pools on JRuby
62
+
63
+ concurrent-ruby-edge:
64
+
65
+ * Add WrappingExecutor (#830)
66
+
67
+ ## Release v1.1.5, edge v0.5.0 (10 Mar 2019)
4
68
 
5
69
  concurrent-ruby:
6
70
 
data/Gemfile CHANGED
@@ -1,7 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- require File.join(File.dirname(__FILE__), 'lib/concurrent/version')
4
- require File.join(File.dirname(__FILE__ ), 'lib-edge/concurrent/edge/version')
3
+ require File.join(File.dirname(__FILE__), 'lib/concurrent-ruby/concurrent/version')
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')
5
6
 
6
7
  no_path = ENV['NO_PATH']
7
8
  options = no_path ? {} : { path: '.' }
@@ -11,9 +12,9 @@ gem 'concurrent-ruby-edge', Concurrent::EDGE_VERSION, options
11
12
  gem 'concurrent-ruby-ext', Concurrent::VERSION, options.merge(platform: :mri)
12
13
 
13
14
  group :development do
14
- gem 'rake', '~> 12.0'
15
+ gem 'rake', '~> 13.0'
15
16
  gem 'rake-compiler', '~> 1.0', '>= 1.0.7'
16
- gem 'rake-compiler-dock', '~> 0.7.0'
17
+ gem 'rake-compiler-dock', '~> 1.0'
17
18
  gem 'pry', '~> 0.11', platforms: :mri
18
19
  end
19
20
 
@@ -25,7 +26,7 @@ end
25
26
 
26
27
  group :testing do
27
28
  gem 'rspec', '~> 3.7'
28
- gem 'timecop', '~> 0.7.4'
29
+ gem 'timecop', '~> 0.9'
29
30
  gem 'sigdump', require: false
30
31
  end
31
32
 
@@ -34,8 +35,3 @@ group :coverage, optional: !ENV['COVERAGE'] do
34
35
  gem 'simplecov', '~> 0.16.0', require: false
35
36
  gem 'coveralls', '~> 0.8.2', require: false
36
37
  end
37
-
38
- group :benchmarks, optional: true do
39
- gem 'benchmark-ips', '~> 2.7'
40
- gem 'bench9000'
41
- end
@@ -1,23 +1,21 @@
1
- ```
2
1
  Copyright (c) Jerry D'Antonio -- released under the MIT license.
3
2
 
4
- http://www.opensource.org/licenses/mit-license.php
3
+ http://www.opensource.org/licenses/mit-license.php
5
4
 
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the "Software"), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
23
- ```
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
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,6 +37,8 @@ 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
@@ -105,9 +105,9 @@ We also have a [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby
105
105
  Collection classes that were originally part of the (deprecated) `thread_safe` gem:
106
106
 
107
107
  * [Array](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Array.html) A thread-safe
108
- subclass of Ruby's standard [Array](http://ruby-doc.org/core-2.2.0/Array.html).
108
+ subclass of Ruby's standard [Array](http://ruby-doc.org/core/Array.html).
109
109
  * [Hash](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Hash.html) A thread-safe
110
- subclass of Ruby's standard [Hash](http://ruby-doc.org/core-2.2.0/Hash.html).
110
+ subclass of Ruby's standard [Hash](http://ruby-doc.org/core/Hash.html).
111
111
  * [Set](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Set.html) A thread-safe
112
112
  subclass of Ruby's standard [Set](http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html).
113
113
  * [Map](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Map.html) A hash-like object
@@ -122,7 +122,7 @@ Value objects inspired by other languages:
122
122
  immutable object representing an optional value, based on
123
123
  [Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html).
124
124
 
125
- Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
125
+ Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core/Struct.html):
126
126
 
127
127
  * [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ImmutableStruct.html)
128
128
  Immutable struct where values are set at construction and cannot be changed later.
@@ -253,18 +253,17 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
253
253
  * [ErlangActor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ErlangActor.html)
254
254
  Actor implementation which precisely matches Erlang actor behaviour.
255
255
  Requires at least Ruby 2.1 otherwise it's not loaded.
256
+ * [WrappingExecutor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/WrappingExecutor.html)
257
+ A delegating executor which modifies each task before the task is given to
258
+ the target executor it delegates to.
256
259
 
257
260
  ## Supported Ruby versions
258
261
 
259
- * MRI 2.0 and above
260
- * JRuby 9000
261
- * TruffleRuby are supported.
262
- * Any Ruby interpreter that is compliant with Ruby 2.0 or newer.
263
-
264
- Actually we still support mri 1.9.3 and jruby 1.7.27 but we are looking at ways how to drop the support.
265
- Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs is supported.
262
+ * MRI 2.2 and above
263
+ * Latest JRuby 9000
264
+ * Latest TruffleRuby
266
265
 
267
- The legacy support for Rubinius is kept but it is no longer maintained, if you would like to help
266
+ The legacy support for Rubinius is kept for the moment but it is no longer maintained and is liable to be removed. If you would like to help
268
267
  please respond to [#739](https://github.com/ruby-concurrency/concurrent-ruby/issues/739).
269
268
 
270
269
  ## Usage
@@ -350,23 +349,47 @@ and load the appropriate C extensions.
350
349
  No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The
351
350
  best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions.
352
351
 
352
+ ## Building the gem
353
+
354
+ ### Requirements
355
+
356
+ * Recent CRuby
357
+ * JRuby, `rbenv install jruby-9.2.17.0`
358
+ * Set env variable `CONCURRENT_JRUBY_HOME` to point to it, e.g. `/usr/local/opt/rbenv/versions/jruby-9.2.17.0`
359
+ * Install Docker, required for Windows builds
360
+
361
+ ### Publishing the Gem
362
+
363
+ * Update `version.rb`
364
+ * Update the CHANGELOG
365
+ * Update the Yard documentation
366
+ - Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the
367
+ documentation.
368
+ - Run `bundle exec rake yard` to update the master documentation and signpost.
369
+ - Run `bundle exec rake yard:<new-version>` to add or update the documentation of the new version.
370
+ * Commit (and push) the changes.
371
+ * Use `be rake release` to release the gem. It consists
372
+ of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps. It will ask at the end before
373
+ publishing anything. Steps can also be executed individually.
374
+
353
375
  ## Maintainers
354
376
 
355
- * [Petr Chalupa](https://github.com/pitr-ch) (lead maintainer, point-of-contact)
356
- * [Jerry D'Antonio](https://github.com/jdantonio) (creator)
357
- * [Chris Seaton](https://github.com/chrisseaton)
377
+ * [Chris Seaton](https://github.com/chrisseaton) Lead maintainer, point-of-contact.
378
+ * [Benoit Daloze](https://github.com/eregon) — If Chris is not available Benoit can help.
358
379
 
359
380
  ### Special Thanks to
360
381
 
361
- * [Brian Durand](https://github.com/bdurand) for the `ref` gem
362
- * [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems
363
- * [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem
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
364
386
 
365
- and to the past maintainers
387
+ to the past maintainers
366
388
 
367
- * [Michele Della Torre](https://github.com/mighe)
368
- * [Paweł Obrok](https://github.com/obrok)
369
- * [Lucas Allan](https://github.com/lucasallan)
389
+ * [Petr Chalupa](https://github.com/pitr-ch)
390
+ * [Michele Della Torre](https://github.com/mighe)
391
+ * [Paweł Obrok](https://github.com/obrok)
392
+ * [Lucas Allan](https://github.com/lucasallan)
370
393
 
371
394
  and to [Ruby Association](https://www.ruby.or.jp/en/) for sponsoring a project
372
395
  ["Enhancing Ruby’s concurrency tooling"](https://www.ruby.or.jp/en/news/20181106) in 2018.
data/Rakefile CHANGED
@@ -1,14 +1,6 @@
1
- require_relative 'lib/concurrent/version'
2
- require_relative 'lib/concurrent/utility/engine'
3
-
4
- if Concurrent.ruby_version :<, 2, 0, 0
5
- # @!visibility private
6
- module Kernel
7
- def __dir__
8
- File.dirname __FILE__
9
- end
10
- end
11
- end
1
+ require_relative 'lib/concurrent-ruby/concurrent/version'
2
+ require_relative 'lib/concurrent-ruby-edge/concurrent/edge/version'
3
+ require_relative 'lib/concurrent-ruby/concurrent/utility/engine'
12
4
 
13
5
  core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec')
14
6
  ext_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec')
@@ -16,17 +8,19 @@ edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.
16
8
 
17
9
  require 'rake/javaextensiontask'
18
10
 
11
+ ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && !Concurrent.on_jruby?
12
+
19
13
  Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext|
20
14
  ext.ext_dir = 'ext/concurrent-ruby'
21
- ext.lib_dir = 'lib/concurrent'
15
+ ext.lib_dir = 'lib/concurrent-ruby/concurrent'
22
16
  end
23
17
 
24
- unless Concurrent.on_jruby?
18
+ unless Concurrent.on_jruby? || Concurrent.on_truffleruby?
25
19
  require 'rake/extensiontask'
26
20
 
27
21
  Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext|
28
22
  ext.ext_dir = 'ext/concurrent-ruby-ext'
29
- ext.lib_dir = 'lib/concurrent'
23
+ ext.lib_dir = 'lib/concurrent-ruby/concurrent'
30
24
  ext.source_pattern = '*.{c,h}'
31
25
 
32
26
  ext.cross_compile = true
@@ -43,10 +37,12 @@ namespace :repackage do
43
37
  sh 'bundle package'
44
38
 
45
39
  # build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem
46
- Rake::Task['lib/concurrent/concurrent_ruby.jar'].invoke
40
+ Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke
47
41
 
48
42
  # build all gem files
49
- RakeCompilerDock.sh 'bundle install --local && bundle exec rake cross native package --trace'
43
+ %w[x86-mingw32 x64-mingw32].each do |plat|
44
+ RakeCompilerDock.sh "bundle install --local && bundle exec rake native:#{plat} gem --trace", platform: plat
45
+ end
50
46
  end
51
47
  end
52
48
  end
@@ -58,7 +54,7 @@ Gem::PackageTask.new(core_gemspec) {} if core_gemspec
58
54
  Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && !Concurrent.on_jruby?
59
55
  Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec
60
56
 
61
- CLEAN.include('lib/concurrent/2.*', 'lib/concurrent/*.jar')
57
+ CLEAN.include('lib/concurrent-ruby/concurrent/2.*', 'lib/concurrent-ruby/concurrent/*.jar')
62
58
 
63
59
  begin
64
60
  require 'rspec'
@@ -72,8 +68,7 @@ begin
72
68
  options = %w[ --color
73
69
  --backtrace
74
70
  --order defined
75
- --format documentation
76
- --tag ~notravis ]
71
+ --format documentation ]
77
72
  t.rspec_opts = [*options].join(' ')
78
73
  end
79
74
 
@@ -130,7 +125,7 @@ begin
130
125
  task :update_readme do
131
126
  Dir.chdir __dir__ do
132
127
  content = File.read(File.join('README.md')).
133
- gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_|
128
+ gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_|
134
129
  case $1
135
130
  when 'LockFreeLinkedSet'
136
131
  "{Concurrent::Edge::#{$1} #{$1}}"
@@ -160,20 +155,22 @@ begin
160
155
  desc "* of #{name} into subdir #{name}"
161
156
  YARD::Rake::YardocTask.new(name) do |yard|
162
157
  yard.options.push(
163
- '--output-dir', output_dir,
164
- '--main', 'tmp/README.md',
165
- *common_yard_options)
166
- yard.files = ['./lib/**/*.rb',
167
- './lib-edge/**/*.rb',
158
+ '--output-dir', output_dir,
159
+ '--main', 'tmp/README.md',
160
+ *common_yard_options)
161
+ yard.files = ['./lib/concurrent-ruby/**/*.rb',
162
+ './lib/concurrent-ruby-edge/**/*.rb',
168
163
  './ext/concurrent_ruby_ext/**/*.c',
169
164
  '-',
170
165
  'docs-source/thread_pools.md',
171
166
  'docs-source/promises.out.md',
172
167
  'docs-source/medium-example.out.rb',
173
- 'LICENSE.md',
168
+ 'LICENSE.txt',
174
169
  'CHANGELOG.md']
175
170
  end
176
- Rake::Task[name].prerequisites.push removal_name, 'yard:eval_md', 'yard:update_readme'
171
+ Rake::Task[name].prerequisites.push removal_name,
172
+ # 'yard:eval_md',
173
+ 'yard:update_readme'
177
174
  end
178
175
 
179
176
  define_yard_task.call current_yard_version_name
@@ -182,9 +179,9 @@ begin
182
179
  desc "* signpost for versions"
183
180
  YARD::Rake::YardocTask.new(:signpost) do |yard|
184
181
  yard.options.push(
185
- '--output-dir', 'docs',
186
- '--main', 'docs-source/signpost.md',
187
- *common_yard_options)
182
+ '--output-dir', 'docs',
183
+ '--main', 'docs-source/signpost.md',
184
+ *common_yard_options)
188
185
  yard.files = ['no-lib']
189
186
  end
190
187
 
@@ -199,7 +196,7 @@ begin
199
196
  sh 'diff -r docs/ docs-copy/' do |ok, res|
200
197
  unless ok
201
198
  begin
202
- STDOUT.puts 'Command failed. Continue? (y/n)'
199
+ STDOUT.puts "yard:#{name} is not properly generated and committed.", "Continue? (y/n)"
203
200
  input = STDIN.gets.strip.downcase
204
201
  end until %w(y n).include?(input)
205
202
  exit 1 if input == 'n'
@@ -227,15 +224,13 @@ task :release => ['release:checks', 'release:build', 'release:test', 'release:pu
227
224
  namespace :release do
228
225
  # Depends on environment of @pitr-ch
229
226
 
230
- mri_version = '2.5.1'
231
- jruby_version = 'jruby-9.1.17.1'
232
-
233
227
  task :checks => "yard:#{current_yard_version_name}:uptodate" do
234
228
  Dir.chdir(__dir__) do
235
229
  sh 'test -z "$(git status --porcelain)"' do |ok, res|
236
230
  unless ok
237
231
  begin
238
- STDOUT.puts 'Command failed. Continue? (y/n)'
232
+ status = `git status --porcelain`
233
+ STDOUT.puts 'There are local changes that you might want to commit.', status, 'Continue? (y/n)'
239
234
  input = STDIN.gets.strip.downcase
240
235
  end until %w(y n).include?(input)
241
236
  exit 1 if input == 'n'
@@ -243,10 +238,10 @@ namespace :release do
243
238
  end
244
239
  sh 'git fetch'
245
240
  sh 'test $(git show-ref --verify --hash refs/heads/master) = ' +
246
- '$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res|
241
+ '$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res|
247
242
  unless ok
248
243
  begin
249
- STDOUT.puts 'Command failed. Continue? (y/n)'
244
+ STDOUT.puts 'Local master branch is not pushed to origin.', 'Continue? (y/n)'
250
245
  input = STDIN.gets.strip.downcase
251
246
  end until %w(y n).include?(input)
252
247
  exit 1 if input == 'n'
@@ -263,6 +258,12 @@ namespace :release do
263
258
  Dir.chdir(__dir__) do
264
259
  old = ENV['RBENV_VERSION']
265
260
 
261
+ mri_version = `ruby -e 'puts RUBY_VERSION'`.chomp
262
+ jruby_version = File.basename(ENV['CONCURRENT_JRUBY_HOME'])
263
+
264
+ puts "Using following version:"
265
+ pp mri_version: mri_version, jruby_version: jruby_version
266
+
266
267
  ENV['RBENV_VERSION'] = mri_version
267
268
  sh 'rbenv version'
268
269
  sh 'bundle exec rake spec:installed'
@@ -285,19 +286,19 @@ namespace :release do
285
286
 
286
287
  task :ask do
287
288
  begin
288
- STDOUT.puts 'Do you want to publish anything? (y/n)'
289
+ STDOUT.puts 'Do you want to publish anything now? (y/n)'
289
290
  input = STDIN.gets.strip.downcase
290
291
  end until %w(y n).include?(input)
291
292
  exit 1 if input == 'n'
292
293
  begin
293
- STDOUT.puts 'Do you want to publish edge? (y/n)'
294
+ STDOUT.puts 'It will publish `concurrent-ruby`. Do you want to publish `concurrent-ruby-edge`? (y/n)'
294
295
  input = STDIN.gets.strip.downcase
295
296
  end until %w(y n).include?(input)
296
297
  publish_edge = input == 'y'
297
298
  end
298
299
 
299
300
  desc '** tag HEAD with current version and push to github'
300
- task :tag do
301
+ task :tag => :ask do
301
302
  Dir.chdir(__dir__) do
302
303
  sh "git tag v#{Concurrent::VERSION}"
303
304
  sh "git push origin v#{Concurrent::VERSION}"
@@ -307,7 +308,7 @@ namespace :release do
307
308
  end
308
309
 
309
310
  desc '** push all *.gem files to rubygems'
310
- task :rubygems do
311
+ task :rubygems => :ask do
311
312
  Dir.chdir(__dir__) do
312
313
  sh "gem push pkg/concurrent-ruby-#{Concurrent::VERSION}.gem"
313
314
  sh "gem push pkg/concurrent-ruby-edge-#{Concurrent::EDGE_VERSION}.gem" if publish_edge
@@ -319,9 +320,10 @@ namespace :release do
319
320
 
320
321
  desc '** print post release steps'
321
322
  task :post_steps do
322
- puts 'Manually: create a release on GitHub with relevant changelog part'
323
- puts 'Manually: send email same as release with relevant changelog part'
324
- puts 'Manually: tweet'
323
+ # TODO: (petr 05-Jun-2021) automate and renew the process
324
+ # puts 'Manually: create a release on GitHub with relevant changelog part'
325
+ # puts 'Manually: send email same as release with relevant changelog part'
326
+ # puts 'Manually: tweet'
325
327
  end
326
328
  end
327
329
  end
@@ -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, IRubyObject value) throws InterruptedException {
49
- this.semaphore.acquire(rubyFixnumToPositiveInt(value, "permits"));
50
- return context.nil;
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
- return getRuntime().newBoolean(semaphore.tryAcquire(1));
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
- return getRuntime().newBoolean(semaphore.tryAcquire(rubyFixnumToPositiveInt(permits, "permits")));
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
- return getRuntime().newBoolean(
82
- semaphore.tryAcquire(
83
- rubyFixnumToPositiveInt(permits, "permits"),
84
- rubyNumericToLong(timeout, "timeout"),
85
- java.util.concurrent.TimeUnit.SECONDS)
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 value) {
97
- this.semaphore.release(rubyFixnumToPositiveInt(value, "permits"));
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;
@@ -10,13 +10,13 @@ module Concurrent
10
10
  # or writing at a time. This includes iteration methods like `#each`.
11
11
  #
12
12
  # @note `a += b` is **not** a **thread-safe** operation on
13
- # `Concurrent::Array`. It reads array `a`, then it creates new `Concurrent::Array`
14
- # which is concatenation of `a` and `b`, then it writes the concatenation to `a`.
15
- # The read and write are independent operations they do not form a single atomic
16
- # operation therefore when two `+=` operations are executed concurrently updates
17
- # may be lost. Use `#concat` instead.
13
+ # `Concurrent::Array`. It reads array `a`, then it creates new `Concurrent::Array`
14
+ # which is concatenation of `a` and `b`, then it writes the concatenation to `a`.
15
+ # The read and write are independent operations they do not form a single atomic
16
+ # operation therefore when two `+=` operations are executed concurrently updates
17
+ # may be lost. Use `#concat` instead.
18
18
  #
19
- # @see http://ruby-doc.org/core-2.2.0/Array.html Ruby standard library `Array`
19
+ # @see http://ruby-doc.org/core/Array.html Ruby standard library `Array`
20
20
 
21
21
  # @!macro internal_implementation_note
22
22
  ArrayImplementation = case