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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -12
  3. data/README.md +29 -39
  4. data/lib/concurrent.rb +3 -3
  5. data/lib/concurrent/async.rb +2 -2
  6. data/lib/concurrent/atom.rb +4 -3
  7. data/lib/concurrent/atomic/abstract_thread_local_var.rb +29 -3
  8. data/lib/concurrent/atomic/atomic_fixnum.rb +4 -0
  9. data/lib/concurrent/atomic/atomic_reference.rb +7 -0
  10. data/lib/concurrent/atomic/count_down_latch.rb +23 -0
  11. data/lib/concurrent/atomic/cyclic_barrier.rb +23 -3
  12. data/lib/concurrent/atomic/java_thread_local_var.rb +1 -14
  13. data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +2 -18
  14. data/lib/concurrent/atomic/mutex_count_down_latch.rb +3 -3
  15. data/lib/concurrent/atomic/mutex_semaphore.rb +15 -15
  16. data/lib/concurrent/atomic/ruby_thread_local_var.rb +31 -42
  17. data/lib/concurrent/atomic/thread_local_var.rb +7 -5
  18. data/lib/concurrent/atomic_reference/jruby+truffle.rb +2 -1
  19. data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +1 -0
  20. data/lib/concurrent/concern/obligation.rb +1 -0
  21. data/lib/concurrent/configuration.rb +56 -21
  22. data/lib/concurrent/errors.rb +24 -1
  23. data/lib/concurrent/executor/timer_set.rb +11 -0
  24. data/lib/concurrent/hash.rb +2 -1
  25. data/lib/concurrent/map.rb +5 -3
  26. data/lib/concurrent/promise.rb +10 -6
  27. data/lib/concurrent/synchronization/object.rb +2 -2
  28. data/lib/concurrent/synchronization/rbx_object.rb +1 -0
  29. data/lib/concurrent/synchronization/truffle_object.rb +1 -2
  30. data/lib/concurrent/thread_safe/util.rb +2 -0
  31. data/lib/concurrent/timer_task.rb +3 -3
  32. data/lib/concurrent/tvar.rb +1 -1
  33. data/lib/concurrent/utility/engine.rb +3 -3
  34. data/lib/concurrent/utility/native_integer.rb +53 -0
  35. data/lib/concurrent/utility/processor_counter.rb +15 -13
  36. data/lib/concurrent/version.rb +2 -2
  37. data/lib/concurrent_ruby_ext.jar +0 -0
  38. metadata +8 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d570e81d15c9f558cd3ba2af24a62a70eb6faf93
4
- data.tar.gz: bdfd64699ab036b7f84ac1132c413bcab6394bdf
3
+ metadata.gz: a60be6dec008167a29f42577f31c869f60d2546b
4
+ data.tar.gz: 37bf185108dd03a4e4f2101f97fc326e2bafa892
5
5
  SHA512:
6
- metadata.gz: 7b424a412239a0b44c1896282a744c2ff37e2e644630ee7a94a8ff04b596f3aac35ee5e853742a6e3f27150a11d784a945dc18ffce528355b756a801a0976766
7
- data.tar.gz: 1817739fb6012cd8713b93d0010dbc590327d38c7b34a051e5a0076b9a2d38e5a805c00addbe287fb1f1a57b851a333e76710c256ebf1db0380c3119d66dfaa6
6
+ metadata.gz: 3ed4f2c8f8cf8ac4c05a87b6a489f5f89ad0e4d28dbe2ab9e272135557eb006f1b235cc1597b6c6540edf383a63e11f60bd25d0cfa047bc4a4fe9aa3d9ab56d4
7
+ data.tar.gz: 84c54fb9a82577f71a444c55ebac7893f4192273c567b742bffb44256e8b53a4669e9437c63373180f0e1d09b174be6a6b84435e710ffa057adcd486c3a77c5c
data/CHANGELOG.md CHANGED
@@ -1,11 +1,39 @@
1
- ## Current Release v1.0.2 (2 May 2016)
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
- ### Release v1.0.1 (27 February 2016)
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
- ### Release v1.0.0 (13 November 2015)
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
- ### Release v0.9.1 (09 August 2015)
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
- ### Release v0.9.0 (10 July 2015)
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
- ### Release v0.8.0 (25 January 2015)
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
- ### Release v0.7.2 (24 January 2015)
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
- ### Release v0.7.1 (4 December 2014)
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
- ### Release v0.7.0 (13 August 2014)
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
- ### Release v0.6.1 (14 June 2014)
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
- ### Release v0.6.0 (25 May 2014)
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
- ### Release v0.5.0
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
- <table>
13
- <tr>
14
- <td align="left" valign="top">
15
- <p>
16
- Modern concurrency tools for Ruby. Inspired by
17
- <a href="http://www.erlang.org/doc/reference_manual/processes.html">Erlang</a>,
18
- <a href="http://clojure.org/concurrent_programming">Clojure</a>,
19
- <a href="http://akka.io/">Scala</a>,
20
- <a href="http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell">Haskell</a>,
21
- <a href="http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx">F#</a>,
22
- <a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx">C#</a>,
23
- <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html">Java</a>,
24
- and classic concurrency patterns.
25
- </p>
26
- <p>
27
- The design goals of this gem are:
28
- <ul>
29
- <li>Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why</li>
30
- <li>Remain free of external gem dependencies</li>
31
- <li>Stay true to the spirit of the languages providing inspiration</li>
32
- <li>But implement in a way that makes sense for Ruby</li>
33
- <li>Keep the semantics as idiomatic Ruby as possible</li>
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
- * [Actor](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Actor.html):
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/Edge/LockFreeStack.html)
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
- # "primative" data type. Each instance can be configured with a few
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 oject
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` methid is called
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
@@ -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
- # reurns the ID of the process. Using the process ID, other processes can
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 boject will not have been changed.
145
+ # state of the object will not have been changed.
146
146
  #
147
147
  # ### Reader Attributes
148
148
  #
@@ -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. Bast used when updates a
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 aninitial value
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 agruments.
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
- @default = default
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
- raise NotImplementedError
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
- if !parties.is_a?(Fixnum) || parties < 1
22
- raise ArgumentError.new('count must be in integer greater than or equal zero')
23
- end
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