concurrent-ruby 0.9.2 → 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|