concurrent-ruby 0.9.2 → 1.0.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -1
- data/README.md +67 -68
- data/lib/concurrent.rb +14 -1
- data/lib/concurrent/array.rb +38 -0
- data/lib/concurrent/async.rb +0 -17
- data/lib/concurrent/atomic/abstract_thread_local_var.rb +40 -0
- data/lib/concurrent/atomic/atomic_boolean.rb +81 -118
- data/lib/concurrent/atomic/atomic_fixnum.rb +98 -162
- data/lib/concurrent/atomic/atomic_reference.rb +0 -7
- data/lib/concurrent/atomic/count_down_latch.rb +62 -103
- data/lib/concurrent/atomic/cyclic_barrier.rb +2 -0
- data/lib/concurrent/atomic/java_count_down_latch.rb +39 -0
- data/lib/concurrent/atomic/java_thread_local_var.rb +50 -0
- data/lib/concurrent/atomic/mutex_atomic_boolean.rb +60 -0
- data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +91 -0
- data/lib/concurrent/atomic/mutex_count_down_latch.rb +43 -0
- data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
- data/lib/concurrent/atomic/ruby_thread_local_var.rb +172 -0
- data/lib/concurrent/atomic/semaphore.rb +84 -178
- data/lib/concurrent/atomic/thread_local_var.rb +63 -294
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +14 -8
- data/lib/concurrent/atomics.rb +0 -33
- data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
- data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +921 -0
- data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
- data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +142 -0
- data/lib/concurrent/collection/map/synchronized_map_backend.rb +86 -0
- data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
- data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
- data/lib/concurrent/concern/logging.rb +1 -1
- data/lib/concurrent/concern/obligation.rb +0 -12
- data/lib/concurrent/configuration.rb +18 -148
- data/lib/concurrent/delay.rb +5 -4
- data/lib/concurrent/exchanger.rb +327 -41
- data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
- data/lib/concurrent/executor/executor.rb +4 -29
- data/lib/concurrent/executor/executor_service.rb +23 -359
- data/lib/concurrent/executor/immediate_executor.rb +3 -2
- data/lib/concurrent/executor/java_executor_service.rb +100 -0
- data/lib/concurrent/executor/java_single_thread_executor.rb +3 -2
- data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -4
- data/lib/concurrent/executor/ruby_executor_service.rb +72 -0
- data/lib/concurrent/executor/ruby_single_thread_executor.rb +7 -5
- data/lib/concurrent/executor/ruby_thread_pool_executor.rb +3 -11
- data/lib/concurrent/executor/safe_task_executor.rb +1 -1
- data/lib/concurrent/executor/serial_executor_service.rb +34 -0
- data/lib/concurrent/executor/serialized_execution.rb +8 -31
- data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
- data/lib/concurrent/executor/simple_executor_service.rb +1 -10
- data/lib/concurrent/executor/timer_set.rb +4 -8
- data/lib/concurrent/executors.rb +13 -2
- data/lib/concurrent/future.rb +2 -2
- data/lib/concurrent/hash.rb +35 -0
- data/lib/concurrent/ivar.rb +9 -14
- data/lib/concurrent/map.rb +178 -0
- data/lib/concurrent/promise.rb +2 -2
- data/lib/concurrent/scheduled_task.rb +9 -69
- data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
- data/lib/concurrent/thread_safe/util.rb +23 -0
- data/lib/concurrent/thread_safe/util/adder.rb +71 -0
- data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +28 -0
- data/lib/concurrent/thread_safe/util/cheap_lockable.rb +115 -0
- data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +37 -0
- data/lib/concurrent/thread_safe/util/striped64.rb +236 -0
- data/lib/concurrent/thread_safe/util/volatile.rb +73 -0
- data/lib/concurrent/thread_safe/util/xor_shift_random.rb +48 -0
- data/lib/concurrent/timer_task.rb +3 -3
- data/lib/concurrent/tuple.rb +86 -0
- data/lib/concurrent/version.rb +2 -2
- metadata +37 -10
- data/lib/concurrent/atomic/condition.rb +0 -78
- data/lib/concurrent/collection/priority_queue.rb +0 -360
- data/lib/concurrent/utilities.rb +0 -5
- data/lib/concurrent/utility/timeout.rb +0 -39
- data/lib/concurrent/utility/timer.rb +0 -26
- data/lib/concurrent_ruby.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73752ee1b21c6a7bed99d034af965e1f7bc12af7
|
4
|
+
data.tar.gz: 1d1cfe49be663c6bef102761aae9dfa6e29e26e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0246cc3adb6b535e7d3149663e5ef771575b0c75d92509e8517853d13c1c06133b354573e5c900308bef5cab7f141dd06d0a89f79493841e6d1b19f6110088a3
|
7
|
+
data.tar.gz: b5e8453b5123206bdaed3cc8122eb65077638a33b977f2d103be998ae42180cfe5bc23fc8eb921a9aab17208f4a26b4826211dd7e76b6275ba82ea705a49aec9
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,18 @@
|
|
1
|
-
## Current Release
|
1
|
+
## Current Release v1.0.0.pre1 (19 Aug 2015)
|
2
|
+
|
3
|
+
* Merged in the `thread_safe` gem
|
4
|
+
- `Concurrent::Array`
|
5
|
+
- `Concurrent::Hash`
|
6
|
+
- `Concurrent::Map` (formerly ThreadSafe::Cache)
|
7
|
+
- `Concurrent::Tuple`
|
8
|
+
* Minor improvements to Concurrent::Map
|
9
|
+
* Complete rewrite of `Exchanger`
|
10
|
+
* Removed all deprecated code (classes, methods, constants, etc.)
|
11
|
+
* Updated Agent, MutexAtomic, and BufferedChannel to inherit from Synchronization::Object.
|
12
|
+
* Many improved tests
|
13
|
+
* Some internal reorganization
|
14
|
+
|
15
|
+
### Release v0.9.1 (09 August 2015)
|
2
16
|
|
3
17
|
* Fixed a Rubiniux bug in synchronization object
|
4
18
|
* Fixed all interpreter warnings (except circular references)
|
data/README.md
CHANGED
@@ -47,7 +47,7 @@
|
|
47
47
|
|
48
48
|
MRI 1.9.3, 2.0, 2.1, 2.2, JRuby (1.9 mode), and Rubinius 2.x are supported.
|
49
49
|
This gem should be fully compatible with any interpreter that is compliant with Ruby 1.9.3 or newer.
|
50
|
-
Java 8 is
|
50
|
+
Java 8 is preferred for JRuby but every Java version on which JRuby 9000 runs will be supported.
|
51
51
|
|
52
52
|
## Features & Documentation
|
53
53
|
|
@@ -62,54 +62,62 @@ This library contains a variety of concurrency abstractions at high and low leve
|
|
62
62
|
#### General-purpose Concurrency Abstractions
|
63
63
|
|
64
64
|
* [Async](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Async.html): A mixin module that provides simple asynchronous behavior to any standard class/object or object.
|
65
|
-
* [Atom](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Atom.html): A way to manage shared, synchronous, independent state.
|
66
65
|
* [Future](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Future.html): An asynchronous operation that produces a value.
|
67
66
|
* [Dataflow](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#dataflow-class_method): Built on Futures, Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available.
|
68
67
|
* [Promise](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Promise.html): Similar to Futures, with more features.
|
69
68
|
* [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ScheduledTask.html): Like a Future scheduled for a specific future time.
|
70
69
|
* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TimerTask.html): A Thread that periodically wakes up to perform work at regular intervals.
|
71
70
|
|
72
|
-
#### Thread-safe Value Objects
|
71
|
+
#### Thread-safe Value Objects, Structures, and Collections
|
72
|
+
|
73
|
+
Collection classes that were originally part of the (deprecated) `thread_safe` gem:
|
74
|
+
|
75
|
+
* [Array](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Array.html) A thread-safe subclass of Ruby's standard [Array](http://ruby-doc.org/core-2.2.0/Array.html).
|
76
|
+
* [Hash](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Hash.html) A thread-safe subclass of Ruby's standard [Hash](http://ruby-doc.org/core-2.2.0/Hash.html).
|
77
|
+
* [Map](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Map.html) A hash-like object that should have much better performance characteristics, especially under high concurrency, than `Concurrent::Hash`.
|
78
|
+
* [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Tuple.html) A fixed size array with volatile (synchronized, thread safe) getters/setters.
|
79
|
+
|
80
|
+
Value objects inspired by other languages:
|
73
81
|
|
74
|
-
*
|
82
|
+
* [Atom](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Atom.html): A way to manage shared, synchronous, independent state.
|
83
|
+
* [Maybe](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Maybe.html) A thread-safe, immutable object representing an optional value, based on
|
75
84
|
[Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html).
|
76
|
-
*
|
85
|
+
* [Delay](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Delay.html) Lazy evaluation of a block yielding an immutable result. Based on Clojure's
|
77
86
|
[delay](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Delay.html).
|
78
87
|
|
79
|
-
|
88
|
+
Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
|
89
|
+
|
90
|
+
* [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ImmutableStruct.html) Immutable struct where values are set at construction and cannot be changed later.
|
91
|
+
* [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutableStruct.html) Synchronized, mutable struct where values can be safely changed at any time.
|
92
|
+
* [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/SettableStruct.html) Synchronized, write-once struct where values can be set at most once, either at construction or any time thereafter.
|
80
93
|
|
81
|
-
|
94
|
+
Thread-safe variables:
|
82
95
|
|
83
|
-
*
|
84
|
-
*
|
85
|
-
*
|
96
|
+
* [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicBoolean.html) A boolean value that can be updated atomically.
|
97
|
+
* [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/AtomicFixnum.html) A numeric value that can be updated atomically.
|
98
|
+
* [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutexAtomic.html) An object reference that may be updated atomically.
|
99
|
+
* [ThreadLocalVar](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html) A variable where the value is different for each thread.
|
86
100
|
|
87
101
|
#### Java-inspired ThreadPools and Other Executors
|
88
102
|
|
89
|
-
* See [
|
103
|
+
* See the [thread pool](http://ruby-concurrency.github.io/concurrent-ruby/file.thread_pools.html) overview, which also contains a list of other Executors available.
|
90
104
|
|
91
105
|
#### Thread Synchronization Classes and Algorithms
|
92
106
|
|
93
|
-
* [CountdownLatch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html)
|
94
|
-
* [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CyclicBarrier.html)
|
95
|
-
* [Event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html)
|
96
|
-
* [
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
* [
|
101
|
-
* [
|
102
|
-
* [
|
103
|
-
* [I-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html) (IVar)
|
104
|
-
* [M-Structures](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html) (MVar)
|
105
|
-
* [Thread-local variables](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadLocalVar.html)
|
106
|
-
* [Software transactional memory](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TVar.html) (TVar)
|
107
|
-
* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReadWriteLock.html)
|
108
|
-
* [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReentrantReadWriteLock.html)
|
107
|
+
* [CountdownLatch](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CountDownLatch.html) A synchronization object that allows one thread to wait on multiple other threads.
|
108
|
+
* [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/CyclicBarrier.html) A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
|
109
|
+
* [Event](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Event.html) Old school kernel-style event.
|
110
|
+
* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html)
|
111
|
+
* [I-Structure](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/IVar.html) (IVar) Similar to a "future" but can be manually assigned once, after which it becomes immutable.
|
112
|
+
* [M-Structure](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MVar.html) (MVar) A synchronized single element container.
|
113
|
+
* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReadWriteLock.html) A lock that supports multiple readers but only one writer.
|
114
|
+
* [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ReentrantReadWriteLock.html) A read/write lock with reentrant and upgrade features.
|
115
|
+
* [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Semaphore.html) A counting-based locking mechanism that uses permits.
|
116
|
+
* [Software transactional memory](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/TVar.html) (TVar) A transactional variable - a single-element container that is used as part of a transaction.
|
109
117
|
|
110
118
|
### Edge Features
|
111
119
|
|
112
|
-
These are available in the `concurrent-ruby-edge` companion gem
|
120
|
+
These are available in the `concurrent-ruby-edge` companion gem.
|
113
121
|
|
114
122
|
These features are under active development and may change frequently. They are expected not to
|
115
123
|
keep backward compatibility (there may also lack tests and documentation). Semantic versions will
|
@@ -125,10 +133,9 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
|
|
125
133
|
* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Agent.html): A single atomic value that represents an identity.
|
126
134
|
* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Channel.html):
|
127
135
|
Communicating Sequential Processes (CSP).
|
128
|
-
* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Exchanger.html)
|
129
136
|
* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/LazyRegister.html)
|
130
|
-
* [
|
131
|
-
* [
|
137
|
+
* [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/AtomicMarkableReference.html)
|
138
|
+
* [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeLinkedSet.html)
|
132
139
|
* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge/LockFreeStack.html)
|
133
140
|
|
134
141
|
#### Statuses:
|
@@ -139,52 +146,21 @@ be obeyed though. Features developed in `concurrent-ruby-edge` are expected to m
|
|
139
146
|
- **Future/Promise Framework** - API changes; partial documentation and tests; stability good.
|
140
147
|
- **Agent** - Incomplete behaviour compared to Clojure's models; stability good.
|
141
148
|
- **Channel** - Missing documentation; limted features; stability good.
|
142
|
-
- **Exchanger** - Known race condition requiring a new implementation.
|
143
149
|
- **LazyRegister** - Missing documentation and tests.
|
144
150
|
- **AtomicMarkableReference, LockFreeLinkedSet, LockFreeStack** - Needs real world battle testing
|
145
151
|
|
146
152
|
## Usage
|
147
153
|
|
148
|
-
|
154
|
+
Everything within this gem can be loaded simply by requiring it:
|
149
155
|
|
150
156
|
```ruby
|
151
157
|
require 'concurrent'
|
152
158
|
```
|
153
159
|
|
154
|
-
To
|
160
|
+
To use the tools in the Edge gem it must be required separately:
|
155
161
|
|
156
162
|
```ruby
|
157
|
-
require 'concurrent'
|
158
|
-
|
159
|
-
# groups
|
160
|
-
|
161
|
-
require 'concurrent/atomics' # atomic and thread synchronization classes
|
162
|
-
require 'concurrent/executors' # Thread pools and other executors
|
163
|
-
|
164
|
-
# individual abstractions
|
165
|
-
|
166
|
-
require 'concurrent/async' # Concurrent::Async
|
167
|
-
require 'concurrent/atom' # Concurrent::Atom
|
168
|
-
require 'concurrent/dataflow' # Concurrent::dataflow
|
169
|
-
require 'concurrent/delay' # Concurrent::Delay
|
170
|
-
require 'concurrent/future' # Concurrent::Future
|
171
|
-
require 'concurrent/immutable_struct' # Concurrent::ImmutableStruct
|
172
|
-
require 'concurrent/ivar' # Concurrent::IVar
|
173
|
-
require 'concurrent/maybe' # Concurrent::Maybe
|
174
|
-
require 'concurrent/mutable_struct' # Concurrent::MutableStruct
|
175
|
-
require 'concurrent/mvar' # Concurrent::MVar
|
176
|
-
require 'concurrent/promise' # Concurrent::Promise
|
177
|
-
require 'concurrent/scheduled_task' # Concurrent::ScheduledTask
|
178
|
-
require 'concurrent/settable_struct' # Concurrent::SettableStruct
|
179
|
-
require 'concurrent/timer_task' # Concurrent::TimerTask
|
180
|
-
require 'concurrent/tvar' # Concurrent::TVar
|
181
|
-
|
182
|
-
# experimental - available in `concurrent-ruby-edge` companion gem
|
183
|
-
|
184
|
-
require 'concurrent/actor' # Concurrent::Actor and supporting code
|
185
|
-
require 'concurrent/edge/future' # new Future Framework
|
186
|
-
require 'concurrent/agent' # Concurrent::Agent
|
187
|
-
require 'concurrent/channel ' # Concurrent::Channel and supporting code
|
163
|
+
require 'concurrent-edge'
|
188
164
|
```
|
189
165
|
|
190
166
|
If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could help to reveal the problem.
|
@@ -203,6 +179,23 @@ gem 'concurrent-ruby'
|
|
203
179
|
|
204
180
|
and run `bundle install` from your shell.
|
205
181
|
|
182
|
+
### Edge Gem Installation
|
183
|
+
|
184
|
+
The Edge gem must be installed separately from the core gem:
|
185
|
+
|
186
|
+
```shell
|
187
|
+
gem install concurrent-ruby-edge
|
188
|
+
```
|
189
|
+
|
190
|
+
or add the following line to Gemfile:
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
gem 'concurrent-ruby-edge'
|
194
|
+
```
|
195
|
+
|
196
|
+
and run `bundle install` from your shell.
|
197
|
+
|
198
|
+
|
206
199
|
### C Extensions for MRI
|
207
200
|
|
208
201
|
Potential performance improvements may be achieved under MRI by installing optional C extensions.
|
@@ -240,7 +233,7 @@ The best practice is to depend on `concurrent-ruby` and let users to decide if t
|
|
240
233
|
|
241
234
|
All published versions of this gem (core, extension, and several platform-specific packages) are compiled,
|
242
235
|
packaged, tested, and published using an open, [automated process](https://github.com/ruby-concurrency/rake-compiler-dev-box).
|
243
|
-
This process can also be used to create pre-compiled binaries of the extension gem for
|
236
|
+
This process can also be used to create pre-compiled binaries of the extension gem for virtually
|
244
237
|
any platform. *Documentation is forthcoming...*
|
245
238
|
|
246
239
|
```
|
@@ -272,11 +265,17 @@ bundle exec rake compile # Compile all the extensions
|
|
272
265
|
## Maintainers
|
273
266
|
|
274
267
|
* [Jerry D'Antonio](https://github.com/jdantonio) (creator)
|
268
|
+
* [Petr Chalupa](https://github.com/pitr-ch)
|
275
269
|
* [Michele Della Torre](https://github.com/mighe)
|
276
270
|
* [Chris Seaton](https://github.com/chrisseaton)
|
277
|
-
* [Lucas Allan](https://github.com/lucasallan)
|
278
|
-
* [Petr Chalupa](https://github.com/pitr-ch)
|
279
271
|
* [Paweł Obrok](https://github.com/obrok)
|
272
|
+
* [Lucas Allan](https://github.com/lucasallan)
|
273
|
+
|
274
|
+
### Special Thanks
|
275
|
+
|
276
|
+
* [Brian Durand](https://github.com/bdurand) for the `ref` gem
|
277
|
+
* [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems
|
278
|
+
* [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem
|
280
279
|
|
281
280
|
## Contributing
|
282
281
|
|
data/lib/concurrent.rb
CHANGED
@@ -7,13 +7,17 @@ require 'concurrent/configuration'
|
|
7
7
|
require 'concurrent/atomics'
|
8
8
|
require 'concurrent/errors'
|
9
9
|
require 'concurrent/executors'
|
10
|
-
require 'concurrent/utilities'
|
11
10
|
|
12
11
|
require 'concurrent/atomic/atomic_reference'
|
13
12
|
require 'concurrent/atom'
|
13
|
+
require 'concurrent/array'
|
14
|
+
require 'concurrent/hash'
|
15
|
+
require 'concurrent/map'
|
16
|
+
require 'concurrent/tuple'
|
14
17
|
require 'concurrent/async'
|
15
18
|
require 'concurrent/dataflow'
|
16
19
|
require 'concurrent/delay'
|
20
|
+
require 'concurrent/exchanger'
|
17
21
|
require 'concurrent/future'
|
18
22
|
require 'concurrent/immutable_struct'
|
19
23
|
require 'concurrent/ivar'
|
@@ -26,6 +30,10 @@ require 'concurrent/settable_struct'
|
|
26
30
|
require 'concurrent/timer_task'
|
27
31
|
require 'concurrent/tvar'
|
28
32
|
|
33
|
+
require 'concurrent/thread_safe/synchronized_delegator'
|
34
|
+
require 'concurrent/thread_safe/util'
|
35
|
+
|
36
|
+
|
29
37
|
# @!macro [new] internal_implementation_note
|
30
38
|
#
|
31
39
|
# @note **Private Implementation:** This abstraction is a private, internal
|
@@ -118,4 +126,9 @@ require 'concurrent/tvar'
|
|
118
126
|
# * Be small, lean, and loosely coupled
|
119
127
|
module Concurrent
|
120
128
|
|
129
|
+
# Various classes within allows for +nil+ values to be stored,
|
130
|
+
# so a special +NULL+ token is required to indicate the "nil-ness".
|
131
|
+
# @!visibility private
|
132
|
+
NULL = Object.new
|
133
|
+
|
121
134
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'concurrent/utility/engine'
|
2
|
+
require 'concurrent/thread_safe/util'
|
3
|
+
|
4
|
+
module Concurrent
|
5
|
+
if Concurrent.on_cruby?
|
6
|
+
|
7
|
+
# Because MRI never runs code in parallel, the existing
|
8
|
+
# non-thread-safe structures should usually work fine.
|
9
|
+
|
10
|
+
# @!macro [attach] concurrent_array
|
11
|
+
#
|
12
|
+
# A thread-safe subclass of Array. This version locks against the object
|
13
|
+
# itself for every method call, ensuring only one thread can be reading
|
14
|
+
# or writing at a time. This includes iteration methods like `#each`.
|
15
|
+
#
|
16
|
+
# @see http://ruby-doc.org/core-2.2.0/Array.html Ruby standard library `Array`
|
17
|
+
class Array < ::Array;
|
18
|
+
end
|
19
|
+
|
20
|
+
elsif Concurrent.on_jruby?
|
21
|
+
require 'jruby/synchronized'
|
22
|
+
|
23
|
+
# @!macro concurrent_array
|
24
|
+
class Array < ::Array
|
25
|
+
include JRuby::Synchronized
|
26
|
+
end
|
27
|
+
|
28
|
+
elsif Concurrent.on_rbx?
|
29
|
+
require 'monitor'
|
30
|
+
|
31
|
+
# @!macro concurrent_array
|
32
|
+
class Array < ::Array
|
33
|
+
end
|
34
|
+
|
35
|
+
ThreadSafe::Util.make_synchronized_on_rbx Array
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
data/lib/concurrent/async.rb
CHANGED
@@ -5,7 +5,6 @@ require 'concurrent/errors'
|
|
5
5
|
require 'concurrent/ivar'
|
6
6
|
require 'concurrent/executor/immediate_executor'
|
7
7
|
require 'concurrent/executor/serialized_execution'
|
8
|
-
require 'concurrent/concern/deprecation'
|
9
8
|
|
10
9
|
module Concurrent
|
11
10
|
|
@@ -248,22 +247,6 @@ module Concurrent
|
|
248
247
|
raise ArgumentError.new('executor has already been set')
|
249
248
|
end
|
250
249
|
|
251
|
-
# Initialize the internal serializer and other stnchronization mechanisms.
|
252
|
-
#
|
253
|
-
# @note This method *must* be called immediately upon object construction.
|
254
|
-
# This is the only way thread-safe initialization can be guaranteed.
|
255
|
-
#
|
256
|
-
# @raise [Concurrent::InitializationError] when called more than once
|
257
|
-
#
|
258
|
-
# @!visibility private
|
259
|
-
# @deprecated
|
260
|
-
def init_mutex
|
261
|
-
deprecated 'mutex synchronization now happens automatically'
|
262
|
-
init_synchronization
|
263
|
-
rescue InitializationError
|
264
|
-
# suppress
|
265
|
-
end
|
266
|
-
|
267
250
|
private
|
268
251
|
|
269
252
|
# Initialize the internal serializer and other stnchronization mechanisms.
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Concurrent
|
2
|
+
|
3
|
+
# @!macro thread_local_var
|
4
|
+
# @!macro internal_implementation_note
|
5
|
+
# @!visibility private
|
6
|
+
class AbstractThreadLocalVar
|
7
|
+
|
8
|
+
# @!visibility private
|
9
|
+
NIL_SENTINEL = Object.new
|
10
|
+
private_constant :NIL_SENTINEL
|
11
|
+
|
12
|
+
# @!macro thread_local_var_method_initialize
|
13
|
+
def initialize(default = nil)
|
14
|
+
@default = default
|
15
|
+
allocate_storage
|
16
|
+
end
|
17
|
+
|
18
|
+
# @!macro thread_local_var_method_get
|
19
|
+
def value
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
# @!macro thread_local_var_method_set
|
24
|
+
def value=(value)
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
# @!macro thread_local_var_method_bind
|
29
|
+
def bind(value, &block)
|
30
|
+
raise NotImplementedError
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
# @!visibility private
|
36
|
+
def allocate_storage
|
37
|
+
raise NotImplementedError
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,113 +1,80 @@
|
|
1
|
+
require 'concurrent/atomic/mutex_atomic_boolean'
|
1
2
|
require 'concurrent/utility/native_extension_loader'
|
2
|
-
require 'concurrent/synchronization'
|
3
3
|
|
4
4
|
module Concurrent
|
5
5
|
|
6
|
-
|
6
|
+
###################################################################
|
7
|
+
|
8
|
+
# @!macro [new] atomic_boolean_method_initialize
|
7
9
|
#
|
8
|
-
#
|
9
|
-
# boolean and thread-safe and guaranteed to succeed. Reads and writes may block
|
10
|
-
# briefly but no explicit locking is required.
|
10
|
+
# Creates a new `AtomicBoolean` with the given initial value.
|
11
11
|
#
|
12
|
-
#
|
13
|
-
|
14
|
-
#
|
15
|
-
# Testing with Concurrent::CAtomicBoolean...
|
16
|
-
# 0.740000 0.000000 0.740000 ( 0.740206)
|
12
|
+
# @param [Boolean] initial the initial value
|
13
|
+
|
14
|
+
# @!macro [new] atomic_boolean_method_value_get
|
17
15
|
#
|
18
|
-
#
|
19
|
-
# Testing with Concurrent::MutexAtomicBoolean...
|
20
|
-
# 5.240000 2.520000 7.760000 ( 3.683000)
|
21
|
-
# Testing with Concurrent::JavaAtomicBoolean...
|
22
|
-
# 3.340000 0.010000 3.350000 ( 0.855000)
|
16
|
+
# Retrieves the current `Boolean` value.
|
23
17
|
#
|
24
|
-
# @
|
18
|
+
# @return [Boolean] the current value
|
19
|
+
|
20
|
+
# @!macro [new] atomic_boolean_method_value_set
|
25
21
|
#
|
26
|
-
#
|
22
|
+
# Explicitly sets the value.
|
27
23
|
#
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
# @!macro [attach] atomic_boolean_method_initialize
|
32
|
-
#
|
33
|
-
# Creates a new `AtomicBoolean` with the given initial value.
|
34
|
-
#
|
35
|
-
# @param [Boolean] initial the initial value
|
36
|
-
def initialize(initial = false)
|
37
|
-
super()
|
38
|
-
synchronize { ns_initialize(initial) }
|
39
|
-
end
|
40
|
-
|
41
|
-
# @!macro [attach] atomic_boolean_method_value_get
|
42
|
-
#
|
43
|
-
# Retrieves the current `Boolean` value.
|
44
|
-
#
|
45
|
-
# @return [Boolean] the current value
|
46
|
-
def value
|
47
|
-
synchronize { @value }
|
48
|
-
end
|
49
|
-
|
50
|
-
# @!macro [attach] atomic_boolean_method_value_set
|
51
|
-
#
|
52
|
-
# Explicitly sets the value.
|
53
|
-
#
|
54
|
-
# @param [Boolean] value the new value to be set
|
55
|
-
#
|
56
|
-
# @return [Boolean] the current value
|
57
|
-
def value=(value)
|
58
|
-
synchronize { @value = !!value }
|
59
|
-
end
|
60
|
-
|
61
|
-
# @!macro [attach] atomic_boolean_method_true_question
|
62
|
-
#
|
63
|
-
# Is the current value `true`
|
64
|
-
#
|
65
|
-
# @return [Boolean] true if the current value is `true`, else false
|
66
|
-
def true?
|
67
|
-
synchronize { @value }
|
68
|
-
end
|
24
|
+
# @param [Boolean] value the new value to be set
|
25
|
+
#
|
26
|
+
# @return [Boolean] the current value
|
69
27
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
def false?
|
76
|
-
synchronize { !@value }
|
77
|
-
end
|
28
|
+
# @!macro [new] atomic_boolean_method_true_question
|
29
|
+
#
|
30
|
+
# Is the current value `true`
|
31
|
+
#
|
32
|
+
# @return [Boolean] true if the current value is `true`, else false
|
78
33
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
def make_true
|
85
|
-
synchronize { ns_make_value(true) }
|
86
|
-
end
|
34
|
+
# @!macro [new] atomic_boolean_method_false_question
|
35
|
+
#
|
36
|
+
# Is the current value `false`
|
37
|
+
#
|
38
|
+
# @return [Boolean] true if the current value is `false`, else false
|
87
39
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
def make_false
|
94
|
-
synchronize { ns_make_value(false) }
|
95
|
-
end
|
40
|
+
# @!macro [new] atomic_boolean_method_make_true
|
41
|
+
#
|
42
|
+
# Explicitly sets the value to true.
|
43
|
+
#
|
44
|
+
# @return [Boolean] true is value has changed, otherwise false
|
96
45
|
|
97
|
-
|
46
|
+
# @!macro [new] atomic_boolean_method_make_false
|
47
|
+
#
|
48
|
+
# Explicitly sets the value to false.
|
49
|
+
#
|
50
|
+
# @return [Boolean] true is value has changed, otherwise false
|
51
|
+
|
52
|
+
###################################################################
|
98
53
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
54
|
+
# @!macro [new] atomic_boolean_public_api
|
55
|
+
#
|
56
|
+
# @!method initialize(initial = false)
|
57
|
+
# @!macro atomic_boolean_method_initialize
|
58
|
+
#
|
59
|
+
# @!method value
|
60
|
+
# @!macro atomic_boolean_method_value_get
|
61
|
+
#
|
62
|
+
# @!method value=(value)
|
63
|
+
# @!macro atomic_boolean_method_value_set
|
64
|
+
#
|
65
|
+
# @!method true?
|
66
|
+
# @!macro atomic_boolean_method_true_question
|
67
|
+
#
|
68
|
+
# @!method false?
|
69
|
+
# @!macro atomic_boolean_method_false_question
|
70
|
+
#
|
71
|
+
# @!method make_true
|
72
|
+
# @!macro atomic_boolean_method_make_true
|
73
|
+
#
|
74
|
+
# @!method make_false
|
75
|
+
# @!macro atomic_boolean_method_make_false
|
103
76
|
|
104
|
-
|
105
|
-
def ns_make_value(value)
|
106
|
-
old = @value
|
107
|
-
@value = value
|
108
|
-
old != @value
|
109
|
-
end
|
110
|
-
end
|
77
|
+
###################################################################
|
111
78
|
|
112
79
|
# @!visibility private
|
113
80
|
# @!macro internal_implementation_note
|
@@ -121,31 +88,27 @@ module Concurrent
|
|
121
88
|
end
|
122
89
|
private_constant :AtomicBooleanImplementation
|
123
90
|
|
124
|
-
# @!macro atomic_boolean
|
91
|
+
# @!macro [attach] atomic_boolean
|
92
|
+
#
|
93
|
+
# A boolean value that can be updated atomically. Reads and writes to an atomic
|
94
|
+
# boolean and thread-safe and guaranteed to succeed. Reads and writes may block
|
95
|
+
# briefly but no explicit locking is required.
|
96
|
+
#
|
97
|
+
# Testing with ruby 2.1.2
|
98
|
+
# Testing with Concurrent::MutexAtomicBoolean...
|
99
|
+
# 2.790000 0.000000 2.790000 ( 2.791454)
|
100
|
+
# Testing with Concurrent::CAtomicBoolean...
|
101
|
+
# 0.740000 0.000000 0.740000 ( 0.740206)
|
102
|
+
#
|
103
|
+
# Testing with jruby 1.9.3
|
104
|
+
# Testing with Concurrent::MutexAtomicBoolean...
|
105
|
+
# 5.240000 2.520000 7.760000 ( 3.683000)
|
106
|
+
# Testing with Concurrent::JavaAtomicBoolean...
|
107
|
+
# 3.340000 0.010000 3.350000 ( 0.855000)
|
108
|
+
#
|
109
|
+
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean
|
125
110
|
#
|
126
|
-
#
|
111
|
+
# @!macro atomic_boolean_public_api
|
127
112
|
class AtomicBoolean < AtomicBooleanImplementation
|
128
|
-
|
129
|
-
# @!method initialize(initial = false)
|
130
|
-
# @!macro atomic_boolean_method_initialize
|
131
|
-
|
132
|
-
# @!method value
|
133
|
-
# @!macro atomic_boolean_method_value_get
|
134
|
-
|
135
|
-
# @!method value=(value)
|
136
|
-
# @!macro atomic_boolean_method_value_set
|
137
|
-
|
138
|
-
# @!method true?
|
139
|
-
# @!macro atomic_boolean_method_true_question
|
140
|
-
|
141
|
-
# @!method false?
|
142
|
-
# @!macro atomic_boolean_method_false_question
|
143
|
-
|
144
|
-
# @!method make_true
|
145
|
-
# @!macro atomic_boolean_method_make_true
|
146
|
-
|
147
|
-
# @!method make_false
|
148
|
-
# @!macro atomic_boolean_method_make_false
|
149
|
-
|
150
113
|
end
|
151
114
|
end
|