concurrent-ruby 1.0.3.pre3-java → 1.0.4-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -12
- data/README.md +29 -39
- data/lib/concurrent.rb +3 -3
- data/lib/concurrent/async.rb +2 -2
- data/lib/concurrent/atom.rb +4 -3
- data/lib/concurrent/atomic/abstract_thread_local_var.rb +29 -3
- data/lib/concurrent/atomic/atomic_fixnum.rb +4 -0
- data/lib/concurrent/atomic/atomic_reference.rb +7 -0
- data/lib/concurrent/atomic/count_down_latch.rb +23 -0
- data/lib/concurrent/atomic/cyclic_barrier.rb +23 -3
- data/lib/concurrent/atomic/java_thread_local_var.rb +1 -14
- data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +2 -18
- data/lib/concurrent/atomic/mutex_count_down_latch.rb +3 -3
- data/lib/concurrent/atomic/mutex_semaphore.rb +15 -15
- data/lib/concurrent/atomic/ruby_thread_local_var.rb +31 -42
- data/lib/concurrent/atomic/thread_local_var.rb +7 -5
- data/lib/concurrent/atomic_reference/jruby+truffle.rb +2 -1
- data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +1 -0
- data/lib/concurrent/concern/obligation.rb +1 -0
- data/lib/concurrent/configuration.rb +56 -21
- data/lib/concurrent/errors.rb +24 -1
- data/lib/concurrent/executor/timer_set.rb +11 -0
- data/lib/concurrent/hash.rb +2 -1
- data/lib/concurrent/map.rb +5 -3
- data/lib/concurrent/promise.rb +10 -6
- data/lib/concurrent/synchronization/object.rb +2 -2
- data/lib/concurrent/synchronization/rbx_object.rb +1 -0
- data/lib/concurrent/synchronization/truffle_object.rb +1 -2
- data/lib/concurrent/thread_safe/util.rb +2 -0
- data/lib/concurrent/timer_task.rb +3 -3
- data/lib/concurrent/tvar.rb +1 -1
- data/lib/concurrent/utility/engine.rb +3 -3
- data/lib/concurrent/utility/native_integer.rb +53 -0
- data/lib/concurrent/utility/processor_counter.rb +15 -13
- data/lib/concurrent/version.rb +2 -2
- data/lib/concurrent_ruby_ext.jar +0 -0
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a60be6dec008167a29f42577f31c869f60d2546b
|
4
|
+
data.tar.gz: 37bf185108dd03a4e4f2101f97fc326e2bafa892
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ed4f2c8f8cf8ac4c05a87b6a489f5f89ad0e4d28dbe2ab9e272135557eb006f1b235cc1597b6c6540edf383a63e11f60bd25d0cfa047bc4a4fe9aa3d9ab56d4
|
7
|
+
data.tar.gz: 84c54fb9a82577f71a444c55ebac7893f4192273c567b742bffb44256e8b53a4669e9437c63373180f0e1d09b174be6a6b84435e710ffa057adcd486c3a77c5c
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,39 @@
|
|
1
|
-
## Current Release v1.0.
|
1
|
+
## Current Release v1.0.4 (27 Dec 2016)
|
2
|
+
|
3
|
+
concurrent-ruby:
|
4
|
+
|
5
|
+
* Nothing
|
6
|
+
|
7
|
+
concurrent-ruby-edge:
|
8
|
+
|
9
|
+
* New promises' API renamed, lots of improvements, edge bumped to 0.3.0
|
10
|
+
* **Incompatible** with previous 0.2.3 version
|
11
|
+
* see https://github.com/ruby-concurrency/concurrent-ruby/pull/522
|
12
|
+
|
13
|
+
## Release v1.0.3 (17 Dec 2016)
|
14
|
+
|
15
|
+
* Trigger execution of flattened delayed futures
|
16
|
+
* Avoid forking for processor_count if possible
|
17
|
+
* Semaphore Mutex and JRuby parity
|
18
|
+
* Adds Map#each as alias to Map#each_pair
|
19
|
+
* Fix uninitialized instance variables
|
20
|
+
* Make Fixnum, Bignum merger ready
|
21
|
+
* Allows Promise#then to receive an executor
|
22
|
+
* TimerSet now survives a fork
|
23
|
+
* Reject promise on any exception
|
24
|
+
* Allow ThreadLocalVar to be initialized with a block
|
25
|
+
* Support Alpha with `Concurrent::processor_count`
|
26
|
+
* Fixes format-security error when compiling ruby_193_compatible.h
|
27
|
+
* Concurrent::Atom#swap fixed: reraise the exceptions from block
|
28
|
+
|
29
|
+
## Release v1.0.2 (2 May 2016)
|
2
30
|
|
3
31
|
* Fix bug with `Concurrent::Map` MRI backend `#inspect` method
|
4
32
|
* Fix bug with `Concurrent::Map` MRI backend using `Hash#value?`
|
5
33
|
* Improved documentation and examples
|
6
34
|
* Minor updates to Edge
|
7
35
|
|
8
|
-
|
36
|
+
## Release v1.0.1 (27 February 2016)
|
9
37
|
|
10
38
|
* Fix "uninitialized constant Concurrent::ReentrantReadWriteLock" error.
|
11
39
|
* Better handling of `autoload` vs. `require`.
|
@@ -18,7 +46,7 @@
|
|
18
46
|
* Improved documentation.
|
19
47
|
* Updated README and CONTRIBUTING.
|
20
48
|
|
21
|
-
|
49
|
+
## Release v1.0.0 (13 November 2015)
|
22
50
|
|
23
51
|
* Rename `attr_volatile_with_cas` to `attr_atomic`
|
24
52
|
* Add `clear_each` to `LockFreeStack`
|
@@ -66,7 +94,7 @@
|
|
66
94
|
* Many improved tests
|
67
95
|
* Some internal reorganization
|
68
96
|
|
69
|
-
|
97
|
+
## Release v0.9.1 (09 August 2015)
|
70
98
|
|
71
99
|
* Fixed a Rubiniux bug in synchronization object
|
72
100
|
* Fixed all interpreter warnings (except circular references)
|
@@ -80,7 +108,7 @@
|
|
80
108
|
* `ThreadLocalVar#bind` method is now public
|
81
109
|
* Refactored many tests
|
82
110
|
|
83
|
-
|
111
|
+
## Release v0.9.0 (10 July 2015)
|
84
112
|
|
85
113
|
* Updated `AtomicReference`
|
86
114
|
- `AtomicReference#try_update` now simply returns instead of raising exception
|
@@ -179,14 +207,14 @@
|
|
179
207
|
* Removed brute-force killing of threads in tests
|
180
208
|
* Fixed a thread pool bug when the operating system cannot allocate more threads
|
181
209
|
|
182
|
-
|
210
|
+
## Release v0.8.0 (25 January 2015)
|
183
211
|
|
184
212
|
* C extension for MRI have been extracted into the `concurrent-ruby-ext` companion gem.
|
185
213
|
Please see the README for more detail.
|
186
214
|
* Better variable isolation in `Promise` and `Future` via an `:args` option
|
187
215
|
* Continued to update intermittently failing tests
|
188
216
|
|
189
|
-
|
217
|
+
## Release v0.7.2 (24 January 2015)
|
190
218
|
|
191
219
|
* New `Semaphore` class based on [java.util.concurrent.Semaphore](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html)
|
192
220
|
* New `Promise.all?` and `Promise.any?` class methods
|
@@ -203,7 +231,7 @@
|
|
203
231
|
* Tests now run on new Travis build environment
|
204
232
|
* Multiple documentation updates
|
205
233
|
|
206
|
-
|
234
|
+
## Release v0.7.1 (4 December 2014)
|
207
235
|
|
208
236
|
Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/issues/142) for more information on the next planned release.
|
209
237
|
|
@@ -224,7 +252,7 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
|
|
224
252
|
* Removed confusing warning when not using native extenstions
|
225
253
|
* Improved documentation
|
226
254
|
|
227
|
-
|
255
|
+
## Release v0.7.0 (13 August 2014)
|
228
256
|
|
229
257
|
* Merge the [atomic](https://github.com/ruby-concurrency/atomic) gem
|
230
258
|
- Pure Ruby `MutexAtomic` atomic reference class
|
@@ -257,14 +285,14 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
|
|
257
285
|
* Removed deprecated `Actor` class
|
258
286
|
* Better support for Rubinius
|
259
287
|
|
260
|
-
|
288
|
+
## Release v0.6.1 (14 June 2014)
|
261
289
|
|
262
290
|
* Many improvements to `Concurrent::Actress`
|
263
291
|
* Bug fixes to `Concurrent::RubyThreadPoolExecutor`
|
264
292
|
* Fixed several brittle tests
|
265
293
|
* Moved documentation to http://ruby-concurrency.github.io/concurrent-ruby/frames.html
|
266
294
|
|
267
|
-
|
295
|
+
## Release v0.6.0 (25 May 2014)
|
268
296
|
|
269
297
|
* Added `Concurrent::Observable` to encapsulate our thread safe observer sets
|
270
298
|
* Improvements to new `Channel`
|
@@ -303,7 +331,7 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
|
|
303
331
|
* First implementation of [new, high-performance](https://github.com/ruby-concurrency/concurrent-ruby/pull/49) `Channel`
|
304
332
|
* `Actor` is deprecated in favor of new experimental actor implementation [#73](https://github.com/ruby-concurrency/concurrent-ruby/pull/73). To avoid namespace collision it is living in `Actress` namespace until `Actor` is removed in next release.
|
305
333
|
|
306
|
-
|
334
|
+
## Release v0.5.0
|
307
335
|
|
308
336
|
This is the most significant release of this gem since its inception. This release includes many improvements and optimizations. It also includes several bug fixes. The major areas of focus for this release were:
|
309
337
|
|
data/README.md
CHANGED
@@ -9,39 +9,28 @@
|
|
9
9
|
[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
|
10
10
|
[![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby)
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
<li>Support features that make sense in Ruby</li>
|
35
|
-
<li>Exclude features that don't make sense in Ruby</li>
|
36
|
-
<li>Be small, lean, and loosely coupled</li>
|
37
|
-
</ul>
|
38
|
-
</p>
|
39
|
-
</td>
|
40
|
-
<td align="right" valign="top">
|
41
|
-
<img src="https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/doc/logo/concurrent-ruby-logo-300x300.png"/>
|
42
|
-
</td>
|
43
|
-
</tr>
|
44
|
-
</table>
|
12
|
+
Modern concurrency tools for Ruby. Inspired by
|
13
|
+
[Erlang](http://www.erlang.org/doc/reference_manual/processes.html),
|
14
|
+
[Clojure](http://clojure.org/concurrent_programming),
|
15
|
+
[Scala](http://akka.io/),
|
16
|
+
[Haskell](http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell),
|
17
|
+
[F#](http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx),
|
18
|
+
[C#](http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx),
|
19
|
+
[Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html),
|
20
|
+
and classic concurrency patterns.
|
21
|
+
|
22
|
+
<img src="https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/doc/logo/concurrent-ruby-logo-300x300.png" align="right" style="margin-left: 20px;" />
|
23
|
+
|
24
|
+
The design goals of this gem are:
|
25
|
+
|
26
|
+
* Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why
|
27
|
+
* Remain free of external gem dependencies
|
28
|
+
* Stay true to the spirit of the languages providing inspiration
|
29
|
+
* But implement in a way that makes sense for Ruby
|
30
|
+
* Keep the semantics as idiomatic Ruby as possible
|
31
|
+
* Support features that make sense in Ruby
|
32
|
+
* Exclude features that don't make sense in Ruby
|
33
|
+
* Be small, lean, and loosely coupled
|
45
34
|
|
46
35
|
### Supported Ruby versions
|
47
36
|
|
@@ -127,13 +116,13 @@ These features are under active development and may change frequently. They are
|
|
127
116
|
keep backward compatibility (there may also lack tests and documentation). Semantic versions will
|
128
117
|
be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to `concurrent-ruby` when final.
|
129
118
|
|
130
|
-
* [
|
131
|
-
Implements the Actor Model, where concurrent actors exchange messages.
|
132
|
-
* [New Future Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/FutureShortcuts.html):
|
119
|
+
* [Promises Framework](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promises.html):
|
133
120
|
Unified implementation of futures and promises which combines features of previous `Future`,
|
134
121
|
`Promise`, `IVar`, `Event`, `dataflow`, `Delay`, and `TimerTask` into a single framework. It extensively uses the
|
135
122
|
new synchronization layer to make all the features **non-blocking** and **lock-free**, with the exception of obviously blocking
|
136
123
|
operations like `#wait`, `#value`. It also offers better performance.
|
124
|
+
* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html):
|
125
|
+
Implements the Actor Model, where concurrent actors exchange messages.
|
137
126
|
* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/Channel.html):
|
138
127
|
Communicating Sequential Processes ([CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes)).
|
139
128
|
Functionally equivalent to Go [channels](https://tour.golang.org/concurrency/2) with additional
|
@@ -141,15 +130,16 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
|
|
141
130
|
* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LazyRegister.html)
|
142
131
|
* [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/AtomicMarkableReference.html)
|
143
132
|
* [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeLinkedSet.html)
|
144
|
-
* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/
|
133
|
+
* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LockFreeStack.html)
|
145
134
|
|
146
135
|
#### Statuses:
|
147
136
|
|
148
137
|
*Why are these not in core?*
|
149
138
|
|
139
|
+
- **Promises Framework** - They are being finalized to be able to be moved to core. They'll deprecate old
|
140
|
+
implementation.
|
150
141
|
- **Actor** - Partial documentation and tests; depends on new future/promise framework; stability is good.
|
151
142
|
- **Channel** - Brand new implementation; partial documentation and tests; stability is good.
|
152
|
-
- **Future/Promise Framework** - API changes; partial documentation and tests; stability is good.
|
153
143
|
- **LazyRegister** - Missing documentation and tests.
|
154
144
|
- **AtomicMarkableReference, LockFreeLinkedSet, LockFreeStack** - Need real world battle testing.
|
155
145
|
|
@@ -235,8 +225,8 @@ The best practice is to depend on `concurrent-ruby` and let users to decide if t
|
|
235
225
|
|
236
226
|
## Maintainers
|
237
227
|
|
228
|
+
* [Petr Chalupa](https://github.com/pitr-ch) (lead maintainer)
|
238
229
|
* [Jerry D'Antonio](https://github.com/jdantonio) (creator)
|
239
|
-
* [Petr Chalupa](https://github.com/pitr-ch)
|
240
230
|
* [Michele Della Torre](https://github.com/mighe)
|
241
231
|
* [Chris Seaton](https://github.com/chrisseaton)
|
242
232
|
* [Paweł Obrok](https://github.com/obrok)
|
data/lib/concurrent.rb
CHANGED
@@ -65,13 +65,13 @@ require 'concurrent/options'
|
|
65
65
|
# Object references in Ruby are mutable. This can lead to serious
|
66
66
|
# problems when the {#value} of an object is a mutable reference. Which
|
67
67
|
# is always the case unless the value is a `Fixnum`, `Symbol`, or similar
|
68
|
-
# "
|
68
|
+
# "primitive" data type. Each instance can be configured with a few
|
69
69
|
# options that can help protect the program from potentially dangerous
|
70
|
-
# operations. Each of these options can be optionally set when the
|
70
|
+
# operations. Each of these options can be optionally set when the object
|
71
71
|
# instance is created:
|
72
72
|
#
|
73
73
|
# * `:dup_on_deref` When true the object will call the `#dup` method on
|
74
|
-
# the `value` object every time the `#value`
|
74
|
+
# the `value` object every time the `#value` method is called
|
75
75
|
# (default: false)
|
76
76
|
# * `:freeze_on_deref` When true the object will call the `#freeze`
|
77
77
|
# method on the `value` object every time the `#value` method is called
|
data/lib/concurrent/async.rb
CHANGED
@@ -34,7 +34,7 @@ module Concurrent
|
|
34
34
|
# When an Erlang module implements the `gen_server` behavior it becomes
|
35
35
|
# inherently asynchronous. The `start` or `start_link` function spawns a
|
36
36
|
# process (similar to a thread but much more lightweight and efficient) and
|
37
|
-
#
|
37
|
+
# returns the ID of the process. Using the process ID, other processes can
|
38
38
|
# send messages to the `gen_server` via the `cast` and `call` methods. Unlike
|
39
39
|
# Erlang's `gen_server`, however, `Async` classes do not support linking or
|
40
40
|
# supervision trees.
|
@@ -142,7 +142,7 @@ module Concurrent
|
|
142
142
|
# practice is to read the instance variable into a local variable at the start
|
143
143
|
# of the method then update the instance variable at the *end* of the method.
|
144
144
|
# This way, should an exception be raised during method execution the internal
|
145
|
-
# state of the
|
145
|
+
# state of the object will not have been changed.
|
146
146
|
#
|
147
147
|
# ### Reader Attributes
|
148
148
|
#
|
data/lib/concurrent/atom.rb
CHANGED
@@ -19,7 +19,7 @@ require 'concurrent/synchronization'
|
|
19
19
|
# the value will undergo frequent reads but only occasional, though complex,
|
20
20
|
# updates. Suitable when the result of an update must be known immediately.
|
21
21
|
# * *{Concurrent::AtomicReference}:* A simple object reference that can be
|
22
|
-
# atomically. Updates are synchronous but fast.
|
22
|
+
# atomically. Updates are synchronous but fast. Best used when updates a
|
23
23
|
# simple set operations. Not suitable when updates are complex.
|
24
24
|
# {Concurrent::AtomicBoolean} and {Concurrent::AtomicFixnum} are similar
|
25
25
|
# but optimized for the given data type.
|
@@ -37,6 +37,7 @@ require 'concurrent/synchronization'
|
|
37
37
|
# *coordinated*, *synchronous*, change of *many* stated. Used when multiple
|
38
38
|
# value must change together, in an all-or-nothing transaction.
|
39
39
|
|
40
|
+
|
40
41
|
module Concurrent
|
41
42
|
|
42
43
|
# Atoms provide a way to manage shared, synchronous, independent state.
|
@@ -61,7 +62,7 @@ module Concurrent
|
|
61
62
|
# set + [set[-2..-1].reduce{|sum,x| sum + x }]
|
62
63
|
# end
|
63
64
|
#
|
64
|
-
# # create an atom with
|
65
|
+
# # create an atom with an initial value
|
65
66
|
# atom = Concurrent::Atom.new(next_fibonacci)
|
66
67
|
#
|
67
68
|
# # send a few update requests
|
@@ -144,7 +145,7 @@ module Concurrent
|
|
144
145
|
# @param [Object] args Zero or more arguments passed to the block.
|
145
146
|
#
|
146
147
|
# @yield [value, args] Calculates a new value for the atom based on the
|
147
|
-
# current value and any supplied
|
148
|
+
# current value and any supplied arguments.
|
148
149
|
# @yieldparam value [Object] The current value of the atom.
|
149
150
|
# @yieldparam args [Object] All arguments passed to the function, in order.
|
150
151
|
# @yieldreturn [Object] The intended new value of the atom.
|
@@ -8,8 +8,17 @@ module Concurrent
|
|
8
8
|
class AbstractThreadLocalVar
|
9
9
|
|
10
10
|
# @!macro thread_local_var_method_initialize
|
11
|
-
def initialize(default = nil)
|
12
|
-
|
11
|
+
def initialize(default = nil, &default_block)
|
12
|
+
if default && block_given?
|
13
|
+
raise ArgumentError, "Cannot use both value and block as default value"
|
14
|
+
end
|
15
|
+
|
16
|
+
if block_given?
|
17
|
+
@default_block = default_block
|
18
|
+
else
|
19
|
+
@default = default
|
20
|
+
end
|
21
|
+
|
13
22
|
allocate_storage
|
14
23
|
end
|
15
24
|
|
@@ -25,7 +34,15 @@ module Concurrent
|
|
25
34
|
|
26
35
|
# @!macro thread_local_var_method_bind
|
27
36
|
def bind(value, &block)
|
28
|
-
|
37
|
+
if block_given?
|
38
|
+
old_value = self.value
|
39
|
+
begin
|
40
|
+
self.value = value
|
41
|
+
yield
|
42
|
+
ensure
|
43
|
+
self.value = old_value
|
44
|
+
end
|
45
|
+
end
|
29
46
|
end
|
30
47
|
|
31
48
|
protected
|
@@ -34,5 +51,14 @@ module Concurrent
|
|
34
51
|
def allocate_storage
|
35
52
|
raise NotImplementedError
|
36
53
|
end
|
54
|
+
|
55
|
+
# @!visibility private
|
56
|
+
def default
|
57
|
+
if @default_block
|
58
|
+
self.value = @default_block.call
|
59
|
+
else
|
60
|
+
@default
|
61
|
+
end
|
62
|
+
end
|
37
63
|
end
|
38
64
|
end
|
@@ -129,5 +129,9 @@ module Concurrent
|
|
129
129
|
#
|
130
130
|
# @!macro atomic_fixnum_public_api
|
131
131
|
class AtomicFixnum < AtomicFixnumImplementation
|
132
|
+
# @return [String] Short string representation.
|
133
|
+
def to_s
|
134
|
+
format '<#%s:0x%x value:%s>', self.class, object_id << 1, get
|
135
|
+
end
|
132
136
|
end
|
133
137
|
end
|
@@ -40,3 +40,10 @@ else
|
|
40
40
|
class Concurrent::AtomicReference < Concurrent::MutexAtomicReference
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
class Concurrent::AtomicReference
|
45
|
+
# @return [String] Short string representation.
|
46
|
+
def to_s
|
47
|
+
format '<#%s:0x%x value:%s>', self.class, object_id << 1, get
|
48
|
+
end
|
49
|
+
end
|
@@ -72,6 +72,29 @@ module Concurrent
|
|
72
72
|
# with its work. A `CountDownLatch` can be used only once. Its value cannot be reset.
|
73
73
|
#
|
74
74
|
# @!macro count_down_latch_public_api
|
75
|
+
# @example Waiter and Decrementer
|
76
|
+
# latch = Concurrent::CountDownLatch.new(3)
|
77
|
+
#
|
78
|
+
# waiter = Thread.new do
|
79
|
+
# latch.wait()
|
80
|
+
# puts ("Waiter released")
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# decrementer = Thread.new do
|
84
|
+
# sleep(1)
|
85
|
+
# latch.count_down
|
86
|
+
# puts latch.count
|
87
|
+
#
|
88
|
+
# sleep(1)
|
89
|
+
# latch.count_down
|
90
|
+
# puts latch.count
|
91
|
+
#
|
92
|
+
# sleep(1)
|
93
|
+
# latch.count_down
|
94
|
+
# puts latch.count
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# [waiter, decrementer].each(&:join)
|
75
98
|
class CountDownLatch < CountDownLatchImplementation
|
76
99
|
end
|
77
100
|
end
|
@@ -1,9 +1,29 @@
|
|
1
1
|
require 'concurrent/synchronization'
|
2
|
+
require 'concurrent/utility/native_integer'
|
2
3
|
|
3
4
|
module Concurrent
|
4
5
|
|
5
6
|
# A synchronization aid that allows a set of threads to all wait for each
|
6
7
|
# other to reach a common barrier point.
|
8
|
+
# @example
|
9
|
+
# barrier = Concurrent::CyclicBarrier.new(3)
|
10
|
+
# jobs = Array.new(3) { |i| -> { sleep i; p done: i } }
|
11
|
+
# process = -> (i) do
|
12
|
+
# # waiting to start at the same time
|
13
|
+
# barrier.wait
|
14
|
+
# # execute job
|
15
|
+
# jobs[i].call
|
16
|
+
# # wait for others to finish
|
17
|
+
# barrier.wait
|
18
|
+
# end
|
19
|
+
# threads = 2.times.map do |i|
|
20
|
+
# Thread.new(i, &process)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # use main as well
|
24
|
+
# process.call 2
|
25
|
+
#
|
26
|
+
# # here we can be sure that all jobs are processed
|
7
27
|
class CyclicBarrier < Synchronization::LockableObject
|
8
28
|
|
9
29
|
# @!visibility private
|
@@ -18,9 +38,9 @@ module Concurrent
|
|
18
38
|
#
|
19
39
|
# @raise [ArgumentError] if `parties` is not an integer or is less than zero
|
20
40
|
def initialize(parties, &block)
|
21
|
-
|
22
|
-
|
23
|
-
|
41
|
+
Utility::NativeInteger.ensure_integer_and_bounds parties
|
42
|
+
Utility::NativeInteger.ensure_positive_and_no_zero parties
|
43
|
+
|
24
44
|
super(&nil)
|
25
45
|
synchronize { ns_initialize parties, &block }
|
26
46
|
end
|