concurrent-ruby-ext 1.0.5-x86-mingw32 → 1.1.0.pre1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +45 -1
- data/{LICENSE.txt → LICENSE.md} +2 -0
- data/README.md +203 -105
- data/ext/{concurrent → concurrent-ruby-ext}/atomic_boolean.c +2 -3
- data/ext/{concurrent → concurrent-ruby-ext}/atomic_boolean.h +0 -0
- data/ext/{concurrent → concurrent-ruby-ext}/atomic_fixnum.c +0 -0
- data/ext/{concurrent → concurrent-ruby-ext}/atomic_fixnum.h +0 -0
- data/ext/{concurrent → concurrent-ruby-ext}/atomic_reference.c +32 -14
- data/ext/{concurrent → concurrent-ruby-ext}/atomic_reference.h +0 -0
- data/ext/concurrent-ruby-ext/extconf.rb +22 -0
- data/ext/{concurrent → concurrent-ruby-ext}/rb_concurrent.c +1 -1
- data/ext/{concurrent → concurrent-ruby-ext}/ruby_193_compatible.h +0 -0
- data/lib/concurrent/2.0/concurrent_ruby_ext.so +0 -0
- data/lib/concurrent/2.1/concurrent_ruby_ext.so +0 -0
- data/lib/concurrent/2.2/concurrent_ruby_ext.so +0 -0
- data/lib/concurrent/2.3/concurrent_ruby_ext.so +0 -0
- data/lib/concurrent/2.4/concurrent_ruby_ext.so +0 -0
- data/lib/concurrent/2.5/concurrent_ruby_ext.so +0 -0
- metadata +28 -27
- data/ext/concurrent/extconf.rb +0 -58
- data/lib/concurrent/1.9/extension.so +0 -0
- data/lib/concurrent/2.0/extension.so +0 -0
- data/lib/concurrent/2.1/extension.so +0 -0
- data/lib/concurrent/2.2/extension.so +0 -0
- data/lib/concurrent/atomic_reference/concurrent_update_error.rb +0 -8
- data/lib/concurrent/atomic_reference/direct_update.rb +0 -81
- data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 72d0162f39f4f866b2264d7faff867084011facebbe96474755e9e5eb0230da9
|
4
|
+
data.tar.gz: 277cc283fbb48e6c5257644f062147ae8393d2aceda020466611fddd12e0ceeb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 571309ea27c0c62013bfa4e708c0e4f0b2642c67f85d6e039d8f92dcd140f5bab0aa564e1fa5d7b21ac58f1704f046ff86340a579b3f7ec469264fdea526c6e6
|
7
|
+
data.tar.gz: f1957aeec7a4dec181cf563a4e40e7fae5b342b62304262f94cd84c78273bc7a4f0d538370b79da720da3f098bed5b35e67eb8c66865e3f0e218e759f953aa1c
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,52 @@
|
|
1
|
-
##
|
1
|
+
## Current
|
2
|
+
|
3
|
+
concurrent-ruby:
|
4
|
+
|
5
|
+
* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/1.1.0/Concurrent/Promises.html)
|
6
|
+
are moved from `concurrent-ruby-edge` to `concurrent-ruby`
|
7
|
+
* Add support for TruffleRuby
|
8
|
+
* (#734) Fix Array/Hash/Set construction broken on TruffleRuby
|
9
|
+
* AtomicReference fixed
|
10
|
+
* CI stabilization
|
11
|
+
* remove sharp dependency edge -> core
|
12
|
+
* remove warnings
|
13
|
+
* documentation updates
|
14
|
+
* Exchanger is no longer documented as edge since it was already available in
|
15
|
+
`concurrent-ruby`
|
16
|
+
* (#644) Fix Map#each and #each_pair not returning enumerator outside of MRI
|
17
|
+
* (#659) Edge promises fail during error handling
|
18
|
+
* (#741) Raise on recursive Delay#value call
|
19
|
+
* (#727) #717 fix global IO executor on JRuby
|
20
|
+
* (#740) Drop support for CRuby 1.9, JRuby 1.7, Rubinius.
|
21
|
+
* (#737) Move AtomicMarkableReference out of Edge
|
22
|
+
* (#708) Prefer platform specific memory barriers
|
23
|
+
* (#735) Fix wrong expected exception in channel spec assertion
|
24
|
+
* (#729) Allow executor option in `Promise#then`
|
25
|
+
* (#725) fix timeout check to use timeout_interval
|
26
|
+
* (#719) update engine detection
|
27
|
+
* (#660) Add specs for Promise#zip/Promise.zip ordering
|
28
|
+
* (#654) Promise.zip execution changes
|
29
|
+
* (#666) Add thread safe set implementation
|
30
|
+
* (#651) #699 #to_s, #inspect should not output negative object IDs.
|
31
|
+
* (#685) Avoid RSpec warnings about raise_error
|
32
|
+
* (#680) Avoid RSpec monkey patching, persist spec results locally, use RSpec
|
33
|
+
v3.7.0
|
34
|
+
* (#665) Initialize the monitor for new subarrays on Rubinius
|
35
|
+
* (#661) Fix error handling in edge promises
|
36
|
+
|
37
|
+
concurrent-ruby-edge:
|
38
|
+
|
39
|
+
* (#659) Edge promises fail during error handling
|
40
|
+
* Edge files clearly separated in `lib-edge`
|
41
|
+
* added ReInclude
|
42
|
+
|
43
|
+
## Release v1.0.5, edge v0.3.1 (26 Feb 2017)
|
2
44
|
|
3
45
|
concurrent-ruby:
|
4
46
|
|
5
47
|
* Documentation for Event and Semaphore
|
6
48
|
* Use Unsafe#fullFence and #loadFence directly since the shortcuts were removed in JRuby
|
49
|
+
* Do not depend on org.jruby.util.unsafe.UnsafeHolder
|
7
50
|
|
8
51
|
concurrent-ruby-edge:
|
9
52
|
|
@@ -11,6 +54,7 @@ concurrent-ruby-edge:
|
|
11
54
|
* (#624) Delayed promises did not interact correctly with flatting
|
12
55
|
* Fix arguments yielded by callback methods
|
13
56
|
* Overridable default executor in promises factory methods
|
57
|
+
* Asking actor to terminate will always resolve to `true`
|
14
58
|
|
15
59
|
## Release v1.0.4, edge v0.3.0 (27 Dec 2016)
|
16
60
|
|
data/{LICENSE.txt → LICENSE.md}
RENAMED
@@ -1,3 +1,4 @@
|
|
1
|
+
```
|
1
2
|
Copyright (c) Jerry D'Antonio -- released under the MIT license.
|
2
3
|
|
3
4
|
http://www.opensource.org/licenses/mit-license.php
|
@@ -19,3 +20,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
20
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
21
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
22
|
THE SOFTWARE.
|
23
|
+
```
|
data/README.md
CHANGED
@@ -3,9 +3,6 @@
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby)
|
4
4
|
[![Build Status](https://travis-ci.org/ruby-concurrency/concurrent-ruby.svg?branch=master)](https://travis-ci.org/ruby-concurrency/concurrent-ruby)
|
5
5
|
[![Build status](https://ci.appveyor.com/api/projects/status/iq8aboyuu3etad4w?svg=true)](https://ci.appveyor.com/project/rubyconcurrency/concurrent-ruby)
|
6
|
-
[![Code Climate](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby.svg)](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby)
|
7
|
-
[![Inline docs](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby.svg)](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby)
|
8
|
-
[![Dependency Status](https://gemnasium.com/ruby-concurrency/concurrent-ruby.svg)](https://gemnasium.com/ruby-concurrency/concurrent-ruby)
|
9
6
|
[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
|
10
7
|
[![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby)
|
11
8
|
|
@@ -19,129 +16,223 @@ Modern concurrency tools for Ruby. Inspired by
|
|
19
16
|
[Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html),
|
20
17
|
and classic concurrency patterns.
|
21
18
|
|
22
|
-
<img src="https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/
|
19
|
+
<img src="https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/docs-source/logo/concurrent-ruby-logo-300x300.png" align="right" style="margin-left: 20px;" />
|
23
20
|
|
24
21
|
The design goals of this gem are:
|
25
22
|
|
26
|
-
*
|
27
|
-
|
28
|
-
*
|
29
|
-
*
|
30
|
-
*
|
31
|
-
*
|
32
|
-
*
|
33
|
-
*
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
23
|
+
* Be an 'unopinionated' toolbox that provides useful utilities without debating which is better
|
24
|
+
or why
|
25
|
+
* Remain free of external gem dependencies
|
26
|
+
* Stay true to the spirit of the languages providing inspiration
|
27
|
+
* But implement in a way that makes sense for Ruby
|
28
|
+
* Keep the semantics as idiomatic Ruby as possible
|
29
|
+
* Support features that make sense in Ruby
|
30
|
+
* Exclude features that don't make sense in Ruby
|
31
|
+
* Be small, lean, and loosely coupled
|
32
|
+
* Thread-safety
|
33
|
+
* Backward compatibility
|
34
|
+
|
35
|
+
## Contributing
|
36
|
+
|
37
|
+
**This gem depends on
|
38
|
+
[contributions](https://github.com/ruby-concurrency/concurrent-ruby/graphs/contributors) and we
|
39
|
+
appreciate your help. Would you like to contribute? Great! Have a look at
|
40
|
+
[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.
|
40
41
|
|
41
42
|
## Thread Safety
|
42
43
|
|
43
|
-
*Concurrent Ruby makes the strongest thread safety guarantees of any Ruby concurrency
|
44
|
+
*Concurrent Ruby makes one of the strongest thread safety guarantees of any Ruby concurrency
|
45
|
+
library, providing consistent behavior and guarantees on all three of the main Ruby interpreters
|
46
|
+
(MRI/CRuby, JRuby, and Rubinius).*
|
47
|
+
|
48
|
+
Every abstraction in this library is thread safe. Specific thread safety guarantees are documented
|
49
|
+
with each abstraction.
|
44
50
|
|
45
|
-
|
51
|
+
It is critical to remember, however, that Ruby is a language of mutable references. *No*
|
52
|
+
concurrency library for Ruby can ever prevent the user from making thread safety mistakes (such as
|
53
|
+
sharing a mutable object between threads and modifying it on both threads) or from creating
|
54
|
+
deadlocks through incorrect use of locks. All the library can do is provide safe abstractions which
|
55
|
+
encourage safe practices. Concurrent Ruby provides more safe concurrency abstractions than any
|
56
|
+
other Ruby library, many of which support the mantra of
|
57
|
+
["Do not communicate by sharing memory; instead, share memory by communicating"](https://blog.golang.org/share-memory-by-communicating).
|
58
|
+
Concurrent Ruby is also the only Ruby library which provides a full suite of thread safe and
|
59
|
+
immutable variable types and data structures.
|
46
60
|
|
47
|
-
|
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 three of the main Ruby interpreters
|
63
|
+
(MRI/CRuby, JRuby, Rubinius, TruffleRuby).
|
48
64
|
|
49
65
|
## Features & Documentation
|
50
66
|
|
51
|
-
The primary site for documentation is the automatically generated
|
67
|
+
**The primary site for documentation is the automatically generated
|
68
|
+
[API documentation](http://ruby-concurrency.github.io/concurrent-ruby/index.html) which is up to
|
69
|
+
date with latest release.** This readme matches the master so may contain new stuff not yet
|
70
|
+
released.
|
71
|
+
|
72
|
+
We also have a [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby).
|
73
|
+
|
74
|
+
### Versioning
|
75
|
+
|
76
|
+
* `concurrent-ruby` uses [Semantic Versioning](http://semver.org/)
|
77
|
+
* `concurrent-ruby-ext` has always same version as `concurrent-ruby`
|
78
|
+
* `concurrent-ruby-edge` will always be 0.y.z therefore following
|
79
|
+
[point 4](http://semver.org/#spec-item-4) applies *"Major version zero
|
80
|
+
(0.y.z) is for initial development. Anything may change at any time. The
|
81
|
+
public API should not be considered stable."* However we additionally use
|
82
|
+
following rules:
|
83
|
+
* Minor version increment means incompatible changes were made
|
84
|
+
* Patch version increment means only compatible changes were made
|
52
85
|
|
53
|
-
We also have a [mailing list](http://groups.google.com/group/concurrent-ruby) and [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby).
|
54
86
|
|
55
87
|
#### General-purpose Concurrency Abstractions
|
56
88
|
|
57
|
-
*
|
58
|
-
|
59
|
-
|
60
|
-
*
|
61
|
-
|
62
|
-
*
|
89
|
+
* [Async](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Async.html):
|
90
|
+
A mixin module that provides simple asynchronous behavior to a class. Loosely based on Erlang's
|
91
|
+
[gen_server](http://www.erlang.org/doc/man/gen_server.html).
|
92
|
+
* [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ScheduledTask.html):
|
93
|
+
Like a Future scheduled for a specific future time.
|
94
|
+
* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TimerTask.html):
|
95
|
+
A Thread that periodically wakes up to perform work at regular intervals.
|
96
|
+
* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html):
|
97
|
+
Unified implementation of futures and promises which combines features of previous `Future`,
|
98
|
+
`Promise`, `IVar`, `Event`, `dataflow`, `Delay`, and (partially) `TimerTask` into a single
|
99
|
+
framework. It extensively uses the new synchronization layer to make all the features
|
100
|
+
**non-blocking** and **lock-free**, with the exception of obviously blocking operations like
|
101
|
+
`#wait`, `#value`. It also offers better performance.
|
63
102
|
|
64
103
|
#### Thread-safe Value Objects, Structures, and Collections
|
65
104
|
|
66
105
|
Collection classes that were originally part of the (deprecated) `thread_safe` gem:
|
67
106
|
|
68
|
-
*
|
69
|
-
|
70
|
-
*
|
71
|
-
|
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).
|
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).
|
111
|
+
* [Set](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Set.html) A thread-safe
|
112
|
+
subclass of Ruby's standard [Set](http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html).
|
113
|
+
* [Map](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Map.html) A hash-like object
|
114
|
+
that should have much better performance characteristics, especially under high concurrency,
|
115
|
+
than `Concurrent::Hash`.
|
116
|
+
* [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Tuple.html) A fixed size
|
117
|
+
array with volatile (synchronized, thread safe) getters/setters.
|
72
118
|
|
73
119
|
Value objects inspired by other languages:
|
74
120
|
|
75
|
-
*
|
76
|
-
|
77
|
-
|
121
|
+
* [Maybe](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Maybe.html) A thread-safe,
|
122
|
+
immutable object representing an optional value, based on
|
123
|
+
[Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html).
|
78
124
|
|
79
125
|
Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
|
80
126
|
|
81
|
-
*
|
82
|
-
|
83
|
-
*
|
127
|
+
* [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ImmutableStruct.html)
|
128
|
+
Immutable struct where values are set at construction and cannot be changed later.
|
129
|
+
* [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MutableStruct.html)
|
130
|
+
Synchronized, mutable struct where values can be safely changed at any time.
|
131
|
+
* [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/SettableStruct.html)
|
132
|
+
Synchronized, write-once struct where values can be set at most once, either at construction
|
133
|
+
or any time thereafter.
|
84
134
|
|
85
135
|
Thread-safe variables:
|
86
136
|
|
87
|
-
*
|
88
|
-
|
89
|
-
|
90
|
-
*
|
91
|
-
|
92
|
-
|
93
|
-
*
|
94
|
-
|
95
|
-
*
|
137
|
+
* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Agent.html): A way to
|
138
|
+
manage shared, mutable, *asynchronous*, independent state. Based on Clojure's
|
139
|
+
[Agent](http://clojure.org/agents).
|
140
|
+
* [Atom](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Atom.html): A way to manage
|
141
|
+
shared, mutable, *synchronous*, independent state. Based on Clojure's
|
142
|
+
[Atom](http://clojure.org/atoms).
|
143
|
+
* [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicBoolean.html)
|
144
|
+
A boolean value that can be updated atomically.
|
145
|
+
* [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicFixnum.html)
|
146
|
+
A numeric value that can be updated atomically.
|
147
|
+
* [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MutexAtomic.html)
|
148
|
+
An object reference that may be updated atomically.
|
149
|
+
* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Exchanger.html)
|
150
|
+
A synchronization point at which threads can pair and swap elements within pairs. Based on
|
151
|
+
Java's [Exchanger](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html).
|
152
|
+
* [MVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MVar.html) A synchronized
|
153
|
+
single element container. Based on Haskell's
|
154
|
+
[MVar](https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Concurrent-MVar.html) and
|
155
|
+
Scala's [MVar](http://docs.typelevel.org/api/scalaz/nightly/index.html#scalaz.concurrent.MVar$).
|
156
|
+
* [ThreadLocalVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ThreadLocalVar.html)
|
157
|
+
A variable where the value is different for each thread.
|
158
|
+
* [TVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TVar.html) A transactional
|
159
|
+
variable implementing software transactional memory (STM). Based on Clojure's
|
160
|
+
[Ref](http://clojure.org/refs).
|
96
161
|
|
97
162
|
#### Java-inspired ThreadPools and Other Executors
|
98
163
|
|
99
|
-
*
|
164
|
+
* See the [thread pool](http://ruby-concurrency.github.io/concurrent-ruby/master/file.thread_pools.html)
|
165
|
+
overview, which also contains a list of other Executors available.
|
100
166
|
|
101
167
|
#### Thread Synchronization Classes and Algorithms
|
102
168
|
|
103
|
-
*
|
104
|
-
|
105
|
-
*
|
106
|
-
|
107
|
-
*
|
108
|
-
|
109
|
-
*
|
110
|
-
|
169
|
+
* [CountDownLatch](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CountDownLatch.html)
|
170
|
+
A synchronization object that allows one thread to wait on multiple other threads.
|
171
|
+
* [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CyclicBarrier.html)
|
172
|
+
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
|
173
|
+
* [Event](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Event.html) Old school
|
174
|
+
kernel-style event.
|
175
|
+
* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReadWriteLock.html)
|
176
|
+
A lock that supports multiple readers but only one writer.
|
177
|
+
* [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReentrantReadWriteLock.html)
|
178
|
+
A read/write lock with reentrant and upgrade features.
|
179
|
+
* [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Semaphore.html)
|
180
|
+
A counting-based locking mechanism that uses permits.
|
181
|
+
* [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Atomic/AtomicMarkableReference.html)
|
182
|
+
|
183
|
+
#### Deprecated
|
184
|
+
|
185
|
+
Deprecated features are still available and bugs are being fixed, but new features will not be added.
|
186
|
+
|
187
|
+
* ~~[Future](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Future.html):
|
188
|
+
An asynchronous operation that produces a value.~~ Replaced by
|
189
|
+
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
190
|
+
* ~~[.dataflow](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent.html#dataflow-class_method):
|
191
|
+
Built on Futures, Dataflow allows you to create a task that will be scheduled when all of
|
192
|
+
its data dependencies are available.~~ Replaced by
|
193
|
+
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
194
|
+
* ~~[Promise](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promise.html): Similar
|
195
|
+
to Futures, with more features.~~ Replaced by
|
196
|
+
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
197
|
+
* ~~[Delay](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Delay.html) Lazy evaluation
|
198
|
+
of a block yielding an immutable result. Based on Clojure's
|
199
|
+
[delay](https://clojuredocs.org/clojure.core/delay).~~ Replaced by
|
200
|
+
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
201
|
+
* ~~[IVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/IVar.html) Similar to a
|
202
|
+
"future" but can be manually assigned once, after which it becomes immutable.~~ Replaced by
|
203
|
+
[Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html).
|
204
|
+
|
111
205
|
### Edge Features
|
112
206
|
|
113
207
|
These are available in the `concurrent-ruby-edge` companion gem.
|
114
208
|
|
115
209
|
These features are under active development and may change frequently. They are expected not to
|
116
210
|
keep backward compatibility (there may also lack tests and documentation). Semantic versions will
|
117
|
-
be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
*
|
131
|
-
*
|
132
|
-
*
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
- **Channel** - Brand new implementation; partial documentation and tests; stability is good.
|
143
|
-
- **LazyRegister** - Missing documentation and tests.
|
144
|
-
- **AtomicMarkableReference, LockFreeLinkedSet, LockFreeStack** - Need real world battle testing.
|
211
|
+
be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to
|
212
|
+
`concurrent-ruby` when final.
|
213
|
+
|
214
|
+
* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Actor.html): Implements
|
215
|
+
the Actor Model, where concurrent actors exchange messages.
|
216
|
+
*Status: Partial documentation and tests; depends on new future/promise framework; stability is good.*
|
217
|
+
* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Channel.html):
|
218
|
+
Communicating Sequential Processes ([CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes)).
|
219
|
+
Functionally equivalent to Go [channels](https://tour.golang.org/concurrency/2) with additional
|
220
|
+
inspiration from Clojure [core.async](https://clojure.github.io/core.async/).
|
221
|
+
*Status: Partial documentation and tests.*
|
222
|
+
* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LazyRegister.html)
|
223
|
+
* [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Edge/LockFreeLinkedSet.html)
|
224
|
+
*Status: will be moved to core soon.*
|
225
|
+
* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LockFreeStack.html)
|
226
|
+
*Status: missing documentation and tests.*
|
227
|
+
|
228
|
+
## Supported Ruby versions
|
229
|
+
|
230
|
+
MRI 2.0 and above, JRuby 9000, TruffleRuby are supported.
|
231
|
+
This gem should be fully compatible with any interpreter that is compliant with Ruby 2.0 or newer.
|
232
|
+
Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs is supported.
|
233
|
+
|
234
|
+
The legacy support for Rubinius is kept but it is no longer maintained, if you would like to help
|
235
|
+
please respond to [#739](https://github.com/ruby-concurrency/concurrent-ruby/issues/739).
|
145
236
|
|
146
237
|
## Usage
|
147
238
|
|
@@ -151,13 +242,16 @@ Everything within this gem can be loaded simply by requiring it:
|
|
151
242
|
require 'concurrent'
|
152
243
|
```
|
153
244
|
|
245
|
+
*Requiring only specific abstractions from Concurrent Ruby is not yet supported.*
|
246
|
+
|
154
247
|
To use the tools in the Edge gem it must be required separately:
|
155
248
|
|
156
249
|
```ruby
|
157
250
|
require 'concurrent-edge'
|
158
251
|
```
|
159
252
|
|
160
|
-
If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could
|
253
|
+
If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could
|
254
|
+
help to reveal the problem.
|
161
255
|
|
162
256
|
## Installation
|
163
257
|
|
@@ -193,9 +287,9 @@ and run `bundle install` from your shell.
|
|
193
287
|
### C Extensions for MRI
|
194
288
|
|
195
289
|
Potential performance improvements may be achieved under MRI by installing optional C extensions.
|
196
|
-
To
|
197
|
-
gem. `concurrent-ruby` and `concurrent-ruby-ext` are always released together with same
|
198
|
-
Simply install the extension gem too:
|
290
|
+
To minimise installation errors the C extensions are available in the `concurrent-ruby-ext`
|
291
|
+
extension gem. `concurrent-ruby` and `concurrent-ruby-ext` are always released together with same
|
292
|
+
version. Simply install the extension gem too:
|
199
293
|
|
200
294
|
```ruby
|
201
295
|
gem install concurrent-ruby-ext
|
@@ -220,28 +314,32 @@ and load the appropriate C extensions.
|
|
220
314
|
|
221
315
|
#### Note For gem developers
|
222
316
|
|
223
|
-
No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users.
|
224
|
-
|
317
|
+
No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The
|
318
|
+
best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions.
|
225
319
|
|
226
320
|
## Maintainers
|
227
321
|
|
228
|
-
*
|
229
|
-
*
|
230
|
-
*
|
231
|
-
|
232
|
-
|
233
|
-
|
322
|
+
* [Petr Chalupa](https://github.com/pitr-ch) (lead maintainer, point-of-contact)
|
323
|
+
* [Jerry D'Antonio](https://github.com/jdantonio) (creator)
|
324
|
+
* [Chris Seaton](https://github.com/chrisseaton)
|
325
|
+
|
326
|
+
### Special Thanks to
|
327
|
+
|
328
|
+
* [Brian Durand](https://github.com/bdurand) for the `ref` gem
|
329
|
+
* [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems
|
330
|
+
* [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem
|
234
331
|
|
235
|
-
|
332
|
+
and to the past maintainers
|
236
333
|
|
237
|
-
*
|
238
|
-
*
|
239
|
-
*
|
334
|
+
* [Michele Della Torre](https://github.com/mighe)
|
335
|
+
* [Paweł Obrok](https://github.com/obrok)
|
336
|
+
* [Lucas Allan](https://github.com/lucasallan)
|
240
337
|
|
241
338
|
## License and Copyright
|
242
339
|
|
243
|
-
*Concurrent Ruby* is free software released under the
|
340
|
+
*Concurrent Ruby* is free software released under the
|
341
|
+
[MIT License](http://www.opensource.org/licenses/MIT).
|
244
342
|
|
245
|
-
The *Concurrent Ruby* [logo](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Logo)
|
246
|
-
|
247
|
-
|
343
|
+
The *Concurrent Ruby* [logo](https://github.com/ruby-concurrency/concurrent-ruby/wiki/Logo) was
|
344
|
+
designed by [David Jones](https://twitter.com/zombyboy). It is Copyright © 2014
|
345
|
+
[Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved.
|
@@ -21,13 +21,12 @@ VALUE method_atomic_boolean_initialize(int argc, VALUE* argv, VALUE self) {
|
|
21
21
|
}
|
22
22
|
|
23
23
|
VALUE method_atomic_boolean_value(VALUE self) {
|
24
|
-
return
|
24
|
+
return(ir_get(self));
|
25
25
|
}
|
26
26
|
|
27
27
|
VALUE method_atomic_boolean_value_set(VALUE self, VALUE value) {
|
28
28
|
VALUE new_value = TRUTHY(value);
|
29
|
-
|
30
|
-
return(new_value);
|
29
|
+
return(ir_set(self, new_value));
|
31
30
|
}
|
32
31
|
|
33
32
|
VALUE method_atomic_boolean_true_question(VALUE self) {
|
File without changes
|
File without changes
|
File without changes
|
@@ -7,8 +7,38 @@
|
|
7
7
|
/*#include <libkern/OSAtomic.h>*/
|
8
8
|
/*#endif*/
|
9
9
|
|
10
|
+
/*
|
11
|
+
Following the wisdom of postgres, we opt to use platform specific memory barriers when available.
|
12
|
+
These are generally more performant. In this PR, we add specific cases for i386, x86_64.
|
13
|
+
|
14
|
+
In the future, we could look at using pg's atomics library directly:
|
15
|
+
https://github.com/postgres/postgres/tree/9d4649ca49416111aee2c84b7e4441a0b7aa2fac/src/include/port/atomics
|
16
|
+
|
17
|
+
Point of contact @ianks
|
18
|
+
*/
|
19
|
+
|
10
20
|
#include "atomic_reference.h"
|
11
21
|
|
22
|
+
#if (defined(__i386__) || defined(__i386)) && (defined(__GNUC__) || defined(__INTEL_COMPILER))
|
23
|
+
#define memory_barrier() \
|
24
|
+
__asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory", "cc")
|
25
|
+
#elif defined(__x86_64__) && (defined(__GNUC__) || defined(__INTEL_COMPILER))
|
26
|
+
#define memory_barrier() \
|
27
|
+
__asm__ __volatile__ ("lock; addl $0,0(%%rsp)" : : : "memory", "cc")
|
28
|
+
#elif defined(HAVE_GCC__ATOMIC_INT32_CAS)
|
29
|
+
#define memory_barrier() \
|
30
|
+
__atomic_thread_fence(__ATOMIC_SEQ_CST)
|
31
|
+
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
|
32
|
+
#define memory_barrier() \
|
33
|
+
__sync_synchronize();
|
34
|
+
#elif defined _MSC_VER
|
35
|
+
#define memory_barrier() \
|
36
|
+
MemoryBarrier();
|
37
|
+
#elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
38
|
+
#define memory_barrier() \
|
39
|
+
OSMemoryBarrier();
|
40
|
+
#endif
|
41
|
+
|
12
42
|
void ir_mark(void *value) {
|
13
43
|
rb_gc_mark_maybe((VALUE) value);
|
14
44
|
}
|
@@ -27,25 +57,13 @@ VALUE ir_initialize(int argc, VALUE* argv, VALUE self) {
|
|
27
57
|
}
|
28
58
|
|
29
59
|
VALUE ir_get(VALUE self) {
|
30
|
-
|
31
|
-
__sync_synchronize();
|
32
|
-
#elif defined _MSC_VER
|
33
|
-
MemoryBarrier();
|
34
|
-
#elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
35
|
-
OSMemoryBarrier();
|
36
|
-
#endif
|
60
|
+
memory_barrier();
|
37
61
|
return (VALUE) DATA_PTR(self);
|
38
62
|
}
|
39
63
|
|
40
64
|
VALUE ir_set(VALUE self, VALUE new_value) {
|
41
65
|
DATA_PTR(self) = (void *) new_value;
|
42
|
-
|
43
|
-
__sync_synchronize();
|
44
|
-
#elif defined _MSC_VER
|
45
|
-
MemoryBarrier();
|
46
|
-
#elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
47
|
-
OSMemoryBarrier();
|
48
|
-
#endif
|
66
|
+
memory_barrier();
|
49
67
|
return new_value;
|
50
68
|
}
|
51
69
|
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
extension_name = 'concurrent_ruby_ext'
|
4
|
+
|
5
|
+
require 'mkmf'
|
6
|
+
dir_config(extension_name)
|
7
|
+
have_header "libkern/OSAtomic.h"
|
8
|
+
|
9
|
+
compiler_is_gcc = (CONFIG["GCC"] && !CONFIG["GCC"].empty?) ||
|
10
|
+
# This could stand to be more generic... but I am afraid.
|
11
|
+
CONFIG["CC"] =~ /\bgcc\b/
|
12
|
+
|
13
|
+
if compiler_is_gcc
|
14
|
+
case CONFIG["arch"]
|
15
|
+
when /mswin32|mingw|solaris/
|
16
|
+
$CFLAGS += " -march=native"
|
17
|
+
when 'i686-linux'
|
18
|
+
$CFLAGS += " -march=i686"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
create_makefile File.join('concurrent', extension_name)
|
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concurrent-ruby-ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.1.0.pre1
|
5
5
|
platform: x86-mingw32
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-08-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: concurrent-ruby
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - '='
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.0.
|
20
|
+
version: 1.1.0.pre1
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - '='
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.0.
|
27
|
+
version: 1.1.0.pre1
|
28
28
|
description: |2
|
29
29
|
C extensions to optimize the concurrent-ruby gem when running under MRI.
|
30
30
|
Please see http://concurrent-ruby.com for more information.
|
@@ -33,28 +33,27 @@ executables: []
|
|
33
33
|
extensions: []
|
34
34
|
extra_rdoc_files:
|
35
35
|
- README.md
|
36
|
-
- LICENSE.
|
36
|
+
- LICENSE.md
|
37
37
|
- CHANGELOG.md
|
38
38
|
files:
|
39
39
|
- CHANGELOG.md
|
40
|
-
- LICENSE.
|
40
|
+
- LICENSE.md
|
41
41
|
- README.md
|
42
|
-
- ext/concurrent/atomic_boolean.c
|
43
|
-
- ext/concurrent/atomic_boolean.h
|
44
|
-
- ext/concurrent/atomic_fixnum.c
|
45
|
-
- ext/concurrent/atomic_fixnum.h
|
46
|
-
- ext/concurrent/atomic_reference.c
|
47
|
-
- ext/concurrent/atomic_reference.h
|
48
|
-
- ext/concurrent/extconf.rb
|
49
|
-
- ext/concurrent/rb_concurrent.c
|
50
|
-
- ext/concurrent/ruby_193_compatible.h
|
51
|
-
- lib/concurrent/
|
52
|
-
- lib/concurrent/2.
|
53
|
-
- lib/concurrent/2.
|
54
|
-
- lib/concurrent/2.
|
55
|
-
- lib/concurrent/
|
56
|
-
- lib/concurrent/
|
57
|
-
- lib/concurrent/atomic_reference/numeric_cas_wrapper.rb
|
42
|
+
- ext/concurrent-ruby-ext/atomic_boolean.c
|
43
|
+
- ext/concurrent-ruby-ext/atomic_boolean.h
|
44
|
+
- ext/concurrent-ruby-ext/atomic_fixnum.c
|
45
|
+
- ext/concurrent-ruby-ext/atomic_fixnum.h
|
46
|
+
- ext/concurrent-ruby-ext/atomic_reference.c
|
47
|
+
- ext/concurrent-ruby-ext/atomic_reference.h
|
48
|
+
- ext/concurrent-ruby-ext/extconf.rb
|
49
|
+
- ext/concurrent-ruby-ext/rb_concurrent.c
|
50
|
+
- ext/concurrent-ruby-ext/ruby_193_compatible.h
|
51
|
+
- lib/concurrent/2.0/concurrent_ruby_ext.so
|
52
|
+
- lib/concurrent/2.1/concurrent_ruby_ext.so
|
53
|
+
- lib/concurrent/2.2/concurrent_ruby_ext.so
|
54
|
+
- lib/concurrent/2.3/concurrent_ruby_ext.so
|
55
|
+
- lib/concurrent/2.4/concurrent_ruby_ext.so
|
56
|
+
- lib/concurrent/2.5/concurrent_ruby_ext.so
|
58
57
|
homepage: http://www.concurrent-ruby.com
|
59
58
|
licenses:
|
60
59
|
- MIT
|
@@ -63,20 +62,22 @@ post_install_message:
|
|
63
62
|
rdoc_options: []
|
64
63
|
require_paths:
|
65
64
|
- lib
|
66
|
-
- ext
|
67
65
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
66
|
requirements:
|
69
67
|
- - ">="
|
70
68
|
- !ruby/object:Gem::Version
|
71
|
-
version:
|
69
|
+
version: '2.0'
|
70
|
+
- - "<"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '2.6'
|
72
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
74
|
requirements:
|
74
|
-
- - "
|
75
|
+
- - ">"
|
75
76
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
77
|
+
version: 1.3.1
|
77
78
|
requirements: []
|
78
79
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.
|
80
|
+
rubygems_version: 2.7.3
|
80
81
|
signing_key:
|
81
82
|
specification_version: 4
|
82
83
|
summary: C extensions to optimize concurrent-ruby under MRI.
|
data/ext/concurrent/extconf.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
|
-
$:.unshift(File.expand_path('../../../lib', __FILE__))
|
4
|
-
require 'concurrent/utility/native_extension_loader'
|
5
|
-
|
6
|
-
EXTENSION_NAME = 'extension'
|
7
|
-
|
8
|
-
def create_dummy_makefile
|
9
|
-
File.open('Makefile', 'w') do |f|
|
10
|
-
f.puts 'all:'
|
11
|
-
f.puts 'install:'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
if Concurrent.on_jruby? || ! Concurrent.allow_c_extensions?
|
16
|
-
create_dummy_makefile
|
17
|
-
warn 'C optimizations are not supported on this version of Ruby.'
|
18
|
-
else
|
19
|
-
begin
|
20
|
-
|
21
|
-
require 'mkmf'
|
22
|
-
dir_config(EXTENSION_NAME)
|
23
|
-
|
24
|
-
have_header "libkern/OSAtomic.h"
|
25
|
-
|
26
|
-
def compiler_is_gcc
|
27
|
-
if CONFIG["GCC"] && CONFIG["GCC"] != ""
|
28
|
-
return true
|
29
|
-
elsif ( # This could stand to be more generic... but I am afraid.
|
30
|
-
CONFIG["CC"] =~ /\bgcc\b/
|
31
|
-
)
|
32
|
-
return true
|
33
|
-
end
|
34
|
-
return false
|
35
|
-
end
|
36
|
-
|
37
|
-
if compiler_is_gcc
|
38
|
-
case CONFIG["arch"]
|
39
|
-
when /mswin32|mingw|solaris/
|
40
|
-
$CFLAGS += " -march=native"
|
41
|
-
when 'i686-linux'
|
42
|
-
$CFLAGS += " -march=i686"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
try_run(<<CODE,$CFLAGS) && ($defs << '-DHAVE_GCC_SYNC')
|
47
|
-
int main() {
|
48
|
-
__sync_synchronize();
|
49
|
-
return 0;
|
50
|
-
}
|
51
|
-
CODE
|
52
|
-
|
53
|
-
create_makefile('concurrent/' + EXTENSION_NAME)
|
54
|
-
rescue
|
55
|
-
create_dummy_makefile
|
56
|
-
warn 'C optimizations cannot be compiled on this version of Ruby.'
|
57
|
-
end
|
58
|
-
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'concurrent/atomic_reference/concurrent_update_error'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
# Define update methods that use direct paths
|
6
|
-
#
|
7
|
-
# @!visibility private
|
8
|
-
# @!macro internal_implementation_note
|
9
|
-
module AtomicDirectUpdate
|
10
|
-
|
11
|
-
# @!macro [attach] atomic_reference_method_update
|
12
|
-
#
|
13
|
-
# Pass the current value to the given block, replacing it
|
14
|
-
# with the block's result. May retry if the value changes
|
15
|
-
# during the block's execution.
|
16
|
-
#
|
17
|
-
# @yield [Object] Calculate a new value for the atomic reference using
|
18
|
-
# given (old) value
|
19
|
-
# @yieldparam [Object] old_value the starting value of the atomic reference
|
20
|
-
#
|
21
|
-
# @return [Object] the new value
|
22
|
-
def update
|
23
|
-
true until compare_and_set(old_value = get, new_value = yield(old_value))
|
24
|
-
new_value
|
25
|
-
end
|
26
|
-
|
27
|
-
# @!macro [attach] atomic_reference_method_try_update
|
28
|
-
#
|
29
|
-
# Pass the current value to the given block, replacing it
|
30
|
-
# with the block's result. Return nil if the update fails.
|
31
|
-
#
|
32
|
-
# @yield [Object] Calculate a new value for the atomic reference using
|
33
|
-
# given (old) value
|
34
|
-
# @yieldparam [Object] old_value the starting value of the atomic reference
|
35
|
-
#
|
36
|
-
# @note This method was altered to avoid raising an exception by default.
|
37
|
-
# Instead, this method now returns `nil` in case of failure. For more info,
|
38
|
-
# please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336
|
39
|
-
#
|
40
|
-
# @return [Object] the new value, or nil if update failed
|
41
|
-
def try_update
|
42
|
-
old_value = get
|
43
|
-
new_value = yield old_value
|
44
|
-
|
45
|
-
return unless compare_and_set old_value, new_value
|
46
|
-
|
47
|
-
new_value
|
48
|
-
end
|
49
|
-
|
50
|
-
# @!macro [attach] atomic_reference_method_try_update!
|
51
|
-
#
|
52
|
-
# Pass the current value to the given block, replacing it
|
53
|
-
# with the block's result. Raise an exception if the update
|
54
|
-
# fails.
|
55
|
-
#
|
56
|
-
# @yield [Object] Calculate a new value for the atomic reference using
|
57
|
-
# given (old) value
|
58
|
-
# @yieldparam [Object] old_value the starting value of the atomic reference
|
59
|
-
#
|
60
|
-
# @note This behavior mimics the behavior of the original
|
61
|
-
# `AtomicReference#try_update` API. The reason this was changed was to
|
62
|
-
# avoid raising exceptions (which are inherently slow) by default. For more
|
63
|
-
# info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336
|
64
|
-
#
|
65
|
-
# @return [Object] the new value
|
66
|
-
#
|
67
|
-
# @raise [Concurrent::ConcurrentUpdateError] if the update fails
|
68
|
-
def try_update!
|
69
|
-
old_value = get
|
70
|
-
new_value = yield old_value
|
71
|
-
unless compare_and_set(old_value, new_value)
|
72
|
-
if $VERBOSE
|
73
|
-
raise ConcurrentUpdateError, "Update failed"
|
74
|
-
else
|
75
|
-
raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE
|
76
|
-
end
|
77
|
-
end
|
78
|
-
new_value
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Concurrent
|
2
|
-
|
3
|
-
# Special "compare and set" handling of numeric values.
|
4
|
-
#
|
5
|
-
# @!visibility private
|
6
|
-
# @!macro internal_implementation_note
|
7
|
-
module AtomicNumericCompareAndSetWrapper
|
8
|
-
|
9
|
-
# @!macro atomic_reference_method_compare_and_set
|
10
|
-
def compare_and_set(old_value, new_value)
|
11
|
-
if old_value.kind_of? Numeric
|
12
|
-
while true
|
13
|
-
old = get
|
14
|
-
|
15
|
-
return false unless old.kind_of? Numeric
|
16
|
-
|
17
|
-
return false unless old == old_value
|
18
|
-
|
19
|
-
result = _compare_and_set(old, new_value)
|
20
|
-
return result if result
|
21
|
-
end
|
22
|
-
else
|
23
|
-
_compare_and_set(old_value, new_value)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
alias_method :compare_and_swap, :compare_and_set
|
27
|
-
end
|
28
|
-
end
|